diff options
Diffstat (limited to 'src/nvim/quickfix.c')
-rw-r--r-- | src/nvim/quickfix.c | 83 |
1 files changed, 52 insertions, 31 deletions
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 4e20eb8925..651ebc9f93 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -13,7 +13,9 @@ #include "nvim/arglist.h" #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" +#include "nvim/autocmd_defs.h" #include "nvim/buffer.h" +#include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/cursor.h" #include "nvim/drawscreen.h" @@ -26,20 +28,24 @@ #include "nvim/ex_cmds_defs.h" #include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" +#include "nvim/ex_eval_defs.h" #include "nvim/ex_getln.h" #include "nvim/fileio.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" -#include "nvim/gettext.h" +#include "nvim/garray_defs.h" +#include "nvim/gettext_defs.h" #include "nvim/globals.h" #include "nvim/help.h" #include "nvim/highlight.h" +#include "nvim/highlight_defs.h" #include "nvim/highlight_group.h" #include "nvim/macros_defs.h" #include "nvim/mark.h" #include "nvim/mbyte.h" +#include "nvim/mbyte_defs.h" #include "nvim/memline.h" +#include "nvim/memline_defs.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/move.h" @@ -49,16 +55,20 @@ #include "nvim/option_vars.h" #include "nvim/optionstr.h" #include "nvim/os/fs.h" +#include "nvim/os/fs_defs.h" #include "nvim/os/input.h" #include "nvim/os/os.h" +#include "nvim/os/os_defs.h" #include "nvim/path.h" #include "nvim/pos_defs.h" #include "nvim/quickfix.h" #include "nvim/regexp.h" +#include "nvim/regexp_defs.h" #include "nvim/search.h" #include "nvim/strings.h" #include "nvim/types_defs.h" #include "nvim/ui.h" +#include "nvim/undo.h" #include "nvim/vim_defs.h" #include "nvim/window.h" @@ -107,7 +117,7 @@ typedef enum { /// Usually the list contains one or more entries. But an empty list can be /// created using setqflist()/setloclist() with a title and/or user context /// information and entries can be added later using setqflist()/setloclist(). -typedef struct qf_list_S { +typedef struct { unsigned qf_id; ///< Unique identifier for this list qfltype_T qfl_type; qfline_T *qf_start; ///< pointer to the first error @@ -232,7 +242,7 @@ typedef struct { } qffields_T; /// :vimgrep command arguments -typedef struct vgr_args_S { +typedef struct { int tomatch; ///< maximum number of matches to find char *spat; ///< search pattern int flags; ///< search modifier @@ -272,7 +282,7 @@ enum { QF_WINHEIGHT = 10, }; ///< default height for quickfix window // Macro to loop through all the items in a quickfix list // Quickfix item index starts from 1, so i below starts at 1 #define FOR_ALL_QFL_ITEMS(qfl, qfp, i) \ - for ((i) = 1, (qfp) = (qfl)->qf_start; /* NOLINT(readability/braces) */ \ + for ((i) = 1, (qfp) = (qfl)->qf_start; \ !got_int && (i) <= (qfl)->qf_count && (qfp) != NULL; \ (i)++, (qfp) = (qfp)->qf_next) @@ -1056,7 +1066,9 @@ static int qf_setup_state(qfstate_T *pstate, char *restrict enc, const char *res } if (efile != NULL - && (pstate->fd = os_fopen(efile, "r")) == NULL) { + && (pstate->fd = (strequal(efile, "-") + ? fdopen(os_open_stdin_fd(), "r") + : os_fopen(efile, "r"))) == NULL) { semsg(_(e_openerrf), efile); return FAIL; } @@ -1603,7 +1615,7 @@ static int qf_parse_get_fields(char *linebuf, size_t linelen, efm_T *fmt_ptr, qf // Always ignore case when looking for a matching error. regmatch.rm_ic = true; regmatch.regprog = fmt_ptr->prog; - int r = vim_regexec(®match, linebuf, 0); + bool r = vim_regexec(®match, linebuf, 0); fmt_ptr->prog = regmatch.regprog; int status = QF_FAIL; if (r) { @@ -1970,7 +1982,7 @@ static qf_info_T *ll_get_or_alloc_list(win_T *wp) /// For a location list command, returns the stack for the current window. If /// the location list is not found, then returns NULL and prints an error /// message if 'print_emsg' is true. -static qf_info_T *qf_cmd_get_stack(exarg_T *eap, int print_emsg) +static qf_info_T *qf_cmd_get_stack(exarg_T *eap, bool print_emsg) { qf_info_T *qi = &ql_info; @@ -2512,7 +2524,7 @@ static void win_set_loclist(win_T *wp, qf_info_T *qi) /// Find a help window or open one. If 'newwin' is true, then open a new help /// window. -static int jump_to_help_window(qf_info_T *qi, bool newwin, int *opened_window) +static int jump_to_help_window(qf_info_T *qi, bool newwin, bool *opened_window) { win_T *wp = NULL; @@ -2715,7 +2727,7 @@ static void qf_goto_win_with_qfl_file(int qf_fnum) // window, jump to it. Otherwise open a new window to display the file. If // 'newwin' is true, then always open a new window. This is called from either // a quickfix or a location list window. -static int qf_jump_to_usable_window(int qf_fnum, bool newwin, int *opened_window) +static int qf_jump_to_usable_window(int qf_fnum, bool newwin, bool *opened_window) { win_T *usable_wp = NULL; bool usable_win = false; @@ -2770,7 +2782,7 @@ static int qf_jump_to_usable_window(int qf_fnum, bool newwin, int *opened_window /// QF_ABORT if the quickfix/location list was freed by an autocmd /// when opening the buffer. static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit, int prev_winid, - int *opened_window) + bool *opened_window) { qf_list_T *qfl = qf_get_curlist(qi); int old_changetick = qfl->qf_changedtick; @@ -2905,7 +2917,7 @@ static void qf_jump_print_msg(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, buf /// FAIL if not able to jump/open a window. /// NOTDONE if a file is not associated with the entry. /// QF_ABORT if the quickfix/location list was modified by an autocmd. -static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, bool newwin, int *opened_window) +static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, bool newwin, bool *opened_window) { qf_list_T *qfl = qf_get_curlist(qi); int old_changetick = qfl->qf_changedtick; @@ -2964,7 +2976,7 @@ static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, bool newwin, int /// QF_ABORT if the quickfix/location list is freed by an autocmd when opening /// the file. static int qf_jump_to_buffer(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, int forceit, - int prev_winid, int *opened_window, int openfold, int print_message) + int prev_winid, bool *opened_window, int openfold, bool print_message) { // If there is a file name, read the wanted file if needed, and check // autowrite etc. @@ -3051,7 +3063,7 @@ static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit, boo int prev_winid = curwin->handle; - int opened_window = false; + bool opened_window = false; int retval = qf_jump_open_window(qi, qf_ptr, newwin, &opened_window); if (retval == FAIL) { goto failed; @@ -3646,12 +3658,12 @@ static int qf_goto_cwindow(const qf_info_T *qi, bool resize, int sz, bool vertsp static void qf_set_cwindow_options(void) { // switch off 'swapfile' - set_option_value_give_err("swf", BOOLEAN_OPTVAL(false), OPT_LOCAL); - set_option_value_give_err("bt", STATIC_CSTR_AS_OPTVAL("quickfix"), OPT_LOCAL); - set_option_value_give_err("bh", STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL); + set_option_value_give_err(kOptSwapfile, BOOLEAN_OPTVAL(false), OPT_LOCAL); + set_option_value_give_err(kOptBuftype, STATIC_CSTR_AS_OPTVAL("quickfix"), OPT_LOCAL); + set_option_value_give_err(kOptBufhidden, STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL); RESET_BINDING(curwin); curwin->w_p_diff = false; - set_option_value_give_err("fdm", STATIC_CSTR_AS_OPTVAL("manual"), OPT_LOCAL); + set_option_value_give_err(kOptFoldmethod, STATIC_CSTR_AS_OPTVAL("manual"), OPT_LOCAL); } // Open a new quickfix or location list window, load the quickfix buffer and @@ -3988,7 +4000,7 @@ static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last) buf_inc_changedtick(buf); if (old_last == NULL) { - (void)qf_win_pos_update(qi, 0); + qf_win_pos_update(qi, 0); // restore curwin/curbuf and a few other things aucmd_restbuf(&aco); @@ -4131,6 +4143,12 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int q } // delete all existing lines + // + // Note: we cannot store undo information, because + // qf buffer is usually not allowed to be modified. + // + // So we need to clean up undo information + // otherwise autocommands may invalidate the undo stack while ((curbuf->b_ml.ml_flags & ML_EMPTY) == 0) { // If deletion fails, this loop may run forever, so // signal error and return. @@ -4139,6 +4157,9 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int q return; } } + + // Remove all undo information + u_clearallandblockfree(curbuf); } // Check if there is anything to display @@ -4199,7 +4220,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int q } if (old_last == NULL) { // Delete the empty line which is now at the end - (void)ml_delete(lnum + 1, false); + ml_delete(lnum + 1, false); } qfga_clear(); @@ -4213,7 +4234,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int q // resembles reading a file into a buffer, it's more logical when using // autocommands. curbuf->b_ro_locked++; - set_option_value_give_err("ft", STATIC_CSTR_AS_OPTVAL("qf"), OPT_LOCAL); + set_option_value_give_err(kOptFiletype, STATIC_CSTR_AS_OPTVAL("qf"), OPT_LOCAL); curbuf->b_p_ma = false; keep_filetype = true; // don't detect 'filetype' @@ -4583,7 +4604,7 @@ int qf_get_cur_valid_idx(exarg_T *eap) /// Used by :cdo, :ldo, :cfdo and :lfdo commands. /// For :cdo and :ldo, returns the 'n'th valid error entry. /// For :cfdo and :lfdo, returns the 'n'th valid file entry. -static size_t qf_get_nth_valid_entry(qf_list_T *qfl, size_t n, int fdo) +static size_t qf_get_nth_valid_entry(qf_list_T *qfl, size_t n, bool fdo) FUNC_ATTR_NONNULL_ALL { // Check if the list has valid errors. @@ -5091,7 +5112,7 @@ void ex_cfile(exarg_T *eap) } } if (*eap->arg != NUL) { - set_string_option_direct("ef", -1, eap->arg, OPT_FREE, 0); + set_string_option_direct(kOptErrorfile, eap->arg, 0, 0); } char *enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc; @@ -5690,7 +5711,7 @@ static buf_T *load_dummy_buffer(char *fname, char *dirname_start, char *resultin return NULL; } - int failed = true; + bool failed = true; bufref_T newbufref; set_bufref(&newbufref, newbuf); @@ -5706,7 +5727,7 @@ static buf_T *load_dummy_buffer(char *fname, char *dirname_start, char *resultin aucmd_prepbuf(&aco, newbuf); // Need to set the filename for autocommands. - (void)setfname(curbuf, fname, NULL, false); + setfname(curbuf, fname, NULL, false); // Create swap file now to avoid the ATTENTION message. check_need_swap(true); @@ -5958,7 +5979,7 @@ static int qf_get_list_from_lines(dict_T *what, dictitem_T *di, dict_T *retdict) if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, errorformat, true, 0, 0, NULL, NULL) > 0) { - (void)get_errorlist(qi, NULL, 0, 0, l); + get_errorlist(qi, NULL, 0, 0, l); qf_free(&qi->qf_lists[0]); } xfree(qi); @@ -6907,7 +6928,7 @@ static int cbuffer_process_args(exarg_T *eap, buf_T **bufp, linenr_T *line1, lin } if (buf->b_ml.ml_mfp == NULL) { - emsg(_("E681: Buffer is not loaded")); + emsg(_(e_buffer_is_not_loaded)); return FAIL; } @@ -7221,7 +7242,7 @@ void ex_helpgrep(exarg_T *eap) bool updated = false; // Make 'cpoptions' empty, the 'l' flag should not be used here. char *const save_cpo = p_cpo; - const bool save_cpo_allocated = is_option_allocated("cpo"); + const bool save_cpo_allocated = (get_option(kOptCpoptions)->flags & P_ALLOCED); p_cpo = empty_string_option; bool new_qi = false; @@ -7259,7 +7280,7 @@ void ex_helpgrep(exarg_T *eap) // Darn, some plugin changed the value. If it's still empty it was // changed and restored, need to restore in the complicated way. if (*p_cpo == NUL) { - set_option_value_give_err("cpo", CSTR_AS_OPTVAL(save_cpo), 0); + set_option_value_give_err(kOptCpoptions, CSTR_AS_OPTVAL(save_cpo), 0); } if (save_cpo_allocated) { free_string_option(save_cpo); @@ -7319,12 +7340,12 @@ void free_quickfix(void) } #endif -static void get_qf_loc_list(int is_qf, win_T *wp, typval_T *what_arg, typval_T *rettv) +static void get_qf_loc_list(bool is_qf, win_T *wp, typval_T *what_arg, typval_T *rettv) { if (what_arg->v_type == VAR_UNKNOWN) { tv_list_alloc_ret(rettv, kListLenMayKnow); if (is_qf || wp != NULL) { - (void)get_errorlist(NULL, wp, -1, 0, rettv->vval.v_list); + get_errorlist(NULL, wp, -1, 0, rettv->vval.v_list); } } else { tv_dict_alloc_ret(rettv); |