aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/quickfix.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/quickfix.c')
-rw-r--r--src/nvim/quickfix.c83
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(&regmatch, linebuf, 0);
+ bool r = vim_regexec(&regmatch, 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);