aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/quickfix.c
diff options
context:
space:
mode:
authorJosh Rahm <rahm@google.com>2022-07-18 19:37:18 +0000
committerJosh Rahm <rahm@google.com>2022-07-18 19:37:18 +0000
commit308e1940dcd64aa6c344c403d4f9e0dda58d9c5c (patch)
tree35fe43e01755e0f312650667004487a44d6b7941 /src/nvim/quickfix.c
parent96a00c7c588b2f38a2424aeeb4ea3581d370bf2d (diff)
parente8c94697bcbe23a5c7b07c292b90a6b70aadfa87 (diff)
downloadrneovim-308e1940dcd64aa6c344c403d4f9e0dda58d9c5c.tar.gz
rneovim-308e1940dcd64aa6c344c403d4f9e0dda58d9c5c.tar.bz2
rneovim-308e1940dcd64aa6c344c403d4f9e0dda58d9c5c.zip
Merge remote-tracking branch 'upstream/master' into rahm
Diffstat (limited to 'src/nvim/quickfix.c')
-rw-r--r--src/nvim/quickfix.c1424
1 files changed, 777 insertions, 647 deletions
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 0196e05455..2138437b29 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -22,6 +22,7 @@
#include "nvim/ex_getln.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
+#include "nvim/highlight_group.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
@@ -39,15 +40,13 @@
#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/strings.h"
-#include "nvim/syntax.h"
#include "nvim/ui.h"
#include "nvim/vim.h"
#include "nvim/window.h"
-
struct dir_stack_T {
struct dir_stack_T *next;
- char_u *dirname;
+ char *dirname;
};
// For each error the next struct is allocated and linked in a list.
@@ -62,23 +61,23 @@ struct qfline_S {
int qf_col; ///< column where the error occurred
int qf_end_col; ///< column when the error has range or zero
int qf_nr; ///< error number
- char_u *qf_module; ///< module name for this error
- char_u *qf_pattern; ///< search pattern for the error
- char_u *qf_text; ///< description of the error
- char_u qf_viscol; ///< set to TRUE if qf_col and qf_end_col is
+ char *qf_module; ///< module name for this error
+ char *qf_pattern; ///< search pattern for the error
+ char *qf_text; ///< description of the error
+ char qf_viscol; ///< set to TRUE if qf_col and qf_end_col is
// screen column
- char_u qf_cleared; ///< set to TRUE if line has been deleted
- char_u qf_type; ///< type of the error (mostly 'E'); 1 for :helpgrep
- char_u qf_valid; ///< valid error message detected
+ char qf_cleared; ///< set to TRUE if line has been deleted
+ char qf_type; ///< type of the error (mostly 'E'); 1 for :helpgrep
+ char qf_valid; ///< valid error message detected
};
// There is a stack of error lists.
#define LISTCOUNT 10
#define INVALID_QFIDX (-1)
+#define INVALID_QFBUFNR (0)
/// Quickfix list type.
-typedef enum
-{
+typedef enum {
QFLT_QUICKFIX, ///< Quickfix list - global list
QFLT_LOCATION, ///< Location list - per window list
QFLT_INTERNAL, ///< Internal - Temporary list used by
@@ -99,15 +98,15 @@ typedef struct qf_list_S {
int qf_count; ///< number of errors (0 means empty list)
int qf_index; ///< current index in the error list
int qf_nonevalid; ///< TRUE if not a single valid entry found
- char_u *qf_title; ///< title derived from the command that created
- ///< the error list or set by setqflist
+ char *qf_title; ///< title derived from the command that created
+ ///< the error list or set by setqflist
typval_T *qf_ctx; ///< context set by setqflist/setloclist
- Callback qftf_cb; ///< 'quickfixtextfunc' callback function
+ Callback qf_qftf_cb; ///< 'quickfixtextfunc' callback function
struct dir_stack_T *qf_dir_stack;
- char_u *qf_directory;
+ char *qf_directory;
struct dir_stack_T *qf_file_stack;
- char_u *qf_currfile;
+ char *qf_currfile;
bool qf_multiline;
bool qf_multiignore;
bool qf_multiscan;
@@ -126,36 +125,37 @@ struct qf_info_S {
int qf_curlist; // current error list
qf_list_T qf_lists[LISTCOUNT];
qfltype_T qfl_type; // type of list
+ int qf_bufnr; // quickfix window buffer number
};
static qf_info_T ql_info; // global quickfix list
static unsigned last_qf_id = 0; // Last Used quickfix list id
-#define FMT_PATTERNS 11 // maximum number of % recognized
+#define FMT_PATTERNS 13 // maximum number of % recognized
// Structure used to hold the info of one part of 'errorformat'
typedef struct efm_S efm_T;
struct efm_S {
regprog_T *prog; // pre-formatted part of 'errorformat'
efm_T *next; // pointer to next (NULL if last)
- char_u addr[FMT_PATTERNS]; // indices of used % patterns
- char_u prefix; // prefix of this format line:
- // 'D' enter directory
- // 'X' leave directory
- // 'A' start of multi-line message
- // 'E' error message
- // 'W' warning message
- // 'I' informational message
- // 'N' note message
- // 'C' continuation line
- // 'Z' end of multi-line message
- // 'G' general, unspecific message
- // 'P' push file (partial) message
- // 'Q' pop/quit file (partial) message
- // 'O' overread (partial) message
- char_u flags; // additional flags given in prefix
- // '-' do not include this line
- // '+' include whole line in message
+ char addr[FMT_PATTERNS]; // indices of used % patterns
+ char prefix; // prefix of this format line:
+ // 'D' enter directory
+ // 'X' leave directory
+ // 'A' start of multi-line message
+ // 'E' error message
+ // 'W' warning message
+ // 'I' informational message
+ // 'N' note message
+ // 'C' continuation line
+ // 'Z' end of multi-line message
+ // 'G' general, unspecific message
+ // 'P' push file (partial) message
+ // 'Q' pop/quit file (partial) message
+ // 'O' overread (partial) message
+ char flags; // additional flags given in prefix
+ // '-' do not include this line
+ // '+' include whole line in message
int conthere; // %> used
};
@@ -178,13 +178,13 @@ enum {
/// State information used to parse lines and add entries to a quickfix/location
/// list.
typedef struct {
- char_u *linebuf;
+ char *linebuf;
size_t linelen;
- char_u *growbuf;
+ char *growbuf;
size_t growbufsiz;
FILE *fd;
typval_T *tv;
- char_u *p_str;
+ char *p_str;
list_T *p_list;
listitem_T *p_li;
buf_T *buf;
@@ -194,55 +194,65 @@ typedef struct {
} qfstate_T;
typedef struct {
- char_u *namebuf;
- char_u *module;
- char_u *errmsg;
+ char *namebuf;
+ char *module;
+ char *errmsg;
size_t errmsglen;
- long lnum;
- long end_lnum;
+ linenr_T lnum;
+ linenr_T end_lnum;
int col;
int end_col;
bool use_viscol;
- char_u *pattern;
+ char *pattern;
int enr;
- char_u type;
+ char type;
bool valid;
} qffields_T;
+/// :vimgrep command arguments
+typedef struct vgr_args_S {
+ long tomatch; ///< maximum number of matches to find
+ char *spat; ///< search pattern
+ int flags; ///< search modifier
+ char **fnames; ///< list of files to search
+ int fcount; ///< number of files
+ regmmatch_T regmatch; ///< compiled search pattern
+ char *qf_title; ///< quickfix list title
+} vgr_args_T;
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "quickfix.c.generated.h"
#endif
-static char_u *e_no_more_items = (char_u *)N_("E553: No more items");
+static char *e_no_more_items = N_("E553: No more items");
// Quickfix window check helper macro
-#define IS_QF_WINDOW(wp) (bt_quickfix(wp->w_buffer) && wp->w_llist_ref == NULL)
+#define IS_QF_WINDOW(wp) (bt_quickfix((wp)->w_buffer) && (wp)->w_llist_ref == NULL)
// Location list window check helper macro
-#define IS_LL_WINDOW(wp) (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL)
+#define IS_LL_WINDOW(wp) (bt_quickfix((wp)->w_buffer) && (wp)->w_llist_ref != NULL)
// Quickfix and location list stack check helper macros
-#define IS_QF_STACK(qi) (qi->qfl_type == QFLT_QUICKFIX)
-#define IS_LL_STACK(qi) (qi->qfl_type == QFLT_LOCATION)
-#define IS_QF_LIST(qfl) (qfl->qfl_type == QFLT_QUICKFIX)
-#define IS_LL_LIST(qfl) (qfl->qfl_type == QFLT_LOCATION)
+#define IS_QF_STACK(qi) ((qi)->qfl_type == QFLT_QUICKFIX)
+#define IS_LL_STACK(qi) ((qi)->qfl_type == QFLT_LOCATION)
+#define IS_QF_LIST(qfl) ((qfl)->qfl_type == QFLT_QUICKFIX)
+#define IS_LL_LIST(qfl) ((qfl)->qfl_type == QFLT_LOCATION)
//
// Return location list for window 'wp'
// For location list window, return the referenced location list
//
-#define GET_LOC_LIST(wp) (IS_LL_WINDOW(wp) ? wp->w_llist_ref : wp->w_llist)
+#define GET_LOC_LIST(wp) (IS_LL_WINDOW(wp) ? (wp)->w_llist_ref : (wp)->w_llist)
// 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) */ \
- !got_int && i <= qfl->qf_count && qfp != NULL; \
- i++, qfp = qfp->qf_next)
-
+ for ((i) = 1, (qfp) = (qfl)->qf_start; /* NOLINT(readability/braces) */ \
+ !got_int && (i) <= (qfl)->qf_count && (qfp) != NULL; \
+ (i)++, (qfp) = (qfp)->qf_next)
// Looking up a buffer can be slow if there are many. Remember the last one
// to make this a lot faster if there are multiple matches in the same file.
-static char_u *qf_last_bufname = NULL;
+static char *qf_last_bufname = NULL;
static bufref_T qf_last_bufref = { NULL, 0, 0 };
static char *e_current_quickfix_list_was_changed =
@@ -279,7 +289,7 @@ static int qf_init_process_nextline(qf_list_T *qfl, efm_T *fmt_first, qfstate_T
(*fields->namebuf || qfl->qf_directory != NULL)
? fields->namebuf
: ((qfl->qf_currfile != NULL && fields->valid)
- ? qfl->qf_currfile : (char_u *)NULL),
+ ? qfl->qf_currfile : NULL),
fields->module,
0,
fields->errmsg,
@@ -305,8 +315,8 @@ static int qf_init_process_nextline(qf_list_T *qfl, efm_T *fmt_first, qfstate_T
/// @params enc If non-NULL, encoding used to parse errors
///
/// @returns -1 for error, number of errors for success.
-int qf_init(win_T *wp, const char_u *restrict efile, char_u *restrict errorformat, int newlist,
- const char_u *restrict qf_title, char_u *restrict enc)
+int qf_init(win_T *wp, const char *restrict efile, char *restrict errorformat, int newlist,
+ const char *restrict qf_title, char *restrict enc)
{
qf_info_T *qi = &ql_info;
@@ -314,37 +324,41 @@ int qf_init(win_T *wp, const char_u *restrict efile, char_u *restrict errorforma
qi = ll_get_or_alloc_list(wp);
}
- return qf_init_ext(qi, qi->qf_curlist, efile, curbuf, NULL, errorformat,
- newlist, (linenr_T)0, (linenr_T)0, qf_title, enc);
+ return qf_init_ext(qi, qi->qf_curlist, (char *)efile, curbuf, NULL, errorformat,
+ newlist, (linenr_T)0, (linenr_T)0, (char *)qf_title, enc);
}
// Maximum number of bytes allowed per line while reading an errorfile.
static const size_t LINE_MAXLEN = 4096;
+/// Patterns used. Keep in sync with qf_parse_fmt[].
static struct fmtpattern {
- char_u convchar;
+ char convchar;
char *pattern;
} fmt_pat[FMT_PATTERNS] =
{
- { 'f', ".\\+" }, // only used when at end
- { 'n', "\\d\\+" },
- { 'l', "\\d\\+" },
- { 'c', "\\d\\+" },
- { 't', "." },
- { 'm', ".\\+" },
- { 'r', ".*" },
- { 'p', "[- .]*"}, // NOLINT(whitespace/tab)
- { 'v', "\\d\\+" },
- { 's', ".\\+" },
- { 'o', ".\\+" }
+ { 'f', ".\\+" }, // only used when at end
+ { 'n', "\\d\\+" }, // 1
+ { 'l', "\\d\\+" }, // 2
+ { 'e', "\\d\\+" }, // 3
+ { 'c', "\\d\\+" }, // 4
+ { 'k', "\\d\\+" }, // 5
+ { 't', "." }, // 6
+#define FMT_PATTERN_M 7
+ { 'm', ".\\+" }, // 7
+#define FMT_PATTERN_R 8
+ { 'r', ".*" }, // 8
+ { 'p', "[- \t.]*" }, // 9
+ { 'v', "\\d\\+" }, // 10
+ { 's', ".\\+" }, // 11
+ { 'o', ".\\+" } // 12
};
/// Convert an errorformat pattern to a regular expression pattern.
/// See fmt_pat definition above for the list of supported patterns. The
/// pattern specifier is supplied in "efmpat". The converted pattern is stored
/// in "regpat". Returns a pointer to the location after the pattern.
-static char_u *efmpat_to_regpat(const char_u *efmpat, char_u *regpat, efm_T *efminfo, int idx,
- int round)
+static char *efmpat_to_regpat(const char *efmpat, char *regpat, efm_T *efminfo, int idx, int round)
FUNC_ATTR_NONNULL_ALL
{
if (efminfo->addr[idx]) {
@@ -352,14 +366,14 @@ static char_u *efmpat_to_regpat(const char_u *efmpat, char_u *regpat, efm_T *efm
semsg(_("E372: Too many %%%c in format string"), *efmpat);
return NULL;
}
- if ((idx && idx < 6
- && vim_strchr((char_u *)"DXOPQ", efminfo->prefix) != NULL)
- || (idx == 6
- && vim_strchr((char_u *)"OPQ", efminfo->prefix) == NULL)) {
+ if ((idx && idx < FMT_PATTERN_R
+ && vim_strchr("DXOPQ", efminfo->prefix) != NULL)
+ || (idx == FMT_PATTERN_R
+ && vim_strchr("OPQ", efminfo->prefix) == NULL)) {
semsg(_("E373: Unexpected %%%c in format string"), *efmpat);
return NULL;
}
- efminfo->addr[idx] = (char_u)++ round;
+ efminfo->addr[idx] = (char)++round;
*regpat++ = '\\';
*regpat++ = '(';
#ifdef BACKSLASH_IN_FILENAME
@@ -387,7 +401,7 @@ static char_u *efmpat_to_regpat(const char_u *efmpat, char_u *regpat, efm_T *efm
regpat += 4;
}
} else {
- char_u *srcptr = (char_u *)fmt_pat[idx].pattern;
+ char *srcptr = fmt_pat[idx].pattern;
while ((*regpat = *srcptr++) != NUL) {
regpat++;
}
@@ -400,10 +414,10 @@ static char_u *efmpat_to_regpat(const char_u *efmpat, char_u *regpat, efm_T *efm
/// Convert a scanf like format in 'errorformat' to a regular expression.
/// Returns a pointer to the location after the pattern.
-static char_u *scanf_fmt_to_regpat(const char_u **pefmp, const char_u *efm, int len, char_u *regpat)
+static char *scanf_fmt_to_regpat(const char **pefmp, const char *efm, int len, char *regpat)
FUNC_ATTR_NONNULL_ALL
{
- const char_u *efmp = *pefmp;
+ const char *efmp = *pefmp;
if (*efmp == '[' || *efmp == '\\') {
if ((*regpat++ = *efmp) == '[') { // %*[^a-z0-9] etc.
@@ -412,8 +426,7 @@ static char_u *scanf_fmt_to_regpat(const char_u **pefmp, const char_u *efm, int
}
if (efmp < efm + len) {
*regpat++ = *++efmp; // could be ']'
- while (efmp < efm + len && (*regpat++ = *++efmp) != ']') {
- }
+ while (efmp < efm + len && (*regpat++ = *++efmp) != ']') {}
if (efmp == efm + len) {
emsg(_("E374: Missing ] in format string"));
return NULL;
@@ -435,13 +448,13 @@ static char_u *scanf_fmt_to_regpat(const char_u **pefmp, const char_u *efm, int
}
/// Analyze/parse an errorformat prefix.
-static const char_u *efm_analyze_prefix(const char_u *efmp, efm_T *efminfo)
+static const char *efm_analyze_prefix(const char *efmp, efm_T *efminfo)
FUNC_ATTR_NONNULL_ALL
{
- if (vim_strchr((char_u *)"+-", *efmp) != NULL) {
+ if (vim_strchr("+-", *efmp) != NULL) {
efminfo->flags = *efmp++;
}
- if (vim_strchr((char_u *)"DXAEWINCZGOPQ", *efmp) != NULL) {
+ if (vim_strchr("DXAEWINCZGOPQ", *efmp) != NULL) {
efminfo->prefix = *efmp;
} else {
semsg(_("E376: Invalid %%%c in format string prefix"), *efmp);
@@ -451,16 +464,15 @@ static const char_u *efm_analyze_prefix(const char_u *efmp, efm_T *efminfo)
return efmp;
}
-
// Converts a 'errorformat' string to regular expression pattern
-static int efm_to_regpat(const char_u *efm, int len, efm_T *fmt_ptr, char_u *regpat)
+static int efm_to_regpat(const char *efm, int len, efm_T *fmt_ptr, char *regpat)
FUNC_ATTR_NONNULL_ALL
{
// Build regexp pattern from current 'errorformat' option
- char_u *ptr = regpat;
+ char *ptr = regpat;
*ptr++ = '^';
int round = 0;
- for (const char_u *efmp = efm; efmp < efm + len; efmp++) {
+ for (const char *efmp = efm; efmp < efm + len; efmp++) {
if (*efmp == '%') {
efmp++;
int idx;
@@ -470,7 +482,7 @@ static int efm_to_regpat(const char_u *efm, int len, efm_T *fmt_ptr, char_u *reg
}
}
if (idx < FMT_PATTERNS) {
- ptr = efmpat_to_regpat(efmp, ptr, fmt_ptr, idx, round);
+ ptr = efmpat_to_regpat((char *)efmp, ptr, fmt_ptr, idx, round);
if (ptr == NULL) {
return FAIL;
}
@@ -481,7 +493,7 @@ static int efm_to_regpat(const char_u *efm, int len, efm_T *fmt_ptr, char_u *reg
if (ptr == NULL) {
return FAIL;
}
- } else if (vim_strchr((char_u *)"%\\.^$~[", *efmp) != NULL) {
+ } else if (vim_strchr("%\\.^$~[", *efmp) != NULL) {
*ptr++ = *efmp; // regexp magic characters
} else if (*efmp == '#') {
*ptr++ = '*';
@@ -501,7 +513,7 @@ static int efm_to_regpat(const char_u *efm, int len, efm_T *fmt_ptr, char_u *reg
} else { // copy normal character
if (*efmp == '\\' && efmp + 1 < efm + len) {
efmp++;
- } else if (vim_strchr((char_u *)".*^$~[", *efmp) != NULL) {
+ } else if (vim_strchr(".*^$~[", *efmp) != NULL) {
*ptr++ = '\\'; // escape regexp atoms
}
if (*efmp) {
@@ -533,7 +545,7 @@ static void free_efm_list(efm_T **efm_first)
/// Compute the size of the buffer used to convert a 'errorformat' pattern into
/// a regular expression pattern.
-static size_t efm_regpat_bufsz(char_u *efm)
+static size_t efm_regpat_bufsz(char *efm)
{
size_t sz;
@@ -551,7 +563,7 @@ static size_t efm_regpat_bufsz(char_u *efm)
}
/// Return the length of a 'errorformat' option part (separated by ",").
-static int efm_option_part_len(char_u *efm)
+static int efm_option_part_len(char *efm)
{
int len;
@@ -567,7 +579,7 @@ static int efm_option_part_len(char_u *efm)
/// Parse the 'errorformat' option. Multiple parts in the 'errorformat' option
/// are parsed and converted to regular expressions. Returns information about
/// the parsed 'errorformat' option.
-static efm_T *parse_efm_option(char_u *efm)
+static efm_T *parse_efm_option(char *efm)
{
efm_T *fmt_ptr = NULL;
efm_T *fmt_first = NULL;
@@ -576,7 +588,7 @@ static efm_T *parse_efm_option(char_u *efm)
// Get some space to modify the format string into.
size_t sz = efm_regpat_bufsz(efm);
- char_u *fmtstr = xmalloc(sz);
+ char *fmtstr = xmalloc(sz);
while (efm[0] != NUL) {
// Allocate a new eformat structure and put it at the end of the list
@@ -598,7 +610,7 @@ static efm_T *parse_efm_option(char_u *efm)
goto parse_efm_error;
}
// Advance to next part
- efm = skip_to_option_part(efm + len); // skip comma and spaces
+ efm = (char *)skip_to_option_part((char_u *)efm + len); // skip comma and spaces
}
if (fmt_first == NULL) { // nothing found
@@ -617,7 +629,7 @@ parse_efm_end:
}
/// Allocate more memory for the line buffer used for parsing lines.
-static char_u *qf_grow_linebuf(qfstate_T *state, size_t newsz)
+static char *qf_grow_linebuf(qfstate_T *state, size_t newsz)
{
// If the line exceeds LINE_MAXLEN exclude the last
// byte since it's not a NL character.
@@ -636,8 +648,8 @@ static char_u *qf_grow_linebuf(qfstate_T *state, size_t newsz)
static int qf_get_next_str_line(qfstate_T *state)
{
// Get the next line from the supplied string
- char_u *p_str = state->p_str;
- char_u *p;
+ char *p_str = state->p_str;
+ char *p;
size_t len;
if (*p_str == NUL) { // Reached the end of the string
@@ -654,7 +666,7 @@ static int qf_get_next_str_line(qfstate_T *state)
if (len > IOSIZE - 2) {
state->linebuf = qf_grow_linebuf(state, len);
} else {
- state->linebuf = IObuff;
+ state->linebuf = (char *)IObuff;
state->linelen = len;
}
memcpy(state->linebuf, p_str, state->linelen);
@@ -690,7 +702,7 @@ static int qf_get_next_list_line(qfstate_T *state)
if (len > IOSIZE - 2) {
state->linebuf = qf_grow_linebuf(state, len);
} else {
- state->linebuf = IObuff;
+ state->linebuf = (char *)IObuff;
state->linelen = len;
}
@@ -704,21 +716,21 @@ static int qf_get_next_list_line(qfstate_T *state)
/// Get the next string from state->buf.
static int qf_get_next_buf_line(qfstate_T *state)
{
- char_u *p_buf = NULL;
+ char *p_buf = NULL;
size_t len;
// Get the next line from the supplied buffer
if (state->buflnum > state->lnumlast) {
return QF_END_OF_INPUT;
}
- p_buf = ml_get_buf(state->buf, state->buflnum, false);
+ p_buf = (char *)ml_get_buf(state->buf, state->buflnum, false);
state->buflnum += 1;
len = STRLEN(p_buf);
if (len > IOSIZE - 2) {
state->linebuf = qf_grow_linebuf(state, len);
} else {
- state->linebuf = IObuff;
+ state->linebuf = (char *)IObuff;
state->linelen = len;
}
STRLCPY(state->linebuf, p_buf, state->linelen + 1);
@@ -757,7 +769,7 @@ retry:
for (;;) {
errno = 0;
- if (fgets((char *)state->growbuf + growbuflen,
+ if (fgets(state->growbuf + growbuflen,
(int)(state->growbufsiz - growbuflen), state->fd) == NULL) {
if (errno == EINTR) {
continue;
@@ -797,19 +809,20 @@ retry:
state->linebuf = state->growbuf;
state->linelen = growbuflen;
} else {
- state->linebuf = IObuff;
+ state->linebuf = (char *)IObuff;
}
// Convert a line if it contains a non-ASCII character
- if (state->vc.vc_type != CONV_NONE && has_non_ascii(state->linebuf)) {
- char_u *line = string_convert(&state->vc, state->linebuf, &state->linelen);
+ if (state->vc.vc_type != CONV_NONE && has_non_ascii((char_u *)state->linebuf)) {
+ char *line = (char *)string_convert(&state->vc, (char_u *)state->linebuf, &state->linelen);
if (line != NULL) {
if (state->linelen < IOSIZE) {
STRLCPY(state->linebuf, line, state->linelen + 1);
xfree(line);
} else {
xfree(state->growbuf);
- state->linebuf = state->growbuf = line;
+ state->linebuf = line;
+ state->growbuf = line;
state->growbufsiz = state->linelen < LINE_MAXLEN
? state->linelen : LINE_MAXLEN;
}
@@ -854,7 +867,7 @@ static int qf_get_nextline(qfstate_T *state)
#endif
}
- remove_bom(state->linebuf);
+ remove_bom((char_u *)state->linebuf);
return QF_OK;
}
@@ -889,12 +902,12 @@ static qf_list_T *qf_get_list(qf_info_T *qi, int idx)
/// Parse a line and get the quickfix fields.
/// Return the QF_ status.
-static int qf_parse_line(qf_list_T *qfl, char_u *linebuf, size_t linelen, efm_T *fmt_first,
+static int qf_parse_line(qf_list_T *qfl, char *linebuf, size_t linelen, efm_T *fmt_first,
qffields_T *fields)
{
efm_T *fmt_ptr;
int idx = 0;
- char_u *tail = NULL;
+ char *tail = NULL;
int status;
restofline:
@@ -911,7 +924,7 @@ restofline:
// match or no match.
fields->valid = true;
for (; fmt_ptr != NULL; fmt_ptr = fmt_ptr->next) {
- idx = fmt_ptr->prefix;
+ idx = (char_u)fmt_ptr->prefix;
status = qf_parse_get_fields(linebuf, linelen, fmt_ptr, fields,
qfl->qf_multiline, qfl->qf_multiscan,
&tail);
@@ -945,16 +958,16 @@ restofline:
fmt_start = fmt_ptr;
}
- if (vim_strchr((char_u *)"AEWIN", idx) != NULL) {
+ if (vim_strchr("AEWIN", idx) != NULL) {
qfl->qf_multiline = true; // start of a multi-line message
qfl->qf_multiignore = false; // reset continuation
- } else if (vim_strchr((char_u *)"CZ", idx) != NULL) {
+ } else if (vim_strchr("CZ", idx) != NULL) {
// continuation of multi-line msg
status = qf_parse_multiline_pfx(idx, qfl, fields);
if (status != QF_OK) {
return status;
}
- } else if (vim_strchr((char_u *)"OPQ", idx) != NULL) {
+ } else if (vim_strchr("OPQ", idx) != NULL) {
// global file names
status = qf_parse_file_pfx(idx, fields, qfl, tail);
if (status == QF_MULTISCAN) {
@@ -996,17 +1009,17 @@ static void qf_free_fields(qffields_T *pfields)
// Setup the state information used for parsing lines and populating a
// quickfix list.
-static int qf_setup_state(qfstate_T *pstate, char_u *restrict enc, const char_u *restrict efile,
+static int qf_setup_state(qfstate_T *pstate, char *restrict enc, const char *restrict efile,
typval_T *tv, buf_T *buf, linenr_T lnumfirst, linenr_T lnumlast)
FUNC_ATTR_NONNULL_ARG(1)
{
pstate->vc.vc_type = CONV_NONE;
if (enc != NULL && *enc != NUL) {
- convert_setup(&pstate->vc, enc, p_enc);
+ convert_setup(&pstate->vc, (char_u *)enc, p_enc);
}
if (efile != NULL
- && (pstate->fd = os_fopen((const char *)efile, "r")) == NULL) {
+ && (pstate->fd = os_fopen(efile, "r")) == NULL) {
semsg(_(e_openerrf), efile);
return FAIL;
}
@@ -1053,9 +1066,9 @@ static void qf_cleanup_state(qfstate_T *pstate)
/// @param lnumlast last line number to use
///
/// @return -1 for error, number of errors for success.
-static int qf_init_ext(qf_info_T *qi, int qf_idx, const char_u *restrict efile, buf_T *buf,
- typval_T *tv, char_u *restrict errorformat, bool newlist, linenr_T lnumfirst,
- linenr_T lnumlast, const char_u *restrict qf_title, char_u *restrict enc)
+static int qf_init_ext(qf_info_T *qi, int qf_idx, const char *restrict efile, buf_T *buf,
+ typval_T *tv, char *restrict errorformat, bool newlist, linenr_T lnumfirst,
+ linenr_T lnumlast, const char *restrict qf_title, char *restrict enc)
FUNC_ATTR_NONNULL_ARG(1)
{
qf_list_T *qfl;
@@ -1064,8 +1077,8 @@ static int qf_init_ext(qf_info_T *qi, int qf_idx, const char_u *restrict efile,
qfline_T *old_last = NULL;
bool adding = false;
static efm_T *fmt_first = NULL;
- char_u *efm;
- static char_u *last_efm = NULL;
+ char *efm;
+ static char *last_efm = NULL;
int retval = -1; // default: return error flag
int status;
@@ -1073,8 +1086,7 @@ static int qf_init_ext(qf_info_T *qi, int qf_idx, const char_u *restrict efile,
XFREE_CLEAR(qf_last_bufname);
qf_alloc_fields(&fields);
- if (qf_setup_state(&state, enc, efile, tv, buf,
- lnumfirst, lnumlast) == FAIL) {
+ if (qf_setup_state(&state, enc, efile, tv, buf, lnumfirst, lnumlast) == FAIL) {
goto qf_init_end;
}
@@ -1092,10 +1104,9 @@ static int qf_init_ext(qf_info_T *qi, int qf_idx, const char_u *restrict efile,
}
}
-
// Use the local value of 'errorformat' if it's set.
if (errorformat == p_efm && tv == NULL && buf && *buf->b_p_efm != NUL) {
- efm = buf->b_p_efm;
+ efm = (char *)buf->b_p_efm;
} else {
efm = errorformat;
}
@@ -1110,7 +1121,7 @@ static int qf_init_ext(qf_info_T *qi, int qf_idx, const char_u *restrict efile,
// parse the current 'efm'
fmt_first = parse_efm_option(efm);
if (fmt_first != NULL) {
- last_efm = vim_strsave(efm);
+ last_efm = xstrdup(efm);
}
}
@@ -1173,14 +1184,14 @@ qf_init_end:
/// Set the title of the specified quickfix list. Frees the previous title.
/// Prepends ':' to the title.
-static void qf_store_title(qf_list_T *qfl, const char_u *title)
+static void qf_store_title(qf_list_T *qfl, const char *title)
FUNC_ATTR_NONNULL_ARG(1)
{
XFREE_CLEAR(qfl->qf_title);
if (title != NULL) {
size_t len = STRLEN(title) + 1;
- char_u *p = xmallocz(len);
+ char *p = xmallocz(len);
qfl->qf_title = p;
STRLCPY(p, title, len + 1);
@@ -1191,11 +1202,11 @@ static void qf_store_title(qf_list_T *qfl, const char_u *title)
/// that created the quickfix list with the ":" prefix.
/// Create a quickfix list title string by prepending ":" to a user command.
/// Returns a pointer to a static buffer with the title.
-static char_u *qf_cmdtitle(char_u *cmd)
+static char *qf_cmdtitle(char *cmd)
{
- static char_u qftitle_str[IOSIZE];
+ static char qftitle_str[IOSIZE];
- snprintf((char *)qftitle_str, IOSIZE, ":%s", (char *)cmd);
+ snprintf((char *)qftitle_str, IOSIZE, ":%s", cmd);
return qftitle_str;
}
@@ -1210,7 +1221,7 @@ static qf_list_T *qf_get_curlist(qf_info_T *qi)
/// Prepare for adding a new quickfix list. If the current list is in the
/// middle of the stack, then all the following lists are freed and then
/// the new list is added.
-static void qf_new_list(qf_info_T *qi, const char_u *qf_title)
+static void qf_new_list(qf_info_T *qi, const char *qf_title)
{
int i;
qf_list_T *qfl;
@@ -1244,22 +1255,22 @@ static void qf_new_list(qf_info_T *qi, const char_u *qf_title)
/// Return the matched value in "fields->namebuf".
static int qf_parse_fmt_f(regmatch_T *rmp, int midx, qffields_T *fields, int prefix)
{
- char_u c;
+ char c;
if (rmp->startp[midx] == NULL || rmp->endp[midx] == NULL) {
return QF_FAIL;
}
// Expand ~/file and $HOME/file to full path.
- c = *rmp->endp[midx];
+ c = (char)(*rmp->endp[midx]);
*rmp->endp[midx] = NUL;
- expand_env(rmp->startp[midx], fields->namebuf, CMDBUFFSIZE);
- *rmp->endp[midx] = c;
+ expand_env(rmp->startp[midx], (char_u *)fields->namebuf, CMDBUFFSIZE);
+ *rmp->endp[midx] = (char_u)c;
// For separate filename patterns (%O, %P and %Q), the specified file
// should exist.
- if (vim_strchr((char_u *)"OPQ", prefix) != NULL
- && !os_path_exists(fields->namebuf)) {
+ if (vim_strchr("OPQ", prefix) != NULL
+ && !os_path_exists((char_u *)fields->namebuf)) {
return QF_FAIL;
}
@@ -1277,14 +1288,25 @@ static int qf_parse_fmt_n(regmatch_T *rmp, int midx, qffields_T *fields)
return QF_OK;
}
-/// Parse the match for line number (%l') pattern in regmatch.
+/// Parse the match for line number ('%l') pattern in regmatch.
/// Return the matched value in "fields->lnum".
static int qf_parse_fmt_l(regmatch_T *rmp, int midx, qffields_T *fields)
{
if (rmp->startp[midx] == NULL) {
return QF_FAIL;
}
- fields->lnum = atol((char *)rmp->startp[midx]);
+ fields->lnum = (linenr_T)atol((char *)rmp->startp[midx]);
+ return QF_OK;
+}
+
+/// Parse the match for end line number ('%e') pattern in regmatch.
+/// Return the matched value in "fields->end_lnum".
+static int qf_parse_fmt_e(regmatch_T *rmp, int midx, qffields_T *fields)
+{
+ if (rmp->startp[midx] == NULL) {
+ return QF_FAIL;
+ }
+ fields->end_lnum = (linenr_T)atol((char *)rmp->startp[midx]);
return QF_OK;
}
@@ -1299,6 +1321,17 @@ static int qf_parse_fmt_c(regmatch_T *rmp, int midx, qffields_T *fields)
return QF_OK;
}
+/// Parse the match for end line number ('%e') pattern in regmatch.
+/// Return the matched value in "fields->end_lnum".
+static int qf_parse_fmt_k(regmatch_T *rmp, int midx, qffields_T *fields)
+{
+ if (rmp->startp[midx] == NULL) {
+ return QF_FAIL;
+ }
+ fields->end_col = (int)atol((char *)rmp->startp[midx]);
+ return QF_OK;
+}
+
/// Parse the match for error type ('%t') pattern in regmatch.
/// Return the matched value in "fields->type".
static int qf_parse_fmt_t(regmatch_T *rmp, int midx, qffields_T *fields)
@@ -1306,13 +1339,13 @@ static int qf_parse_fmt_t(regmatch_T *rmp, int midx, qffields_T *fields)
if (rmp->startp[midx] == NULL) {
return QF_FAIL;
}
- fields->type = *rmp->startp[midx];
+ fields->type = (char)(*rmp->startp[midx]);
return QF_OK;
}
/// Parse the match for '%+' format pattern. The whole matching line is included
/// in the error string. Return the matched line in "fields->errmsg".
-static void qf_parse_fmt_plus(const char_u *linebuf, size_t linelen, qffields_T *fields)
+static void qf_parse_fmt_plus(const char *linebuf, size_t linelen, qffields_T *fields)
FUNC_ATTR_NONNULL_ALL
{
if (linelen >= fields->errmsglen) {
@@ -1344,12 +1377,12 @@ static int qf_parse_fmt_m(regmatch_T *rmp, int midx, qffields_T *fields)
/// Parse the match for rest of a single-line file message ('%r') pattern.
/// Return the matched value in "tail".
-static int qf_parse_fmt_r(regmatch_T *rmp, int midx, char_u **tail)
+static int qf_parse_fmt_r(regmatch_T *rmp, int midx, char **tail)
{
if (rmp->startp[midx] == NULL) {
return QF_FAIL;
}
- *tail = rmp->startp[midx];
+ *tail = (char *)rmp->startp[midx];
return QF_OK;
}
@@ -1357,13 +1390,13 @@ static int qf_parse_fmt_r(regmatch_T *rmp, int midx, char_u **tail)
/// Return the matched value in "fields->col".
static int qf_parse_fmt_p(regmatch_T *rmp, int midx, qffields_T *fields)
{
- char_u *match_ptr;
+ char *match_ptr;
if (rmp->startp[midx] == NULL || rmp->endp[midx] == NULL) {
return QF_FAIL;
}
fields->col = 0;
- for (match_ptr = rmp->startp[midx]; match_ptr != rmp->endp[midx];
+ for (match_ptr = (char *)rmp->startp[midx]; (char_u *)match_ptr != rmp->endp[midx];
match_ptr++) {
fields->col++;
if (*match_ptr == TAB) {
@@ -1431,14 +1464,17 @@ static int qf_parse_fmt_o(regmatch_T *rmp, int midx, qffields_T *fields)
/// 'errorformat' format pattern parser functions.
/// The '%f' and '%r' formats are parsed differently from other formats.
/// See qf_parse_match() for details.
+/// Keep in sync with fmt_pat[].
static int (*qf_parse_fmt[FMT_PATTERNS])(regmatch_T *, int, qffields_T *) = {
- NULL,
+ NULL, // %f
qf_parse_fmt_n,
qf_parse_fmt_l,
+ qf_parse_fmt_e,
qf_parse_fmt_c,
+ qf_parse_fmt_k,
qf_parse_fmt_t,
qf_parse_fmt_m,
- NULL,
+ NULL, // %r
qf_parse_fmt_p,
qf_parse_fmt_v,
qf_parse_fmt_s,
@@ -1449,10 +1485,10 @@ static int (*qf_parse_fmt[FMT_PATTERNS])(regmatch_T *, int, qffields_T *) = {
/// fmt_ptr contains the 'efm' format specifiers/prefixes that have a match.
/// Returns QF_OK if all the matches are successfully parsed. On failure,
/// returns QF_FAIL or QF_NOMEM.
-static int qf_parse_match(char_u *linebuf, size_t linelen, efm_T *fmt_ptr, regmatch_T *regmatch,
- qffields_T *fields, int qf_multiline, int qf_multiscan, char_u **tail)
+static int qf_parse_match(char *linebuf, size_t linelen, efm_T *fmt_ptr, regmatch_T *regmatch,
+ qffields_T *fields, int qf_multiline, int qf_multiscan, char **tail)
{
- char_u idx = fmt_ptr->prefix;
+ char idx = fmt_ptr->prefix;
int i;
int midx;
int status;
@@ -1460,7 +1496,7 @@ static int qf_parse_match(char_u *linebuf, size_t linelen, efm_T *fmt_ptr, regma
if ((idx == 'C' || idx == 'Z') && !qf_multiline) {
return QF_FAIL;
}
- if (vim_strchr((char_u *)"EWIN", idx) != NULL) {
+ if (vim_strchr("EWIN", idx) != NULL) {
fields->type = idx;
} else {
fields->type = 0;
@@ -1474,13 +1510,13 @@ static int qf_parse_match(char_u *linebuf, size_t linelen, efm_T *fmt_ptr, regma
midx = (int)fmt_ptr->addr[i];
if (i == 0 && midx > 0) { // %f
status = qf_parse_fmt_f(regmatch, midx, fields, idx);
- } else if (i == 5) {
+ } else if (i == FMT_PATTERN_M) {
if (fmt_ptr->flags == '+' && !qf_multiscan) { // %+
qf_parse_fmt_plus(linebuf, linelen, fields);
} else if (midx > 0) { // %m
status = qf_parse_fmt_m(regmatch, midx, fields);
}
- } else if (i == 6 && midx > 0) { // %r
+ } else if (i == FMT_PATTERN_R && midx > 0) { // %r
status = qf_parse_fmt_r(regmatch, midx, tail);
} else if (midx > 0) { // others
status = (qf_parse_fmt[i])(regmatch, midx, fields);
@@ -1498,14 +1534,14 @@ static int qf_parse_match(char_u *linebuf, size_t linelen, efm_T *fmt_ptr, regma
/// 'fmt_ptr->prog' and return the matching values in 'fields'.
/// Returns QF_OK if the efm format matches completely and the fields are
/// successfully copied. Otherwise returns QF_FAIL or QF_NOMEM.
-static int qf_parse_get_fields(char_u *linebuf, size_t linelen, efm_T *fmt_ptr, qffields_T *fields,
- int qf_multiline, int qf_multiscan, char_u **tail)
+static int qf_parse_get_fields(char *linebuf, size_t linelen, efm_T *fmt_ptr, qffields_T *fields,
+ int qf_multiline, int qf_multiscan, char **tail)
{
regmatch_T regmatch;
int status = QF_FAIL;
int r;
- if (qf_multiscan && vim_strchr((char_u *)"OPQ", fmt_ptr->prefix) == NULL) {
+ if (qf_multiscan && vim_strchr("OPQ", fmt_ptr->prefix) == NULL) {
return QF_FAIL;
}
@@ -1559,13 +1595,12 @@ static int qf_parse_dir_pfx(int idx, qffields_T *fields, qf_list_T *qfl)
}
/// Parse global file name error format prefixes (%O, %P and %Q).
-static int qf_parse_file_pfx(int idx, qffields_T *fields, qf_list_T *qfl, char_u *tail)
+static int qf_parse_file_pfx(int idx, qffields_T *fields, qf_list_T *qfl, char *tail)
{
fields->valid = false;
- if (*fields->namebuf == NUL || os_path_exists(fields->namebuf)) {
+ if (*fields->namebuf == NUL || os_path_exists((char_u *)fields->namebuf)) {
if (*fields->namebuf && idx == 'P') {
- qfl->qf_currfile = qf_push_dir(fields->namebuf, &qfl->qf_file_stack,
- true);
+ qfl->qf_currfile = qf_push_dir(fields->namebuf, &qfl->qf_file_stack, true);
} else if (idx == 'Q') {
qfl->qf_currfile = qf_pop_dir(&qfl->qf_file_stack);
}
@@ -1582,7 +1617,7 @@ static int qf_parse_file_pfx(int idx, qffields_T *fields, qf_list_T *qfl, char_u
/// Parse a non-error line (a line which doesn't match any of the error
/// format in 'efm').
-static int qf_parse_line_nomatch(char_u *linebuf, size_t linelen, qffields_T *fields)
+static int qf_parse_line_nomatch(char *linebuf, size_t linelen, qffields_T *fields)
{
fields->namebuf[0] = NUL; // no match found, remove file name
fields->lnum = 0; // don't jump to this line
@@ -1625,10 +1660,16 @@ static int qf_parse_multiline_pfx(int idx, qf_list_T *qfl, qffields_T *fields)
if (!qfprev->qf_lnum) {
qfprev->qf_lnum = fields->lnum;
}
+ if (!qfprev->qf_end_lnum) {
+ qfprev->qf_end_lnum = fields->end_lnum;
+ }
if (!qfprev->qf_col) {
qfprev->qf_col = fields->col;
qfprev->qf_viscol = fields->use_viscol;
}
+ if (!qfprev->qf_end_col) {
+ qfprev->qf_end_col = fields->end_col;
+ }
if (!qfprev->qf_fnum) {
qfprev->qf_fnum = qf_get_fnum(qfl, qfl->qf_directory,
*fields->namebuf || qfl->qf_directory
@@ -1656,6 +1697,28 @@ static void locstack_queue_delreq(qf_info_T *qi)
qf_delq_head = q;
}
+/// Return the global quickfix stack window buffer number.
+int qf_stack_get_bufnr(void)
+{
+ return ql_info.qf_bufnr;
+}
+
+/// Wipe the quickfix window buffer (if present) for the specified
+/// quickfix/location list.
+static void wipe_qf_buffer(qf_info_T *qi)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (qi->qf_bufnr != INVALID_QFBUFNR) {
+ buf_T *const qfbuf = buflist_findnr(qi->qf_bufnr);
+ if (qfbuf != NULL && qfbuf->b_nwindows == 0) {
+ // If the quickfix buffer is not loaded in any window, then
+ // wipe the buffer.
+ close_buffer(NULL, qfbuf, DOBUF_WIPE, false, false);
+ qi->qf_bufnr = INVALID_QFBUFNR;
+ }
+ }
+}
+
/// Free a location list stack
static void ll_free_all(qf_info_T **pqi)
{
@@ -1668,19 +1731,23 @@ static void ll_free_all(qf_info_T **pqi)
}
*pqi = NULL; // Remove reference to this list
+ // If the location list is still in use, then queue the delete request
+ // to be processed later.
+ if (quickfix_busy > 0) {
+ locstack_queue_delreq(qi);
+ return;
+ }
+
qi->qf_refcount--;
if (qi->qf_refcount < 1) {
// No references to this location list.
- // If the location list is still in use, then queue the delete request
- // to be processed later.
- if (quickfix_busy > 0) {
- locstack_queue_delreq(qi);
- } else {
- for (i = 0; i < qi->qf_listcount; i++) {
- qf_free(qf_get_list(qi, i));
- }
- xfree(qi);
+ // If the quickfix window buffer is loaded, then wipe it
+ wipe_qf_buffer(qi);
+
+ for (i = 0; i < qi->qf_listcount; i++) {
+ qf_free(qf_get_list(qi, i));
}
+ xfree(qi);
}
}
@@ -1765,9 +1832,9 @@ void check_quickfix_busy(void)
/// @param valid valid entry
///
/// @returns QF_OK or QF_FAIL.
-static int qf_add_entry(qf_list_T *qfl, char_u *dir, char_u *fname, char_u *module, int bufnum,
- char_u *mesg, long lnum, long end_lnum, int col, int end_col,
- char_u vis_col, char_u *pattern, int nr, char_u type, char_u valid)
+static int qf_add_entry(qf_list_T *qfl, char *dir, char *fname, char *module, int bufnum,
+ char *mesg, linenr_T lnum, linenr_T end_lnum, int col, int end_col,
+ char vis_col, char *pattern, int nr, char type, char valid)
{
qfline_T *qfp = xmalloc(sizeof(qfline_T));
qfline_T **lastp; // pointer to qf_last or NULL
@@ -1783,7 +1850,7 @@ static int qf_add_entry(qf_list_T *qfl, char_u *dir, char_u *fname, char_u *modu
} else {
qfp->qf_fnum = qf_get_fnum(qfl, dir, fname);
}
- qfp->qf_text = vim_strsave(mesg);
+ qfp->qf_text = xstrdup(mesg);
qfp->qf_lnum = lnum;
qfp->qf_end_lnum = end_lnum;
qfp->qf_col = col;
@@ -1792,12 +1859,12 @@ static int qf_add_entry(qf_list_T *qfl, char_u *dir, char_u *fname, char_u *modu
if (pattern == NULL || *pattern == NUL) {
qfp->qf_pattern = NULL;
} else {
- qfp->qf_pattern = vim_strsave(pattern);
+ qfp->qf_pattern = xstrdup(pattern);
}
if (module == NULL || *module == NUL) {
qfp->qf_module = NULL;
} else {
- qfp->qf_module = vim_strsave(module);
+ qfp->qf_module = xstrdup(module);
}
qfp->qf_nr = nr;
if (type != 1 && !vim_isprintc(type)) { // only printable chars allowed
@@ -1838,6 +1905,7 @@ static qf_info_T *qf_alloc_stack(qfltype_T qfltype)
qf_info_T *qi = xcalloc(1, sizeof(qf_info_T));
qi->qf_refcount++;
qi->qfl_type = qfltype;
+ qi->qf_bufnr = INVALID_QFBUFNR;
return qi;
}
@@ -1954,7 +2022,7 @@ static int copy_loclist(qf_list_T *from_qfl, qf_list_T *to_qfl)
to_qfl->qf_last = NULL;
to_qfl->qf_ptr = NULL;
if (from_qfl->qf_title != NULL) {
- to_qfl->qf_title = vim_strsave(from_qfl->qf_title);
+ to_qfl->qf_title = xstrdup(from_qfl->qf_title);
} else {
to_qfl->qf_title = NULL;
}
@@ -1964,7 +2032,7 @@ static int copy_loclist(qf_list_T *from_qfl, qf_list_T *to_qfl)
} else {
to_qfl->qf_ctx = NULL;
}
- callback_copy(&to_qfl->qftf_cb, &from_qfl->qftf_cb);
+ callback_copy(&to_qfl->qf_qftf_cb, &from_qfl->qf_qftf_cb);
if (from_qfl->qf_count) {
if (copy_loclist_entries(from_qfl, to_qfl) == FAIL) {
@@ -2028,10 +2096,10 @@ void copy_loclist_stack(win_T *from, win_T *to)
/// Get buffer number for file "directory/fname".
/// Also sets the b_has_qf_entry flag.
-static int qf_get_fnum(qf_list_T *qfl, char_u *directory, char_u *fname)
+static int qf_get_fnum(qf_list_T *qfl, char *directory, char *fname)
{
- char_u *ptr = NULL;
- char_u *bufname;
+ char *ptr = NULL;
+ char *bufname;
buf_T *buf;
if (fname == NULL || *fname == NUL) { // no file name
return 0;
@@ -2043,19 +2111,19 @@ static int qf_get_fnum(qf_list_T *qfl, char_u *directory, char_u *fname)
}
slash_adjust(fname);
#endif
- if (directory != NULL && !vim_isAbsName(fname)) {
- ptr = (char_u *)concat_fnames((char *)directory, (char *)fname, true);
+ if (directory != NULL && !vim_isAbsName((char_u *)fname)) {
+ ptr = concat_fnames(directory, fname, true);
// Here we check if the file really exists.
// This should normally be true, but if make works without
// "leaving directory"-messages we might have missed a
// directory change.
- if (!os_path_exists(ptr)) {
+ if (!os_path_exists((char_u *)ptr)) {
xfree(ptr);
directory = qf_guess_filepath(qfl, fname);
if (directory) {
- ptr = (char_u *)concat_fnames((char *)directory, (char *)fname, true);
+ ptr = concat_fnames(directory, fname, true);
} else {
- ptr = vim_strsave(fname);
+ ptr = xstrdup(fname);
}
}
// Use concatenated directory name and file name.
@@ -2072,7 +2140,7 @@ static int qf_get_fnum(qf_list_T *qfl, char_u *directory, char_u *fname)
} else {
xfree(qf_last_bufname);
buf = buflist_new(bufname, NULL, (linenr_T)0, BLN_NOOPT);
- qf_last_bufname = (bufname == ptr) ? bufname : vim_strsave(bufname);
+ qf_last_bufname = (bufname == ptr) ? bufname : xstrdup(bufname);
set_bufref(&qf_last_bufref, buf);
}
if (buf == NULL) {
@@ -2085,7 +2153,7 @@ static int qf_get_fnum(qf_list_T *qfl, char_u *directory, char_u *fname)
// Push dirbuf onto the directory stack and return pointer to actual dir or
// NULL on error.
-static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr, bool is_file_stack)
+static char *qf_push_dir(char *dirbuf, struct dir_stack_T **stackptr, bool is_file_stack)
{
struct dir_stack_T *ds_ptr;
@@ -2096,10 +2164,10 @@ static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr, bool i
*stackptr = ds_new;
// store directory on the stack
- if (vim_isAbsName(dirbuf)
+ if (vim_isAbsName((char_u *)dirbuf)
|| (*stackptr)->next == NULL
- || (*stackptr && is_file_stack)) {
- (*stackptr)->dirname = vim_strsave(dirbuf);
+ || is_file_stack) {
+ (*stackptr)->dirname = xstrdup(dirbuf);
} else {
// Okay we don't have an absolute path.
// dirbuf must be a subdir of one of the directories on the stack.
@@ -2108,9 +2176,8 @@ static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr, bool i
(*stackptr)->dirname = NULL;
while (ds_new) {
xfree((*stackptr)->dirname);
- (*stackptr)->dirname = (char_u *)concat_fnames((char *)ds_new->dirname,
- (char *)dirbuf, TRUE);
- if (os_isdir((*stackptr)->dirname)) {
+ (*stackptr)->dirname = concat_fnames(ds_new->dirname, dirbuf, true);
+ if (os_isdir((char_u *)(*stackptr)->dirname)) {
break;
}
@@ -2128,7 +2195,7 @@ static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr, bool i
// Nothing found -> it must be on top level
if (ds_new == NULL) {
xfree((*stackptr)->dirname);
- (*stackptr)->dirname = vim_strsave(dirbuf);
+ (*stackptr)->dirname = xstrdup(dirbuf);
}
}
@@ -2142,10 +2209,9 @@ static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr, bool i
}
}
-
// pop dirbuf from the directory stack and return previous directory or NULL if
// stack is empty
-static char_u *qf_pop_dir(struct dir_stack_T **stackptr)
+static char *qf_pop_dir(struct dir_stack_T **stackptr)
{
struct dir_stack_T *ds_ptr;
@@ -2194,11 +2260,11 @@ static void qf_clean_dir_stack(struct dir_stack_T **stackptr)
/// x.c:9: Error
/// Then qf_push_dir thinks we are in ./aa/bb, but we are in ./bb.
/// qf_guess_filepath will return NULL.
-static char_u *qf_guess_filepath(qf_list_T *qfl, char_u *filename)
+static char *qf_guess_filepath(qf_list_T *qfl, char *filename)
{
struct dir_stack_T *ds_ptr;
struct dir_stack_T *ds_tmp;
- char_u *fullname;
+ char *fullname;
// no dirs on the stack - there's nothing we can do
if (qfl->qf_dir_stack == NULL) {
@@ -2209,9 +2275,9 @@ static char_u *qf_guess_filepath(qf_list_T *qfl, char_u *filename)
fullname = NULL;
while (ds_ptr) {
xfree(fullname);
- fullname = (char_u *)concat_fnames((char *)ds_ptr->dirname, (char *)filename, TRUE);
+ fullname = concat_fnames(ds_ptr->dirname, filename, true);
- if (os_path_exists(fullname)) {
+ if (os_path_exists((char_u *)fullname)) {
break;
}
@@ -2237,7 +2303,10 @@ static bool qflist_valid(win_T *wp, unsigned int qf_id)
qf_info_T *qi = &ql_info;
if (wp) {
- qi = GET_LOC_LIST(wp);
+ if (!win_valid(wp)) {
+ return false;
+ }
+ qi = GET_LOC_LIST(wp); // Location list
if (!qi) {
return false;
}
@@ -2325,7 +2394,7 @@ static qfline_T *get_nth_valid_entry(qf_list_T *qfl, int errornr, int dir, int *
int qf_idx = qfl->qf_index;
qfline_T *prev_qf_ptr;
int prev_index;
- char_u *err = e_no_more_items;
+ char *err = e_no_more_items;
while (errornr--) {
prev_qf_ptr = qf_ptr;
@@ -2399,7 +2468,7 @@ static qfline_T *qf_get_entry(qf_list_T *qfl, int errornr, int dir, int *new_qfi
return qf_ptr;
}
-// Find a window displaying a Vim help file.
+// Find a window displaying a Vim help file in the current tab page.
static win_T *qf_find_help_win(void)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -2424,7 +2493,7 @@ static int jump_to_help_window(qf_info_T *qi, bool newwin, int *opened_window)
{
win_T *wp = NULL;
- if (cmdmod.tab != 0 || newwin) {
+ if (cmdmod.cmod_tab != 0 || newwin) {
wp = NULL;
} else {
wp = qf_find_help_win();
@@ -2436,7 +2505,7 @@ static int jump_to_help_window(qf_info_T *qi, bool newwin, int *opened_window)
// Split off help window; put it at far top if no position
// specified, the current window is vertically split and narrow.
int flags = WSP_HELP;
- if (cmdmod.split == 0
+ if (cmdmod.cmod_split == 0
&& curwin->w_width != Columns
&& curwin->w_width < 80) {
flags |= WSP_TOP;
@@ -2466,15 +2535,14 @@ static int jump_to_help_window(qf_info_T *qi, bool newwin, int *opened_window)
}
}
- if (!p_im) {
- restart_edit = 0; // don't want insert mode in help file
- }
+ restart_edit = 0; // don't want insert mode in help file
return OK;
}
-// Find a non-quickfix window using the given location list.
-// Returns NULL if a matching window is not found.
+/// Find a non-quickfix window using the given location list stack in the
+/// current tabpage.
+/// Returns NULL if a matching window is not found.
static win_T *qf_find_win_with_loclist(const qf_info_T *ll)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -2486,7 +2554,7 @@ static win_T *qf_find_win_with_loclist(const qf_info_T *ll)
return NULL;
}
-// Find a window containing a normal buffer
+/// Find a window containing a normal buffer in the current tab page.
static win_T *qf_find_win_with_normal_buf(void)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -2542,7 +2610,7 @@ static void qf_goto_win_with_ll_file(win_T *use_win, int qf_fnum, qf_info_T *ll_
win_T *win = use_win;
if (win == NULL) {
- // Find the window showing the selected file
+ // Find the window showing the selected file in the current tab page.
FOR_ALL_WINDOWS_IN_TAB(win2, curtab) {
if (win2->w_buffer->b_fnum == qf_fnum) {
win = win2;
@@ -2674,7 +2742,7 @@ static int qf_jump_to_usable_window(int qf_fnum, bool newwin, int *opened_window
}
/// Edit the selected file or help file.
-static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit, win_T *oldwin,
+static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit, int prev_winid,
int *opened_window)
{
qf_list_T *qfl = qf_get_curlist(qi);
@@ -2693,7 +2761,7 @@ static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit, win
} else {
retval = do_ecmd(qf_ptr->qf_fnum, NULL, NULL, NULL, (linenr_T)1,
ECMD_HIDE + ECMD_SET_HELP,
- oldwin == curwin ? curwin : NULL);
+ prev_winid == curwin->handle ? curwin : NULL);
}
} else {
retval = buflist_getfile(qf_ptr->qf_fnum, (linenr_T)1,
@@ -2701,10 +2769,14 @@ static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit, win
}
// If a location list, check whether the associated window is still
// present.
- if (qfl_type == QFLT_LOCATION && !win_valid_any_tab(oldwin)) {
- emsg(_("E924: Current window was closed"));
- *opened_window = false;
- return NOTDONE;
+ if (qfl_type == QFLT_LOCATION) {
+ win_T *wp = win_id2wp(prev_winid);
+
+ if (wp == NULL && curwin->w_llist != qi) {
+ emsg(_("E924: Current window was closed"));
+ *opened_window = false;
+ return NOTDONE;
+ }
}
if (qfl_type == QFLT_QUICKFIX && !qflist_valid(NULL, save_qfid)) {
@@ -2712,8 +2784,8 @@ static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit, win
return NOTDONE;
}
- if (old_qf_curlist != qi->qf_curlist
- || old_changetick != qfl->qf_changedtick
+ if (old_qf_curlist != qi->qf_curlist // -V560
+ || old_changetick != qfl->qf_changedtick // -V560
|| !is_qf_entry_present(qfl, qf_ptr)) {
if (qfl_type == QFLT_QUICKFIX) {
emsg(_(e_current_quickfix_list_was_changed));
@@ -2728,7 +2800,7 @@ static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit, win
/// Go to the error line in the current file using either line/column number or
/// a search pattern.
-static void qf_jump_goto_line(linenr_T qf_lnum, int qf_col, char_u qf_viscol, char_u *qf_pattern)
+static void qf_jump_goto_line(linenr_T qf_lnum, int qf_col, char qf_viscol, char *qf_pattern)
{
linenr_T i;
@@ -2757,7 +2829,7 @@ static void qf_jump_goto_line(linenr_T qf_lnum, int qf_col, char_u qf_viscol, ch
// Move the cursor to the first line in the buffer
pos_T save_cursor = curwin->w_cursor;
curwin->w_cursor.lnum = 0;
- if (!do_search(NULL, '/', '/', qf_pattern, (long)1, SEARCH_KEEP, NULL)) {
+ if (!do_search(NULL, '/', '/', (char_u *)qf_pattern, (long)1, SEARCH_KEEP, NULL)) {
curwin->w_cursor = save_cursor;
}
}
@@ -2775,10 +2847,10 @@ static void qf_jump_print_msg(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, buf
snprintf((char *)IObuff, IOSIZE, _("(%d of %d)%s%s: "), qf_index,
qf_get_curlist(qi)->qf_count,
qf_ptr->qf_cleared ? _(" (line deleted)") : "",
- (char *)qf_types(qf_ptr->qf_type, qf_ptr->qf_nr));
+ qf_types(qf_ptr->qf_type, qf_ptr->qf_nr));
// Add the message, skipping leading whitespace and newlines.
int len = (int)STRLEN(IObuff);
- qf_fmt_text(skipwhite(qf_ptr->qf_text), IObuff + len, IOSIZE - len);
+ qf_fmt_text(skipwhite(qf_ptr->qf_text), (char *)IObuff + len, IOSIZE - len);
// Output the message. Overwrite to avoid scrolling when the 'O'
// flag is present in 'shortmess'; But when not jumping, print the
@@ -2808,13 +2880,13 @@ static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, bool newwin, int
qfltype_T qfl_type = qfl->qfl_type;
// For ":helpgrep" find a help window or open one.
- if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.tab != 0)) {
+ if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.cmod_tab != 0)) {
if (jump_to_help_window(qi, newwin, opened_window) == FAIL) {
return FAIL;
}
}
if (old_qf_curlist != qi->qf_curlist
- || old_changetick != qfl->qf_changedtick
+ || old_changetick != qfl->qf_changedtick // -V560
|| !is_qf_entry_present(qfl, qf_ptr)) {
if (qfl_type == QFLT_QUICKFIX) {
emsg(_(e_current_quickfix_list_was_changed));
@@ -2859,7 +2931,7 @@ static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, bool newwin, int
/// NOTDONE 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,
- win_T *oldwin, int *opened_window, int openfold, int print_message)
+ int prev_winid, int *opened_window, int openfold, int print_message)
{
buf_T *old_curbuf;
linenr_T old_lnum;
@@ -2871,7 +2943,7 @@ static int qf_jump_to_buffer(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, int
old_lnum = curwin->w_cursor.lnum;
if (qf_ptr->qf_fnum != 0) {
- retval = qf_jump_edit_buffer(qi, qf_ptr, forceit, oldwin,
+ retval = qf_jump_edit_buffer(qi, qf_ptr, forceit, prev_winid,
opened_window);
if (retval != OK) {
return retval;
@@ -2883,8 +2955,7 @@ static int qf_jump_to_buffer(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, int
setpcmark();
}
- qf_jump_goto_line(qf_ptr->qf_lnum, qf_ptr->qf_col, qf_ptr->qf_viscol,
- qf_ptr->qf_pattern);
+ qf_jump_goto_line(qf_ptr->qf_lnum, qf_ptr->qf_col, qf_ptr->qf_viscol, qf_ptr->qf_pattern);
if ((fdo_flags & FDO_QUICKFIX) && openfold) {
foldOpenCursor();
@@ -2918,10 +2989,10 @@ static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit, boo
qfline_T *old_qf_ptr;
int qf_index;
int old_qf_index;
- char_u *old_swb = p_swb;
+ char *old_swb = (char *)p_swb;
unsigned old_swb_flags = swb_flags;
+ int prev_winid;
int opened_window = false;
- win_T *oldwin = curwin;
int print_message = true;
const bool old_KeyTyped = KeyTyped; // getting file may reset it
int retval = OK;
@@ -2935,6 +3006,8 @@ static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit, boo
return;
}
+ incr_quickfix_busy();
+
qfl = qf_get_curlist(qi);
qf_ptr = qfl->qf_ptr;
@@ -2957,6 +3030,8 @@ static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit, boo
print_message = false;
}
+ prev_winid = curwin->handle;
+
retval = qf_jump_open_window(qi, qf_ptr, newwin, &opened_window);
if (retval == FAIL) {
goto failed;
@@ -2965,7 +3040,7 @@ static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit, boo
goto theend;
}
- retval = qf_jump_to_buffer(qi, qf_index, qf_ptr, forceit, oldwin,
+ retval = qf_jump_to_buffer(qi, qf_index, qf_ptr, forceit, prev_winid,
&opened_window, old_KeyTyped, print_message);
if (retval == NOTDONE) {
// Quickfix/location list is freed by an autocmd
@@ -2975,7 +3050,7 @@ static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit, boo
if (retval != OK) {
if (opened_window) {
- win_close(curwin, true); // Close opened window
+ win_close(curwin, true, false); // Close opened window
}
if (qf_ptr != NULL && qf_ptr->qf_fnum != 0) {
// Couldn't open file, so put index back where it was. This could
@@ -2990,15 +3065,15 @@ theend:
qfl->qf_ptr = qf_ptr;
qfl->qf_index = qf_index;
}
- if (p_swb != old_swb && p_swb == empty_option && opened_window) {
+ if (p_swb != (char_u *)old_swb && p_swb == empty_option) {
// Restore old 'switchbuf' value, but not when an autocommand or
// modeline has changed the value.
- p_swb = old_swb;
+ p_swb = (char_u *)old_swb;
swb_flags = old_swb_flags;
}
+ decr_quickfix_busy();
}
-
// Highlight attributes used for displaying entries from the quickfix list.
static int qfFileAttr;
static int qfSepAttr;
@@ -3010,13 +3085,12 @@ static int qfLineAttr;
/// quickfix list.
static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel)
{
- char_u *fname;
+ char *fname;
buf_T *buf;
fname = NULL;
if (qfp->qf_module != NULL && *qfp->qf_module != NUL) {
- vim_snprintf((char *)IObuff, IOSIZE, "%2d %s", qf_idx,
- (char *)qfp->qf_module);
+ vim_snprintf((char *)IObuff, IOSIZE, "%2d %s", qf_idx, qfp->qf_module);
} else {
if (qfp->qf_fnum != 0
&& (buf = buflist_findnr(qfp->qf_fnum)) != NULL) {
@@ -3028,8 +3102,7 @@ static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel)
if (fname == NULL) {
snprintf((char *)IObuff, IOSIZE, "%2d", qf_idx);
} else {
- vim_snprintf((char *)IObuff, IOSIZE, "%2d %s",
- qf_idx, (char *)fname);
+ vim_snprintf((char *)IObuff, IOSIZE, "%2d %s", qf_idx, fname);
}
}
@@ -3038,16 +3111,16 @@ static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel)
// text of the entry.
bool filter_entry = true;
if (qfp->qf_module != NULL && *qfp->qf_module != NUL) {
- filter_entry &= message_filtered(qfp->qf_module);
+ filter_entry &= message_filtered((char_u *)qfp->qf_module);
}
if (filter_entry && fname != NULL) {
- filter_entry &= message_filtered(fname);
+ filter_entry &= message_filtered((char_u *)fname);
}
if (filter_entry && qfp->qf_pattern != NULL) {
- filter_entry &= message_filtered(qfp->qf_pattern);
+ filter_entry &= message_filtered((char_u *)qfp->qf_pattern);
}
if (filter_entry) {
- filter_entry &= message_filtered(qfp->qf_text);
+ filter_entry &= message_filtered((char_u *)qfp->qf_text);
}
if (filter_entry) {
return;
@@ -3062,14 +3135,13 @@ static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel)
if (qfp->qf_lnum == 0) {
IObuff[0] = NUL;
} else {
- qf_range_text(qfp, IObuff, IOSIZE);
+ qf_range_text(qfp, (char *)IObuff, IOSIZE);
}
- vim_snprintf((char *)IObuff + STRLEN(IObuff), IOSIZE, "%s",
- (char *)qf_types(qfp->qf_type, qfp->qf_nr));
+ vim_snprintf((char *)IObuff + STRLEN(IObuff), IOSIZE, "%s", qf_types(qfp->qf_type, qfp->qf_nr));
msg_puts_attr((const char *)IObuff, qfLineAttr);
msg_puts_attr(":", qfSepAttr);
if (qfp->qf_pattern != NULL) {
- qf_fmt_text(qfp->qf_pattern, IObuff, IOSIZE);
+ qf_fmt_text(qfp->qf_pattern, (char *)IObuff, IOSIZE);
msg_puts((const char *)IObuff);
msg_puts_attr(":", qfSepAttr);
}
@@ -3080,7 +3152,7 @@ static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel)
// with ^^^^. */
qf_fmt_text((fname != NULL || qfp->qf_lnum != 0)
? skipwhite(qfp->qf_text) : qfp->qf_text,
- IObuff, IOSIZE);
+ (char *)IObuff, IOSIZE);
msg_prt_line(IObuff, false);
ui_flush(); // show one line at a time
}
@@ -3094,7 +3166,7 @@ void qf_list(exarg_T *eap)
int i;
int idx1 = 1;
int idx2 = -1;
- char_u *arg = eap->arg;
+ char *arg = eap->arg;
int all = eap->forceit; // if not :cl!, only show
// recognised errors
qf_info_T *qi;
@@ -3113,7 +3185,7 @@ void qf_list(exarg_T *eap)
arg++;
plus = true;
}
- if (!get_list_range(&arg, &idx1, &idx2) || *arg != NUL) {
+ if (!get_list_range((char_u **)&arg, &idx1, &idx2) || *arg != NUL) {
emsg(_(e_trailing));
return;
}
@@ -3163,11 +3235,11 @@ void qf_list(exarg_T *eap)
// Remove newlines and leading whitespace from an error message.
// Put the result in "buf[bufsize]".
-static void qf_fmt_text(const char_u *restrict text, char_u *restrict buf, int bufsize)
+static void qf_fmt_text(const char *restrict text, char *restrict buf, int bufsize)
FUNC_ATTR_NONNULL_ALL
{
int i;
- const char_u *p = text;
+ const char *p = (char *)text;
for (i = 0; *p != NUL && i < bufsize - 1; ++i) {
if (*p == '\n') {
@@ -3186,37 +3258,33 @@ static void qf_fmt_text(const char_u *restrict text, char_u *restrict buf, int b
// Range information from lnum, col, end_lnum, and end_col.
// Put the result in "buf[bufsize]".
-static void qf_range_text(const qfline_T *qfp, char_u *buf, int bufsize)
+static void qf_range_text(const qfline_T *qfp, char *buf, int bufsize)
{
- vim_snprintf((char *)buf, (size_t)bufsize, "%" PRIdLINENR, qfp->qf_lnum);
+ vim_snprintf(buf, (size_t)bufsize, "%" PRIdLINENR, qfp->qf_lnum);
int len = (int)STRLEN(buf);
if (qfp->qf_end_lnum > 0 && qfp->qf_lnum != qfp->qf_end_lnum) {
- vim_snprintf((char *)buf + len, (size_t)(bufsize - len),
- "-%" PRIdLINENR, qfp->qf_end_lnum);
+ vim_snprintf(buf + len, (size_t)(bufsize - len), "-%" PRIdLINENR, qfp->qf_end_lnum);
len += (int)STRLEN(buf + len);
}
if (qfp->qf_col > 0) {
- vim_snprintf((char *)buf + len, (size_t)(bufsize - len),
- " col %d", qfp->qf_col);
+ vim_snprintf(buf + len, (size_t)(bufsize - len), " col %d", qfp->qf_col);
len += (int)STRLEN(buf + len);
if (qfp->qf_end_col > 0 && qfp->qf_col != qfp->qf_end_col) {
- vim_snprintf((char *)buf + len, (size_t)(bufsize - len),
- "-%d", qfp->qf_end_col);
+ vim_snprintf(buf + len, (size_t)(bufsize - len), "-%d", qfp->qf_end_col);
len += (int)STRLEN(buf + len);
}
}
buf[len] = NUL;
}
-
/// Display information (list number, list size and the title) about a
/// quickfix/location list.
static void qf_msg(qf_info_T *qi, int which, char *lead)
{
- char *title = (char *)qi->qf_lists[which].qf_title;
+ char *title = qi->qf_lists[which].qf_title;
int count = qi->qf_lists[which].qf_count;
- char_u buf[IOSIZE];
+ char buf[IOSIZE];
vim_snprintf((char *)buf, IOSIZE, _("%serror list %d of %d; %d errors "),
lead,
@@ -3234,7 +3302,7 @@ static void qf_msg(qf_info_T *qi, int which, char *lead)
STRLCAT(buf, title, IOSIZE);
}
trunc_string(buf, buf, Columns - 1, IOSIZE);
- msg((char *)buf);
+ msg(buf);
}
/// ":colder [count]": Up in the quickfix stack.
@@ -3251,7 +3319,6 @@ void qf_age(exarg_T *eap)
}
if (eap->addr_count != 0) {
- assert(eap->line2 <= INT_MAX);
count = (int)eap->line2;
} else {
count = 1;
@@ -3289,7 +3356,7 @@ void qf_history(exarg_T *eap)
// Jump to the specified quickfix list
if (eap->line2 > 0 && eap->line2 <= qi->qf_listcount) {
- qi->qf_curlist = (int)(eap->line2 - 1);
+ qi->qf_curlist = eap->line2 - 1;
qf_msg(qi, qi->qf_curlist, "");
qf_update_buffer(qi, NULL);
} else {
@@ -3362,13 +3429,14 @@ static void qf_free(qf_list_T *qfl)
XFREE_CLEAR(qfl->qf_title);
tv_free(qfl->qf_ctx);
qfl->qf_ctx = NULL;
- callback_free(&qfl->qftf_cb);
+ callback_free(&qfl->qf_qftf_cb);
qfl->qf_id = 0;
qfl->qf_changedtick = 0L;
}
// qf_mark_adjust: adjust marks
-bool qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, long amount_after)
+bool qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, linenr_T amount,
+ linenr_T amount_after)
{
int i;
qfline_T *qfp;
@@ -3425,25 +3493,25 @@ bool qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, long
// 0 n " error n"
// other n " c n"
// 1 x "" :helpgrep
-static char_u *qf_types(int c, int nr)
+static char *qf_types(int c, int nr)
{
- static char_u buf[20];
- static char_u cc[3];
- char_u *p;
+ static char buf[20];
+ static char cc[3];
+ char *p;
if (c == 'W' || c == 'w') {
- p = (char_u *)" warning";
+ p = " warning";
} else if (c == 'I' || c == 'i') {
- p = (char_u *)" info";
+ p = " info";
} else if (c == 'N' || c == 'n') {
- p = (char_u *)" note";
+ p = " note";
} else if (c == 'E' || c == 'e' || (c == 0 && nr > 0)) {
- p = (char_u *)" error";
+ p = " error";
} else if (c == 0 || c == 1) {
- p = (char_u *)"";
+ p = "";
} else {
cc[0] = ' ';
- cc[1] = (char_u)c;
+ cc[1] = (char)c;
cc[2] = NUL;
p = cc;
}
@@ -3452,7 +3520,7 @@ static char_u *qf_types(int c, int nr)
return p;
}
- sprintf((char *)buf, "%s %3d", (char *)p, nr);
+ snprintf((char *)buf, sizeof(buf), "%s %3d", p, nr);
return buf;
}
@@ -3530,7 +3598,7 @@ void ex_cclose(exarg_T *eap)
// Find existing quickfix window and close it.
win = qf_find_win(qi);
if (win != NULL) {
- win_close(win, false);
+ win_close(win, false, false);
}
}
@@ -3550,7 +3618,7 @@ static int qf_goto_cwindow(const qf_info_T *qi, bool resize, int sz, bool vertsp
win_setwidth(sz);
}
} else if (sz != win->w_height
- && (win->w_height + win->w_status_height + tabline_height()
+ && (win->w_height + win->w_hsep_height + win->w_status_height + tabline_height()
< cmdline_row)) {
win_setheight(sz);
}
@@ -3565,7 +3633,7 @@ static void qf_set_cwindow_options(void)
// switch off 'swapfile'
set_option_value("swf", 0L, NULL, OPT_LOCAL);
set_option_value("bt", 0L, "quickfix", OPT_LOCAL);
- set_option_value("bh", 0L, "wipe", OPT_LOCAL);
+ set_option_value("bh", 0L, "hide", OPT_LOCAL);
RESET_BINDING(curwin);
curwin->w_p_diff = false;
set_option_value("fdm", 0L, "manual", OPT_LOCAL);
@@ -3586,35 +3654,26 @@ static int qf_open_new_cwindow(qf_info_T *qi, int height)
// The current window becomes the previous window afterwards.
win_T *const win = curwin;
- if (IS_QF_STACK(qi) && cmdmod.split == 0) {
+ if (IS_QF_STACK(qi) && cmdmod.cmod_split == 0) {
// Create the new quickfix window at the very bottom, except when
// :belowright or :aboveleft is used.
win_goto(lastwin);
}
// Default is to open the window below the current window
- if (cmdmod.split == 0) {
+ if (cmdmod.cmod_split == 0) {
flags = WSP_BELOW;
}
flags |= WSP_NEWLOC;
if (win_split(height, flags) == FAIL) {
return FAIL; // not enough room for window
}
-
- // User autocommands may have invalidated the previous window after calling
- // win_split, so add a check to ensure that the win is still here
- if (IS_LL_STACK(qi) && !win_valid(win)) {
- // close the window that was supposed to be for the loclist
- win_close(curwin, false);
- return FAIL;
- }
-
RESET_BINDING(curwin);
if (IS_LL_STACK(qi)) {
// For the location list window, create a reference to the
- // location list from the window 'win'.
- curwin->w_llist_ref = win->w_llist;
- win->w_llist->qf_refcount++;
+ // location list stack from the window 'win'.
+ curwin->w_llist_ref = qi;
+ qi->qf_refcount++;
}
if (oldwin != curwin) {
@@ -3631,6 +3690,8 @@ static int qf_open_new_cwindow(qf_info_T *qi, int height)
if (do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE + ECMD_NOWINENTER, oldwin) == FAIL) {
return FAIL;
}
+ // save the number of the new buffer
+ qi->qf_bufnr = curbuf->b_fnum;
}
// Set the options for the quickfix buffer/window (if not already done)
@@ -3677,7 +3738,6 @@ void ex_copen(exarg_T *eap)
incr_quickfix_busy();
if (eap->addr_count != 0) {
- assert(eap->line2 <= INT_MAX);
height = (int)eap->line2;
} else {
height = QF_WINHEIGHT;
@@ -3685,9 +3745,9 @@ void ex_copen(exarg_T *eap)
reset_VIsual_and_resel(); // stop Visual mode
// Find an existing quickfix window, or open a new one.
- if (cmdmod.tab == 0) {
+ if (cmdmod.cmod_tab == 0) {
status = qf_goto_cwindow(qi, eap->addr_count != 0, height,
- cmdmod.split & WSP_VERT);
+ cmdmod.cmod_split & WSP_VERT);
}
if (status == FAIL) {
if (qf_open_new_cwindow(qi, height) == FAIL) {
@@ -3809,8 +3869,8 @@ static int is_qf_win(const win_T *win, const qf_info_T *qi)
return false;
}
-/// Find a window displaying the quickfix/location stack 'qi'
-/// Only searches in the current tabpage.
+/// Find a window displaying the quickfix/location stack 'qi' in the current tab
+/// page.
static win_T *qf_find_win(const qf_info_T *qi)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -3823,11 +3883,20 @@ static win_T *qf_find_win(const qf_info_T *qi)
return NULL;
}
-// Find a quickfix buffer.
-// Searches in windows opened in all the tabs.
+/// Find a quickfix buffer.
+/// Searches in windows opened in all the tab pages.
static buf_T *qf_find_buf(qf_info_T *qi)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
+ if (qi->qf_bufnr != INVALID_QFBUFNR) {
+ buf_T *const qfbuf = buflist_findnr(qi->qf_bufnr);
+ if (qfbuf != NULL) {
+ return qfbuf;
+ }
+ // buffer is no longer present
+ qi->qf_bufnr = INVALID_QFBUFNR;
+ }
+
FOR_ALL_TAB_WINDOWS(tp, win) {
if (is_qf_win(win, qi)) {
return win->w_buffer;
@@ -3850,7 +3919,7 @@ bool qf_process_qftf_option(void)
if (*p_qftf == '{') {
// Lambda expression
- tv = eval_expr(p_qftf);
+ tv = eval_expr((char *)p_qftf);
if (tv == NULL) {
return false;
}
@@ -3858,7 +3927,7 @@ bool qf_process_qftf_option(void)
// treat everything else as a function name string
tv = xcalloc(1, sizeof(*tv));
tv->v_type = VAR_STRING;
- tv->vval.v_string = vim_strsave(p_qftf);
+ tv->vval.v_string = (char *)vim_strsave(p_qftf);
}
if (!callback_from_typval(&cb, tv)) {
@@ -3941,7 +4010,7 @@ static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last)
// Add an error line to the quickfix buffer.
static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum, const qfline_T *qfp,
- char_u *dirname, char_u *qftf_str, bool first_bufline)
+ char *dirname, char *qftf_str, bool first_bufline)
FUNC_ATTR_NONNULL_ARG(1, 2, 4, 5)
{
int len;
@@ -3966,11 +4035,11 @@ static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum, const qfli
// buffer.
if (first_bufline
&& (errbuf->b_sfname == NULL
- || path_is_absolute(errbuf->b_sfname))) {
+ || path_is_absolute((char_u *)errbuf->b_sfname))) {
if (*dirname == NUL) {
- os_dirname(dirname, MAXPATHL);
+ os_dirname((char_u *)dirname, MAXPATHL);
}
- shorten_buf_fname(errbuf, dirname, false);
+ shorten_buf_fname(errbuf, (char_u *)dirname, false);
}
STRLCPY(IObuff, errbuf->b_fname, IOSIZE);
}
@@ -3982,14 +4051,14 @@ static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum, const qfli
IObuff[len++] = '|';
}
if (qfp->qf_lnum > 0) {
- qf_range_text(qfp, IObuff + len, IOSIZE - len);
+ qf_range_text(qfp, (char *)IObuff + len, IOSIZE - len);
len += (int)STRLEN(IObuff + len);
- snprintf((char *)IObuff + len, (size_t)(IOSIZE - len), "%s",
- (char *)qf_types(qfp->qf_type, qfp->qf_nr));
+ snprintf((char *)IObuff + len, (size_t)(IOSIZE - len), "%s", qf_types(qfp->qf_type,
+ qfp->qf_nr));
len += (int)STRLEN(IObuff + len);
} else if (qfp->qf_pattern != NULL) {
- qf_fmt_text(qfp->qf_pattern, IObuff + len, IOSIZE - len);
+ qf_fmt_text(qfp->qf_pattern, (char *)IObuff + len, IOSIZE - len);
len += (int)STRLEN(IObuff + len);
}
if (len < IOSIZE - 2) {
@@ -4001,7 +4070,7 @@ static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum, const qfli
// For an unrecognized line keep the indent, the compiler may
// mark a word with ^^^^.
qf_fmt_text(len > 3 ? skipwhite(qfp->qf_text) : qfp->qf_text,
- IObuff + len, IOSIZE - len);
+ (char *)IObuff + len, IOSIZE - len);
}
if (ml_append_buf(buf, lnum, IObuff,
@@ -4021,10 +4090,10 @@ static list_T *call_qftf_func(qf_list_T *qfl, int qf_winid, long start_idx, long
// If 'quickfixtextfunc' is set, then use the user-supplied function to get
// the text to display. Use the local value of 'quickfixtextfunc' if it is
// set.
- if (qfl->qftf_cb.type != kCallbackNone) {
- cb = &qfl->qftf_cb;
+ if (qfl->qf_qftf_cb.type != kCallbackNone) {
+ cb = &qfl->qf_qftf_cb;
}
- if (cb != NULL && cb->type != kCallbackNone) {
+ if (cb->type != kCallbackNone) {
typval_T args[1];
typval_T rettv;
@@ -4083,7 +4152,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int q
// Check if there is anything to display
if (qfl != NULL) {
- char_u dirname[MAXPATHL];
+ char dirname[MAXPATHL];
int prev_bufnr = -1;
bool invalid_val = false;
@@ -4106,13 +4175,13 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int q
qftf_li = tv_list_first(qftf_list);
while (lnum < qfl->qf_count) {
- char_u *qftf_str = NULL;
+ char *qftf_str = NULL;
// Use the text supplied by the user defined function (if any).
// If the returned value is not string, then ignore the rest
// of the returned values and use the default.
if (qftf_li != NULL && !invalid_val) {
- qftf_str = (char_u *)tv_get_string_chk(TV_LIST_ITEM_TV(qftf_li));
+ qftf_str = (char *)tv_get_string_chk(TV_LIST_ITEM_TV(qftf_li));
if (qftf_str == NULL) {
invalid_val = true;
}
@@ -4151,10 +4220,8 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int q
curbuf->b_p_ma = false;
keep_filetype = true; // don't detect 'filetype'
- apply_autocmds(EVENT_BUFREADPOST, (char_u *)"quickfix", NULL,
- false, curbuf);
- apply_autocmds(EVENT_BUFWINENTER, (char_u *)"quickfix", NULL,
- false, curbuf);
+ apply_autocmds(EVENT_BUFREADPOST, "quickfix", NULL, false, curbuf);
+ apply_autocmds(EVENT_BUFWINENTER, "quickfix", NULL, false, curbuf);
keep_filetype = false;
curbuf->b_ro_locked--;
@@ -4228,22 +4295,22 @@ int grep_internal(cmdidx_T cmdidx)
}
// Return the make/grep autocmd name.
-static char_u *make_get_auname(cmdidx_T cmdidx)
+static char *make_get_auname(cmdidx_T cmdidx)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (cmdidx) {
case CMD_make:
- return (char_u *)"make";
+ return "make";
case CMD_lmake:
- return (char_u *)"lmake";
+ return "lmake";
case CMD_grep:
- return (char_u *)"grep";
+ return "grep";
case CMD_lgrep:
- return (char_u *)"lgrep";
+ return "lgrep";
case CMD_grepadd:
- return (char_u *)"grepadd";
+ return "grepadd";
case CMD_lgrepadd:
- return (char_u *)"lgrepadd";
+ return "lgrepadd";
default:
return NULL;
}
@@ -4251,7 +4318,7 @@ static char_u *make_get_auname(cmdidx_T cmdidx)
// Form the complete command line to invoke 'make'/'grep'. Quote the command
// using 'shellquote' and append 'shellpipe'. Echo the fully formed command.
-static char *make_get_fullcmd(const char_u *makecmd, const char_u *fname)
+static char *make_get_fullcmd(const char *makecmd, const char *fname)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
{
size_t len = STRLEN(p_shq) * 2 + STRLEN(makecmd) + 1;
@@ -4274,7 +4341,7 @@ static char *make_get_fullcmd(const char_u *makecmd, const char_u *fname)
}
msg_start();
msg_puts(":!");
- msg_outtrans((char_u *)cmd); // show what we are doing
+ msg_outtrans(cmd); // show what we are doing
return cmd;
}
@@ -4282,11 +4349,11 @@ static char *make_get_fullcmd(const char_u *makecmd, const char_u *fname)
// Used for ":make", ":lmake", ":grep", ":lgrep", ":grepadd", and ":lgrepadd"
void ex_make(exarg_T *eap)
{
- char_u *fname;
+ char *fname;
win_T *wp = NULL;
qf_info_T *qi = &ql_info;
int res;
- char_u *enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc;
+ char *enc = (*curbuf->b_p_menc != NUL) ? (char *)curbuf->b_p_menc : (char *)p_menc;
// Redirect ":grep" to ":vimgrep" if 'grepprg' is "internal".
if (grep_internal(eap->cmdidx)) {
@@ -4294,7 +4361,7 @@ void ex_make(exarg_T *eap)
return;
}
- char_u *const au_name = make_get_auname(eap->cmdidx);
+ char *const au_name = make_get_auname(eap->cmdidx);
if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
curbuf->b_fname, true, curbuf)) {
if (aborting()) {
@@ -4311,11 +4378,11 @@ void ex_make(exarg_T *eap)
if (fname == NULL) {
return;
}
- os_remove((char *)fname); // in case it's not unique
+ os_remove(fname); // in case it's not unique
char *const cmd = make_get_fullcmd(eap->arg, fname);
- do_shell((char_u *)cmd, 0);
+ do_shell(cmd, 0);
incr_quickfix_busy();
@@ -4346,7 +4413,7 @@ void ex_make(exarg_T *eap)
cleanup:
decr_quickfix_busy();
- os_remove((char *)fname);
+ os_remove(fname);
xfree(fname);
xfree(cmd);
}
@@ -4354,15 +4421,15 @@ cleanup:
// Return the name for the errorfile, in allocated memory.
// Find a new unique name when 'makeef' contains "##".
// Returns NULL for error.
-static char_u *get_mef_name(void)
+static char *get_mef_name(void)
{
- char_u *p;
- char_u *name;
+ char *p;
+ char *name;
static int start = -1;
static int off = 0;
if (*p_mef == NUL) {
- name = vim_tempname();
+ name = (char *)vim_tempname();
if (name == NULL) {
emsg(_(e_notmp));
}
@@ -4376,7 +4443,7 @@ static char_u *get_mef_name(void)
}
if (*p == NUL) {
- return vim_strsave(p_mef);
+ return xstrdup(p_mef);
}
// Keep trying until the name doesn't exist yet.
@@ -4388,11 +4455,11 @@ static char_u *get_mef_name(void)
}
name = xmalloc(STRLEN(p_mef) + 30);
STRCPY(name, p_mef);
- sprintf((char *)name + (p - p_mef), "%d%d", start, off);
+ snprintf(name + (p - p_mef), STRLEN(name), "%d%d", start, off);
STRCAT(name, p + 2);
// Don't accept a symbolic link, it's a security risk.
FileInfo file_info;
- bool file_or_link_found = os_fileinfo_link((char *)name, &file_info);
+ bool file_or_link_found = os_fileinfo_link(name, &file_info);
if (!file_or_link_found) {
break;
}
@@ -4849,11 +4916,12 @@ static qfline_T *qf_find_closest_entry(qf_list_T *qfl, int bnr, const pos_T *pos
/// Get the nth quickfix entry below the specified entry. Searches forward in
/// the list. If linewise is true, then treat multiple entries on a single line
/// as one.
-static void qf_get_nth_below_entry(qfline_T *entry, linenr_T n, bool linewise, int *errornr)
+static void qf_get_nth_below_entry(qfline_T *entry_arg, linenr_T n, bool linewise, int *errornr)
FUNC_ATTR_NONNULL_ALL
{
+ qfline_T *entry = entry_arg;
+
while (n-- > 0 && !got_int) {
- // qfline_T *first_entry = entry;
int first_errornr = *errornr;
if (linewise) {
@@ -4864,9 +4932,6 @@ static void qf_get_nth_below_entry(qfline_T *entry, linenr_T n, bool linewise, i
if (entry->qf_next == NULL
|| entry->qf_next->qf_fnum != entry->qf_fnum) {
if (linewise) {
- // If multiple entries are on the same line, then use the first
- // entry
- // entry = first_entry;
*errornr = first_errornr;
}
break;
@@ -4996,36 +5061,34 @@ void ex_cbelow(exarg_T *eap)
}
}
-
/// Return the autocmd name for the :cfile Ex commands
-static char_u *cfile_get_auname(cmdidx_T cmdidx)
+static char *cfile_get_auname(cmdidx_T cmdidx)
{
switch (cmdidx) {
case CMD_cfile:
- return (char_u *)"cfile";
+ return "cfile";
case CMD_cgetfile:
- return (char_u *)"cgetfile";
+ return "cgetfile";
case CMD_caddfile:
- return (char_u *)"caddfile";
+ return "caddfile";
case CMD_lfile:
- return (char_u *)"lfile";
+ return "lfile";
case CMD_lgetfile:
- return (char_u *)"lgetfile";
+ return "lgetfile";
case CMD_laddfile:
- return (char_u *)"laddfile";
+ return "laddfile";
default:
return NULL;
}
}
-
// ":cfile"/":cgetfile"/":caddfile" commands.
// ":lfile"/":lgetfile"/":laddfile" commands.
void ex_cfile(exarg_T *eap)
{
win_T *wp = NULL;
qf_info_T *qi = &ql_info;
- char_u *au_name = NULL;
+ char *au_name = NULL;
au_name = cfile_get_auname(eap->cmdidx);
if (au_name != NULL
@@ -5038,7 +5101,7 @@ void ex_cfile(exarg_T *eap)
set_string_option_direct("ef", -1, eap->arg, OPT_FREE, 0);
}
- char_u *enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc;
+ char *enc = (*curbuf->b_p_menc != NUL) ? (char *)curbuf->b_p_menc : (char *)p_menc;
if (is_loclist_cmd(eap->cmdidx)) {
wp = curwin;
@@ -5054,8 +5117,8 @@ void ex_cfile(exarg_T *eap)
// first error.
// :caddfile adds to an existing quickfix list. If there is no
// quickfix list then a new list is created.
- int res = qf_init(wp, p_ef, p_efm, (eap->cmdidx != CMD_caddfile
- && eap->cmdidx != CMD_laddfile),
+ int res = qf_init(wp, (char *)p_ef, p_efm, (eap->cmdidx != CMD_caddfile
+ && eap->cmdidx != CMD_laddfile),
qf_cmdtitle(*eap->cmdlinep), enc);
if (wp != NULL) {
qi = GET_LOC_LIST(wp);
@@ -5083,32 +5146,32 @@ void ex_cfile(exarg_T *eap)
}
/// Return the vimgrep autocmd name.
-static char_u *vgr_get_auname(cmdidx_T cmdidx)
+static char *vgr_get_auname(cmdidx_T cmdidx)
{
switch (cmdidx) {
case CMD_vimgrep:
- return (char_u *)"vimgrep";
+ return "vimgrep";
case CMD_lvimgrep:
- return (char_u *)"lvimgrep";
+ return "lvimgrep";
case CMD_vimgrepadd:
- return (char_u *)"vimgrepadd";
+ return "vimgrepadd";
case CMD_lvimgrepadd:
- return (char_u *)"lvimgrepadd";
+ return "lvimgrepadd";
case CMD_grep:
- return (char_u *)"grep";
+ return "grep";
case CMD_lgrep:
- return (char_u *)"lgrep";
+ return "lgrep";
case CMD_grepadd:
- return (char_u *)"grepadd";
+ return "grepadd";
case CMD_lgrepadd:
- return (char_u *)"lgrepadd";
+ return "lgrepadd";
default:
return NULL;
}
}
/// Initialize the regmatch used by vimgrep for pattern "s".
-static void vgr_init_regmatch(regmmatch_T *regmatch, char_u *s)
+static void vgr_init_regmatch(regmmatch_T *regmatch, char *s)
{
// Get the search pattern: either white-separated or enclosed in //.
regmatch->regprog = NULL;
@@ -5119,7 +5182,7 @@ static void vgr_init_regmatch(regmmatch_T *regmatch, char_u *s)
emsg(_(e_noprevre));
return;
}
- regmatch->regprog = vim_regcomp(last_search_pat(), RE_MAGIC);
+ regmatch->regprog = vim_regcomp((char *)last_search_pat(), RE_MAGIC);
} else {
regmatch->regprog = vim_regcomp(s, RE_MAGIC);
}
@@ -5128,12 +5191,11 @@ static void vgr_init_regmatch(regmmatch_T *regmatch, char_u *s)
regmatch->rmm_maxcol = 0;
}
-
/// Display a file name when vimgrep is running.
-static void vgr_display_fname(char_u *fname)
+static void vgr_display_fname(char *fname)
{
msg_start();
- char_u *p = msg_strtrunc(fname, true);
+ char *p = (char *)msg_strtrunc((char_u *)fname, true);
if (p == NULL) {
msg_outtrans(fname);
} else {
@@ -5148,11 +5210,11 @@ static void vgr_display_fname(char_u *fname)
}
/// Load a dummy buffer to search for a pattern using vimgrep.
-static buf_T *vgr_load_dummy_buf(char_u *fname, char_u *dirname_start, char_u *dirname_now)
+static buf_T *vgr_load_dummy_buf(char *fname, char *dirname_start, char *dirname_now)
{
// Don't do Filetype autocommands to avoid loading syntax and
// indent scripts, a great speed improvement.
- char_u *save_ei = au_event_disable(",Filetype");
+ char *save_ei = au_event_disable(",Filetype");
long save_mls = p_mls;
p_mls = 0;
@@ -5170,7 +5232,7 @@ static buf_T *vgr_load_dummy_buf(char_u *fname, char_u *dirname_start, char_u *d
/// Check whether a quickfix/location list is valid. Autocmds may remove or
/// change a quickfix list when vimgrep is running. If the list is not found,
/// create a new list.
-static bool vgr_qflist_valid(win_T *wp, qf_info_T *qi, unsigned qfid, char_u *title)
+static bool vgr_qflist_valid(win_T *wp, qf_info_T *qi, unsigned qfid, char *title)
{
// Verify that the quickfix/location list was not freed by an autocmd
if (!qflist_valid(wp, qfid)) {
@@ -5191,52 +5253,96 @@ static bool vgr_qflist_valid(win_T *wp, qf_info_T *qi, unsigned qfid, char_u *ti
return true;
}
-
/// Search for a pattern in all the lines in a buffer and add the matching lines
/// to a quickfix list.
-static bool vgr_match_buflines(qf_list_T *qfl, char_u *fname, buf_T *buf, regmmatch_T *regmatch,
- long *tomatch, int duplicate_name, int flags)
- FUNC_ATTR_NONNULL_ARG(1, 3, 4, 5)
+static bool vgr_match_buflines(qf_list_T *qfl, char *fname, buf_T *buf, char *spat,
+ regmmatch_T *regmatch, long *tomatch, int duplicate_name, int flags)
+ FUNC_ATTR_NONNULL_ARG(1, 3, 4, 5, 6)
{
bool found_match = false;
- for (long lnum = 1; lnum <= buf->b_ml.ml_line_count && *tomatch > 0; lnum++) {
+ for (linenr_T lnum = 1; lnum <= buf->b_ml.ml_line_count && *tomatch > 0; lnum++) {
colnr_T col = 0;
- while (vim_regexec_multi(regmatch, curwin, buf, lnum, col, NULL,
- NULL) > 0) {
- // Pass the buffer number so that it gets used even for a
- // dummy buffer, unless duplicate_name is set, then the
- // buffer will be wiped out below.
- if (qf_add_entry(qfl,
- NULL, // dir
- fname,
- NULL,
- duplicate_name ? 0 : buf->b_fnum,
- ml_get_buf(buf, regmatch->startpos[0].lnum + lnum,
- false),
- regmatch->startpos[0].lnum + lnum,
- regmatch->endpos[0].lnum + lnum,
- regmatch->startpos[0].col + 1,
- regmatch->endpos[0].col + 1,
- false, // vis_col
- NULL, // search pattern
- 0, // nr
- 0, // type
- true) // valid
- == QF_FAIL) {
- got_int = true;
- break;
- }
- found_match = true;
- if (--*tomatch == 0) {
- break;
- }
- if ((flags & VGR_GLOBAL) == 0 || regmatch->endpos[0].lnum > 0) {
- break;
+ if (!(flags & VGR_FUZZY)) {
+ // Regular expression match
+ while (vim_regexec_multi(regmatch, curwin, buf, lnum, col, NULL, NULL) > 0) {
+ // Pass the buffer number so that it gets used even for a
+ // dummy buffer, unless duplicate_name is set, then the
+ // buffer will be wiped out below.
+ if (qf_add_entry(qfl,
+ NULL, // dir
+ fname,
+ NULL,
+ duplicate_name ? 0 : buf->b_fnum,
+ (char *)ml_get_buf(buf, regmatch->startpos[0].lnum + lnum, false),
+ regmatch->startpos[0].lnum + lnum,
+ regmatch->endpos[0].lnum + lnum,
+ regmatch->startpos[0].col + 1,
+ regmatch->endpos[0].col + 1,
+ false, // vis_col
+ NULL, // search pattern
+ 0, // nr
+ 0, // type
+ true) // valid
+ == QF_FAIL) {
+ got_int = true;
+ break;
+ }
+ found_match = true;
+ if (--*tomatch == 0) {
+ break;
+ }
+ if ((flags & VGR_GLOBAL) == 0 || regmatch->endpos[0].lnum > 0) {
+ break;
+ }
+ col = regmatch->endpos[0].col + (col == regmatch->endpos[0].col);
+ if (col > (colnr_T)STRLEN(ml_get_buf(buf, lnum, false))) {
+ break;
+ }
}
- col = regmatch->endpos[0].col + (col == regmatch->endpos[0].col);
- if (col > (colnr_T)STRLEN(ml_get_buf(buf, lnum, false))) {
- break;
+ } else {
+ const size_t pat_len = STRLEN(spat);
+ char *const str = (char *)ml_get_buf(buf, lnum, false);
+ int score;
+ uint32_t matches[MAX_FUZZY_MATCHES];
+ const size_t sz = sizeof(matches) / sizeof(matches[0]);
+
+ // Fuzzy string match
+ while (fuzzy_match((char_u *)str + col, (char_u *)spat, false, &score, matches,
+ (int)sz) > 0) {
+ // Pass the buffer number so that it gets used even for a
+ // dummy buffer, unless duplicate_name is set, then the
+ // buffer will be wiped out below.
+ if (qf_add_entry(qfl,
+ NULL, // dir
+ fname,
+ NULL,
+ duplicate_name ? 0 : buf->b_fnum,
+ str,
+ lnum,
+ 0,
+ (colnr_T)matches[0] + col + 1,
+ 0,
+ false, // vis_col
+ NULL, // search pattern
+ 0, // nr
+ 0, // type
+ true) // valid
+ == QF_FAIL) {
+ got_int = true;
+ break;
+ }
+ found_match = true;
+ if (--*tomatch == 0) {
+ break;
+ }
+ if ((flags & VGR_GLOBAL) == 0) {
+ break;
+ }
+ col = (colnr_T)matches[pat_len - 1] + col + 1;
+ if (col > (colnr_T)STRLEN(str)) {
+ break;
+ }
}
}
line_breakcheck();
@@ -5249,8 +5355,8 @@ static bool vgr_match_buflines(qf_list_T *qfl, char_u *fname, buf_T *buf, regmma
}
/// Jump to the first match and update the directory.
-static void vgr_jump_to_match(qf_info_T *qi, int forceit, int *redraw_for_dummy,
- buf_T *first_match_buf, char_u *target_dir)
+static void vgr_jump_to_match(qf_info_T *qi, int forceit, bool *redraw_for_dummy,
+ buf_T *first_match_buf, char *target_dir)
{
buf_T *buf = curbuf;
qf_jump(qi, 0, 0, forceit);
@@ -5276,7 +5382,7 @@ static bool existing_swapfile(const buf_T *buf)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (buf->b_ml.ml_mfp != NULL && buf->b_ml.ml_mfp->mf_fname != NULL) {
- const char_u *const fname = buf->b_ml.ml_mfp->mf_fname;
+ const char *const fname = (char *)buf->b_ml.ml_mfp->mf_fname;
const size_t len = STRLEN(fname);
return fname[len - 1] != 'p' || fname[len - 2] != 'w';
@@ -5284,104 +5390,71 @@ static bool existing_swapfile(const buf_T *buf)
return false;
}
-// ":vimgrep {pattern} file(s)"
-// ":vimgrepadd {pattern} file(s)"
-// ":lvimgrep {pattern} file(s)"
-// ":lvimgrepadd {pattern} file(s)"
-void ex_vimgrep(exarg_T *eap)
+/// Process :vimgrep command arguments. The command syntax is:
+///
+/// :{count}vimgrep /{pattern}/[g][j] {file} ...
+static int vgr_process_args(exarg_T *eap, vgr_args_T *args)
{
- regmmatch_T regmatch;
- int fcount;
- char_u **fnames;
- char_u *fname;
- char_u *s;
- char_u *p;
- int fi;
- qf_list_T *qfl;
- win_T *wp = NULL;
- buf_T *buf;
- int duplicate_name = FALSE;
- int using_dummy;
- int redraw_for_dummy = FALSE;
- int found_match;
- buf_T *first_match_buf = NULL;
- time_t seconds = 0;
- aco_save_T aco;
- int flags = 0;
- long tomatch;
- char_u *dirname_start = NULL;
- char_u *dirname_now = NULL;
- char_u *target_dir = NULL;
- char_u *au_name = NULL;
-
- au_name = vgr_get_auname(eap->cmdidx);
- if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
- curbuf->b_fname, true, curbuf)) {
- if (aborting()) {
- return;
- }
- }
+ memset(args, 0, sizeof(*args));
- qf_info_T *qi = qf_cmd_get_or_alloc_stack(eap, &wp);
+ args->regmatch.regprog = NULL;
+ args->qf_title = xstrdup(qf_cmdtitle(*eap->cmdlinep));
if (eap->addr_count > 0) {
- tomatch = eap->line2;
+ args->tomatch = eap->line2;
} else {
- tomatch = MAXLNUM;
+ args->tomatch = MAXLNUM;
}
// Get the search pattern: either white-separated or enclosed in //
- regmatch.regprog = NULL;
- char_u *title = vim_strsave(qf_cmdtitle(*eap->cmdlinep));
- p = skip_vimgrep_pat(eap->arg, &s, &flags);
+ char *p = skip_vimgrep_pat(eap->arg, &args->spat, &args->flags);
if (p == NULL) {
emsg(_(e_invalpat));
- goto theend;
+ return FAIL;
}
- vgr_init_regmatch(&regmatch, s);
- if (regmatch.regprog == NULL) {
- goto theend;
+ vgr_init_regmatch(&args->regmatch, args->spat);
+ if (args->regmatch.regprog == NULL) {
+ return FAIL;
}
p = skipwhite(p);
if (*p == NUL) {
emsg(_("E683: File name missing or invalid pattern"));
- goto theend;
- }
-
- if ((eap->cmdidx != CMD_grepadd && eap->cmdidx != CMD_lgrepadd
- && eap->cmdidx != CMD_vimgrepadd && eap->cmdidx != CMD_lvimgrepadd)
- || qf_stack_empty(qi)) {
- // make place for a new list
- qf_new_list(qi, title);
+ return FAIL;
}
// Parse the list of arguments, wildcards have already been expanded.
- if (get_arglist_exp(p, &fcount, &fnames, true) == FAIL) {
- goto theend;
+ if (get_arglist_exp((char_u *)p, &args->fcount, (char_u ***)&args->fnames, true) == FAIL) {
+ return FAIL;
}
- if (fcount == 0) {
+ if (args->fcount == 0) {
emsg(_(e_nomatch));
- goto theend;
+ return FAIL;
}
- dirname_start = xmalloc(MAXPATHL);
- dirname_now = xmalloc(MAXPATHL);
+ return OK;
+}
- // Remember the current directory, because a BufRead autocommand that does
- // ":lcd %:p:h" changes the meaning of short path names.
- os_dirname(dirname_start, MAXPATHL);
+/// Search for a pattern in a list of files and populate the quickfix list with
+/// the matches.
+static int vgr_process_files(win_T *wp, qf_info_T *qi, vgr_args_T *cmd_args, bool *redraw_for_dummy,
+ buf_T **first_match_buf, char **target_dir)
+{
+ int status = FAIL;
+ unsigned save_qfid = qf_get_curlist(qi)->qf_id;
+ bool duplicate_name = false;
- incr_quickfix_busy();
+ char *dirname_start = xmalloc(MAXPATHL);
+ char *dirname_now = xmalloc(MAXPATHL);
- // Remember the current quickfix list identifier, so that we can check for
- // autocommands changing the current quickfix list.
- unsigned save_qfid = qf_get_curlist(qi)->qf_id;
+ // Remember the current directory, because a BufRead autocommand that does
+ // ":lcd %:p:h" changes the meaning of short path names.
+ os_dirname((char_u *)dirname_start, MAXPATHL);
- seconds = (time_t)0;
- for (fi = 0; fi < fcount && !got_int && tomatch > 0; fi++) {
- fname = path_try_shorten_fname(fnames[fi]);
+ time_t seconds = (time_t)0;
+ for (int fi = 0; fi < cmd_args->fcount && !got_int && cmd_args->tomatch > 0; fi++) {
+ char *fname = (char *)path_try_shorten_fname((char_u *)cmd_args->fnames[fi]);
if (time(NULL) > seconds) {
// Display the file name every second or so, show the user we are
// working on it.
@@ -5389,13 +5462,13 @@ void ex_vimgrep(exarg_T *eap)
vgr_display_fname(fname);
}
- buf = buflist_findname_exp(fnames[fi]);
+ buf_T *buf = buflist_findname_exp(cmd_args->fnames[fi]);
+ bool using_dummy;
if (buf == NULL || buf->b_ml.ml_mfp == NULL) {
// Remember that a buffer with this name already exists.
duplicate_name = (buf != NULL);
- using_dummy = TRUE;
- redraw_for_dummy = TRUE;
-
+ using_dummy = true;
+ *redraw_for_dummy = true;
buf = vgr_load_dummy_buf(fname, dirname_start, dirname_now);
} else {
// Use existing, loaded buffer.
@@ -5404,11 +5477,10 @@ void ex_vimgrep(exarg_T *eap)
// Check whether the quickfix list is still valid. When loading a
// buffer above, autocommands might have changed the quickfix list.
- if (!vgr_qflist_valid(wp, qi, save_qfid, *eap->cmdlinep)) {
- FreeWild(fcount, fnames);
- decr_quickfix_busy();
+ if (!vgr_qflist_valid(wp, qi, save_qfid, cmd_args->qf_title)) {
goto theend;
}
+
save_qfid = qf_get_curlist(qi)->qf_id;
if (buf == NULL) {
@@ -5418,20 +5490,25 @@ void ex_vimgrep(exarg_T *eap)
} else {
// Try for a match in all lines of the buffer.
// For ":1vimgrep" look for first match only.
- found_match = vgr_match_buflines(qf_get_curlist(qi),
- fname, buf, &regmatch, &tomatch,
- duplicate_name, flags);
+ bool found_match = vgr_match_buflines(qf_get_curlist(qi),
+ fname,
+ buf,
+ cmd_args->spat,
+ &cmd_args->regmatch,
+ &cmd_args->tomatch,
+ duplicate_name,
+ cmd_args->flags);
if (using_dummy) {
- if (found_match && first_match_buf == NULL) {
- first_match_buf = buf;
+ if (found_match && *first_match_buf == NULL) {
+ *first_match_buf = buf;
}
if (duplicate_name) {
// Never keep a dummy buffer if there is another buffer
// with the same name.
wipe_dummy_buffer(buf, dirname_start);
buf = NULL;
- } else if (!cmdmod.hide
+ } else if ((cmdmod.cmod_flags & CMOD_HIDE) == 0
|| buf->b_p_bh[0] == 'u' // "unload"
|| buf->b_p_bh[0] == 'w' // "wipe"
|| buf->b_p_bh[0] == 'd') { // "delete"
@@ -5444,8 +5521,8 @@ void ex_vimgrep(exarg_T *eap)
if (!found_match) {
wipe_dummy_buffer(buf, dirname_start);
buf = NULL;
- } else if (buf != first_match_buf
- || (flags & VGR_NOJUMP)
+ } else if (buf != *first_match_buf
+ || (cmd_args->flags & VGR_NOJUMP)
|| existing_swapfile(buf)) {
unload_dummy_buffer(buf, dirname_start);
// Keeping the buffer, remove the dummy flag.
@@ -5460,18 +5537,19 @@ void ex_vimgrep(exarg_T *eap)
// If the buffer is still loaded we need to use the
// directory we jumped to below.
- if (buf == first_match_buf
- && target_dir == NULL
+ if (buf == *first_match_buf
+ && *target_dir == NULL
&& STRCMP(dirname_start, dirname_now) != 0) {
- target_dir = vim_strsave(dirname_now);
+ *target_dir = xstrdup(dirname_now);
}
// The buffer is still loaded, the Filetype autocommands
// need to be done now, in that buffer. And the modelines
// need to be done (again). But not the window-local
// options!
+ aco_save_T aco;
aucmd_prepbuf(&aco, buf);
- apply_autocmds(EVENT_FILETYPE, buf->b_p_ft, buf->b_fname, true, buf);
+ apply_autocmds(EVENT_FILETYPE, (char *)buf->b_p_ft, buf->b_fname, true, buf);
do_modelines(OPT_NOWIN);
aucmd_restbuf(&aco);
}
@@ -5479,9 +5557,58 @@ void ex_vimgrep(exarg_T *eap)
}
}
- FreeWild(fcount, fnames);
+ status = OK;
- qfl = qf_get_curlist(qi);
+theend:
+ xfree(dirname_now);
+ xfree(dirname_start);
+ return status;
+}
+
+/// ":vimgrep {pattern} file(s)"
+/// ":vimgrepadd {pattern} file(s)"
+/// ":lvimgrep {pattern} file(s)"
+/// ":lvimgrepadd {pattern} file(s)"
+void ex_vimgrep(exarg_T *eap)
+{
+ char *au_name = vgr_get_auname(eap->cmdidx);
+ if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
+ curbuf->b_fname, true, curbuf)) {
+ if (aborting()) {
+ return;
+ }
+ }
+
+ win_T *wp = NULL;
+ qf_info_T *qi = qf_cmd_get_or_alloc_stack(eap, &wp);
+ char *target_dir = NULL;
+ vgr_args_T args;
+ if (vgr_process_args(eap, &args) == FAIL) {
+ goto theend;
+ }
+
+ if ((eap->cmdidx != CMD_grepadd && eap->cmdidx != CMD_lgrepadd
+ && eap->cmdidx != CMD_vimgrepadd && eap->cmdidx != CMD_lvimgrepadd)
+ || qf_stack_empty(qi)) {
+ // make place for a new list
+ qf_new_list(qi, args.qf_title);
+ }
+
+ incr_quickfix_busy();
+
+ bool redraw_for_dummy = false;
+ buf_T *first_match_buf = NULL;
+ int status = vgr_process_files(wp, qi, &args, &redraw_for_dummy, &first_match_buf, &target_dir);
+
+ if (status != OK) {
+ FreeWild(args.fcount, (char_u **)args.fnames);
+ decr_quickfix_busy();
+ goto theend;
+ }
+
+ FreeWild(args.fcount, (char_u **)args.fnames);
+
+ qf_list_T *qfl = qf_get_curlist(qi);
qfl->qf_nonevalid = false;
qfl->qf_ptr = qfl->qf_start;
qfl->qf_index = 1;
@@ -5489,26 +5616,28 @@ void ex_vimgrep(exarg_T *eap)
qf_update_buffer(qi, NULL);
+ // Remember the current quickfix list identifier, so that we can check for
+ // autocommands changing the current quickfix list.
+ unsigned save_qfid = qf_get_curlist(qi)->qf_id;
+
if (au_name != NULL) {
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, curbuf->b_fname, true, curbuf);
}
// The QuickFixCmdPost autocmd may free the quickfix list. Check the list
// is still valid.
- if (!qflist_valid(wp, save_qfid)
- || qf_restore_list(qi, save_qfid) == FAIL) {
+ if (!qflist_valid(wp, save_qfid) || qf_restore_list(qi, save_qfid) == FAIL) {
decr_quickfix_busy();
goto theend;
}
// Jump to first match.
if (!qf_list_empty(qf_get_curlist(qi))) {
- if ((flags & VGR_NOJUMP) == 0) {
- vgr_jump_to_match(qi, eap->forceit, &redraw_for_dummy, first_match_buf,
- target_dir);
+ if ((args.flags & VGR_NOJUMP) == 0) {
+ vgr_jump_to_match(qi, eap->forceit, &redraw_for_dummy, first_match_buf, target_dir);
}
} else {
- semsg(_(e_nomatch2), s);
+ semsg(_(e_nomatch2), args.spat);
}
decr_quickfix_busy();
@@ -5520,21 +5649,19 @@ void ex_vimgrep(exarg_T *eap)
}
theend:
- xfree(title);
- xfree(dirname_now);
- xfree(dirname_start);
+ xfree(args.qf_title);
xfree(target_dir);
- vim_regfree(regmatch.regprog);
+ vim_regfree(args.regmatch.regprog);
}
// Restore current working directory to "dirname_start" if they differ, taking
// into account whether it is set locally or globally.
-static void restore_start_dir(char_u *dirname_start)
+static void restore_start_dir(char *dirname_start)
FUNC_ATTR_NONNULL_ALL
{
- char_u *dirname_now = xmalloc(MAXPATHL);
+ char *dirname_now = xmalloc(MAXPATHL);
- os_dirname(dirname_now, MAXPATHL);
+ os_dirname((char_u *)dirname_now, MAXPATHL);
if (STRCMP(dirname_start, dirname_now) != 0) {
// If the directory has changed, change it back by building up an
// appropriate ex command and executing it.
@@ -5560,7 +5687,7 @@ static void restore_start_dir(char_u *dirname_start)
/// @param resulting_dir out: new directory
///
/// @return NULL if it fails.
-static buf_T *load_dummy_buffer(char_u *fname, char_u *dirname_start, char_u *resulting_dir)
+static buf_T *load_dummy_buffer(char *fname, char *dirname_start, char *resulting_dir)
{
buf_T *newbuf;
bufref_T newbufref;
@@ -5599,7 +5726,7 @@ static buf_T *load_dummy_buffer(char_u *fname, char_u *dirname_start, char_u *re
newbuf_to_wipe.br_buf = NULL;
readfile_result = readfile(fname, NULL, (linenr_T)0, (linenr_T)0,
(linenr_T)MAXLNUM, NULL,
- READ_NEW | READ_DUMMY);
+ READ_NEW | READ_DUMMY, false);
newbuf->b_locked--;
if (readfile_result == OK
&& !got_int
@@ -5629,7 +5756,7 @@ static buf_T *load_dummy_buffer(char_u *fname, char_u *dirname_start, char_u *re
// When autocommands/'autochdir' option changed directory: go back.
// Let the caller know what the resulting dir was first, in case it is
// important.
- os_dirname(resulting_dir, MAXPATHL);
+ os_dirname((char_u *)resulting_dir, MAXPATHL);
restore_start_dir(dirname_start);
if (!bufref_valid(&newbufref)) {
@@ -5645,7 +5772,7 @@ static buf_T *load_dummy_buffer(char_u *fname, char_u *dirname_start, char_u *re
// Wipe out the dummy buffer that load_dummy_buffer() created. Restores
// directory to "dirname_start" prior to returning, if autocmds or the
// 'autochdir' option have changed it.
-static void wipe_dummy_buffer(buf_T *buf, char_u *dirname_start)
+static void wipe_dummy_buffer(buf_T *buf, char *dirname_start)
FUNC_ATTR_NONNULL_ALL
{
// If any autocommand opened a window on the dummy buffer, close that
@@ -5656,7 +5783,7 @@ static void wipe_dummy_buffer(buf_T *buf, char_u *dirname_start)
if (firstwin->w_next != NULL) {
for (win_T *wp = firstwin; wp != NULL; wp = wp->w_next) {
if (wp->w_buffer == buf) {
- if (win_close(wp, false) == OK) {
+ if (win_close(wp, false, false) == OK) {
did_one = true;
}
break;
@@ -5689,10 +5816,10 @@ static void wipe_dummy_buffer(buf_T *buf, char_u *dirname_start)
// Unload the dummy buffer that load_dummy_buffer() created. Restores
// directory to "dirname_start" prior to returning, if autocmds or the
// 'autochdir' option have changed it.
-static void unload_dummy_buffer(buf_T *buf, char_u *dirname_start)
+static void unload_dummy_buffer(buf_T *buf, char *dirname_start)
{
if (curbuf != buf) { // safety check
- close_buffer(NULL, buf, DOBUF_UNLOAD, false);
+ close_buffer(NULL, buf, DOBUF_UNLOAD, false, true);
// When autocommands/'autochdir' option changed directory: go back.
restore_start_dir(dirname_start);
@@ -5703,7 +5830,7 @@ static void unload_dummy_buffer(buf_T *buf, char_u *dirname_start)
/// to 'list'. Returns OK on success.
static int get_qfline_items(qfline_T *qfp, list_T *list)
{
- char_u buf[2];
+ char buf[2];
int bufnum;
// Handle entries with a non-existing buffer number.
@@ -5822,7 +5949,7 @@ enum {
static int qf_get_list_from_lines(dict_T *what, dictitem_T *di, dict_T *retdict)
{
int status = FAIL;
- char_u *errorformat = p_efm;
+ char *errorformat = p_efm;
dictitem_T *efm_di;
// Only a List value is supported
@@ -5869,6 +5996,21 @@ static int qf_winid(qf_info_T *qi)
return 0;
}
+/// Returns the number of the buffer displayed in the quickfix/location list
+/// window. If there is no buffer associated with the list or the buffer is
+/// wiped out, then returns 0.
+static int qf_getprop_qfbufnr(const qf_info_T *qi, dict_T *retdict)
+ FUNC_ATTR_NONNULL_ARG(2)
+{
+ int bufnum = 0;
+
+ if (qi != NULL && buflist_findnr(qi->qf_bufnr) != NULL) {
+ bufnum = qi->qf_bufnr;
+ }
+
+ return tv_dict_add_nr(retdict, S_LEN("qfbufnr"), bufnum);
+}
+
/// Convert the keys in 'what' to quickfix list property flags.
static int qf_getprop_keys2flags(const dict_T *what, bool loclist)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
@@ -5912,6 +6054,9 @@ static int qf_getprop_keys2flags(const dict_T *what, bool loclist)
if (loclist && tv_dict_find(what, S_LEN("filewinid")) != NULL) {
flags |= QF_GETLIST_FILEWINID;
}
+ if (tv_dict_find(what, S_LEN("qfbufnr")) != NULL) {
+ flags |= QF_GETLIST_QFBUFNR;
+ }
if (tv_dict_find(what, S_LEN("quickfixtextfunc")) != NULL) {
flags |= QF_GETLIST_QFTF;
}
@@ -6003,6 +6148,9 @@ static int qf_getprop_defaults(qf_info_T *qi, int flags, int locstack, dict_T *r
if ((status == OK) && locstack && (flags & QF_GETLIST_FILEWINID)) {
status = tv_dict_add_nr(retdict, S_LEN("filewinid"), 0);
}
+ if ((status == OK) && (flags & QF_GETLIST_QFBUFNR)) {
+ status = qf_getprop_qfbufnr(qi, retdict);
+ }
if ((status == OK) && (flags & QF_GETLIST_QFTF)) {
status = tv_dict_add_str(retdict, S_LEN("quickfixtextfunc"), "");
}
@@ -6086,10 +6234,10 @@ static int qf_getprop_qftf(qf_list_T *qfl, dict_T *retdict)
{
int status;
- if (qfl->qftf_cb.type != kCallbackNone) {
+ if (qfl->qf_qftf_cb.type != kCallbackNone) {
typval_T tv;
- callback_put(&qfl->qftf_cb, &tv);
+ callback_put(&qfl->qf_qftf_cb, &tv);
status = tv_dict_add_tv(retdict, S_LEN("quickfixtextfunc"), &tv);
tv_clear(&tv);
} else {
@@ -6172,6 +6320,9 @@ int qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
if ((status == OK) && (wp != NULL) && (flags & QF_GETLIST_FILEWINID)) {
status = qf_getprop_filewinid(wp, qi, retdict);
}
+ if ((status == OK) && (flags & QF_GETLIST_QFBUFNR)) {
+ status = qf_getprop_qfbufnr(qi, retdict);
+ }
if ((status == OK) && (flags & QF_GETLIST_QFTF)) {
status = qf_getprop_qftf(qfl, retdict);
}
@@ -6186,9 +6337,9 @@ static int qf_setprop_qftf(qf_list_T *qfl, dictitem_T *di)
{
Callback cb;
- callback_free(&qfl->qftf_cb);
+ callback_free(&qfl->qf_qftf_cb);
if (callback_from_typval(&cb, &di->di_tv)) {
- qfl->qftf_cb = cb;
+ qfl->qf_qftf_cb = cb;
}
return OK;
}
@@ -6209,11 +6360,11 @@ static int qf_add_entry_from_dict(qf_list_T *qfl, const dict_T *d, bool first_en
char *const filename = tv_dict_get_string(d, "filename", true);
char *const module = tv_dict_get_string(d, "module", true);
int bufnum = (int)tv_dict_get_number(d, "bufnr");
- const long lnum = (long)tv_dict_get_number(d, "lnum");
- const long end_lnum = (long)tv_dict_get_number(d, "end_lnum");
+ const linenr_T lnum = (linenr_T)tv_dict_get_number(d, "lnum");
+ const linenr_T end_lnum = (linenr_T)tv_dict_get_number(d, "end_lnum");
const int col = (int)tv_dict_get_number(d, "col");
const int end_col = (int)tv_dict_get_number(d, "end_col");
- const char_u vcol = (char_u)tv_dict_get_number(d, "vcol");
+ const char vcol = (char)tv_dict_get_number(d, "vcol");
const int nr = (int)tv_dict_get_number(d, "nr");
const char *const type = tv_dict_get_string(d, "type", false);
char *const pattern = tv_dict_get_string(d, "pattern", true);
@@ -6245,18 +6396,18 @@ static int qf_add_entry_from_dict(qf_list_T *qfl, const dict_T *d, bool first_en
const int status = qf_add_entry(qfl,
NULL, // dir
- (char_u *)filename,
- (char_u *)module,
+ filename,
+ module,
bufnum,
- (char_u *)text,
+ text,
lnum,
end_lnum,
col,
end_col,
vcol, // vis_col
- (char_u *)pattern, // search pattern
+ pattern, // search pattern
nr,
- (char_u)(type == NULL ? NUL : *type),
+ type == NULL ? NUL : *type,
valid);
xfree(filename);
@@ -6273,7 +6424,7 @@ static int qf_add_entry_from_dict(qf_list_T *qfl, const dict_T *d, bool first_en
/// Add list of entries to quickfix/location list. Each list entry is
/// a dictionary with item information.
-static int qf_add_entries(qf_info_T *qi, int qf_idx, list_T *list, char_u *title, int action)
+static int qf_add_entries(qf_info_T *qi, int qf_idx, list_T *list, char *title, int action)
{
qf_list_T *qfl = qf_get_list(qi, qf_idx);
qfline_T *old_last = NULL;
@@ -6396,7 +6547,7 @@ static int qf_setprop_title(qf_info_T *qi, int qf_idx, const dict_T *what, const
}
xfree(qfl->qf_title);
- qfl->qf_title = (char_u *)tv_dict_get_string(what, "title", true);
+ qfl->qf_title = tv_dict_get_string(what, "title", true);
if (qf_idx == qi->qf_curlist) {
qf_update_win_titlevar(qi);
}
@@ -6412,9 +6563,8 @@ static int qf_setprop_items(qf_info_T *qi, int qf_idx, dictitem_T *di, int actio
return FAIL;
}
- char_u *title_save = vim_strsave(qi->qf_lists[qf_idx].qf_title);
- const int retval = qf_add_entries(qi, qf_idx, di->di_tv.vval.v_list,
- title_save,
+ char *title_save = xstrdup(qi->qf_lists[qf_idx].qf_title);
+ const int retval = qf_add_entries(qi, qf_idx, di->di_tv.vval.v_list, title_save,
action == ' ' ? 'a' : action);
xfree(title_save);
@@ -6426,7 +6576,7 @@ static int qf_setprop_items_from_lines(qf_info_T *qi, int qf_idx, const dict_T *
dictitem_T *di, int action)
FUNC_ATTR_NONNULL_ALL
{
- char_u *errorformat = p_efm;
+ char *errorformat = p_efm;
dictitem_T *efm_di;
int retval = FAIL;
@@ -6512,7 +6662,7 @@ static int qf_setprop_curidx(qf_info_T *qi, qf_list_T *qfl, const dictitem_T *di
/// Set quickfix/location list properties (title, items, context).
/// Also used to add items from parsing a list of lines.
/// Used by the setqflist() and setloclist() Vim script functions.
-static int qf_set_properties(qf_info_T *qi, const dict_T *what, int action, char_u *title)
+static int qf_set_properties(qf_info_T *qi, const dict_T *what, int action, char *title)
FUNC_ATTR_NONNULL_ALL
{
qf_list_T *qfl;
@@ -6560,20 +6710,6 @@ static int qf_set_properties(qf_info_T *qi, const dict_T *what, int action, char
return retval;
}
-/// Find the non-location list window with the specified location list stack in
-/// the current tabpage.
-static win_T *find_win_with_ll(const qf_info_T *qi)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
-{
- FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
- if ((wp->w_llist == qi) && !bt_quickfix(wp->w_buffer)) {
- return wp;
- }
- }
-
- return NULL;
-}
-
// Free the entire quickfix/location list stack.
// If the quickfix/location list window is open, then clear it.
static void qf_free_stack(win_T *wp, qf_info_T *qi)
@@ -6588,12 +6724,10 @@ static void qf_free_stack(win_T *wp, qf_info_T *qi)
qf_update_buffer(qi, NULL);
}
- win_T *llwin = NULL;
- win_T *orig_wp = wp;
if (wp != NULL && IS_LL_WINDOW(wp)) {
// If in the location list window, then use the non-location list
// window with this location list (if present)
- llwin = find_win_with_ll(qi);
+ win_T *const llwin = qf_find_win_with_loclist(qi);
if (llwin != NULL) {
wp = llwin;
}
@@ -6604,16 +6738,17 @@ static void qf_free_stack(win_T *wp, qf_info_T *qi)
// quickfix list
qi->qf_curlist = 0;
qi->qf_listcount = 0;
- } else if (IS_LL_WINDOW(orig_wp)) {
+ } else if (qfwin != NULL) {
// If the location list window is open, then create a new empty location
// list
qf_info_T *new_ll = qf_alloc_stack(QFLT_LOCATION);
+ new_ll->qf_bufnr = qfwin->w_buffer->b_fnum;
// first free the list reference in the location list window
- ll_free_all(&orig_wp->w_llist_ref);
+ ll_free_all(&qfwin->w_llist_ref);
- orig_wp->w_llist_ref = new_ll;
- if (llwin != NULL) {
+ qfwin->w_llist_ref = new_ll;
+ if (wp != qfwin) {
win_set_loclist(wp, new_ll);
}
}
@@ -6623,7 +6758,7 @@ static void qf_free_stack(win_T *wp, qf_info_T *qi)
// of dictionaries. "title" will be copied to w:quickfix_title
// "action" is 'a' for add, 'r' for replace. Otherwise create a new list.
// When "what" is not NULL then only set some properties.
-int set_errorlist(win_T *wp, list_T *list, int action, char_u *title, dict_T *what)
+int set_errorlist(win_T *wp, list_T *list, int action, char *title, dict_T *what)
{
qf_info_T *qi = &ql_info;
int retval = OK;
@@ -6708,21 +6843,21 @@ bool set_ref_in_quickfix(int copyID)
}
/// Return the autocmd name for the :cbuffer Ex commands
-static char_u *cbuffer_get_auname(cmdidx_T cmdidx)
+static char *cbuffer_get_auname(cmdidx_T cmdidx)
{
switch (cmdidx) {
case CMD_cbuffer:
- return (char_u *)"cbuffer";
+ return "cbuffer";
case CMD_cgetbuffer:
- return (char_u *)"cgetbuffer";
+ return "cgetbuffer";
case CMD_caddbuffer:
- return (char_u *)"caddbuffer";
+ return "caddbuffer";
case CMD_lbuffer:
- return (char_u *)"lbuffer";
+ return "lbuffer";
case CMD_lgetbuffer:
- return (char_u *)"lgetbuffer";
+ return "lgetbuffer";
case CMD_laddbuffer:
- return (char_u *)"laddbuffer";
+ return "laddbuffer";
default:
return NULL;
}
@@ -6737,7 +6872,7 @@ static int cbuffer_process_args(exarg_T *eap, buf_T **bufp, linenr_T *line1, lin
if (*eap->arg == NUL) {
buf = curbuf;
} else if (*skipwhite(skipdigits(eap->arg)) == NUL) {
- buf = buflist_findnr(atoi((char *)eap->arg));
+ buf = buflist_findnr(atoi(eap->arg));
}
if (buf == NULL) {
@@ -6777,9 +6912,9 @@ static int cbuffer_process_args(exarg_T *eap, buf_T **bufp, linenr_T *line1, lin
void ex_cbuffer(exarg_T *eap)
{
buf_T *buf = NULL;
- char_u *au_name = NULL;
+ char *au_name = NULL;
win_T *wp = NULL;
- char_u *qf_title;
+ char *qf_title;
linenr_T line1;
linenr_T line2;
@@ -6801,9 +6936,8 @@ void ex_cbuffer(exarg_T *eap)
qf_title = qf_cmdtitle(*eap->cmdlinep);
if (buf->b_sfname) {
- vim_snprintf((char *)IObuff, IOSIZE, "%s (%s)",
- (char *)qf_title, (char *)buf->b_sfname);
- qf_title = IObuff;
+ vim_snprintf((char *)IObuff, IOSIZE, "%s (%s)", qf_title, buf->b_sfname);
+ qf_title = (char *)IObuff;
}
incr_quickfix_busy();
@@ -6824,8 +6958,7 @@ void ex_cbuffer(exarg_T *eap)
unsigned save_qfid = qf_get_curlist(qi)->qf_id;
if (au_name != NULL) {
const buf_T *const curbuf_old = curbuf;
- apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
- curbuf->b_fname, true, curbuf);
+ apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, curbuf->b_fname, true, curbuf);
if (curbuf != curbuf_old) {
// Autocommands changed buffer, don't jump now, "qi" may
// be invalid.
@@ -6844,21 +6977,21 @@ void ex_cbuffer(exarg_T *eap)
}
/// Return the autocmd name for the :cexpr Ex commands.
-static char_u *cexpr_get_auname(cmdidx_T cmdidx)
+static char *cexpr_get_auname(cmdidx_T cmdidx)
{
switch (cmdidx) {
case CMD_cexpr:
- return (char_u *)"cexpr";
+ return "cexpr";
case CMD_cgetexpr:
- return (char_u *)"cgetexpr";
+ return "cgetexpr";
case CMD_caddexpr:
- return (char_u *)"caddexpr";
+ return "caddexpr";
case CMD_lexpr:
- return (char_u *)"lexpr";
+ return "lexpr";
case CMD_lgetexpr:
- return (char_u *)"lgetexpr";
+ return "lgetexpr";
case CMD_laddexpr:
- return (char_u *)"laddexpr";
+ return "laddexpr";
default:
return NULL;
}
@@ -6868,7 +7001,7 @@ static char_u *cexpr_get_auname(cmdidx_T cmdidx)
/// ":lexpr {expr}", ":lgetexpr {expr}", ":laddexpr {expr}" command.
void ex_cexpr(exarg_T *eap)
{
- char_u *au_name = NULL;
+ char *au_name = NULL;
win_T *wp = NULL;
au_name = cexpr_get_auname(eap->cmdidx);
@@ -6904,8 +7037,7 @@ void ex_cexpr(exarg_T *eap)
// check for autocommands changing the current quickfix list.
unsigned save_qfid = qf_get_curlist(qi)->qf_id;
if (au_name != NULL) {
- apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
- curbuf->b_fname, true, curbuf);
+ apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, curbuf->b_fname, true, curbuf);
}
// Jump to the first error for a new list and if autocmds didn't
// free the list.
@@ -6954,17 +7086,17 @@ static qf_info_T *hgr_get_ll(bool *new_ll)
}
// Search for a pattern in a help file.
-static void hgr_search_file(qf_list_T *qfl, char_u *fname, regmatch_T *p_regmatch)
+static void hgr_search_file(qf_list_T *qfl, char *fname, regmatch_T *p_regmatch)
FUNC_ATTR_NONNULL_ARG(1, 3)
{
- FILE *const fd = os_fopen((char *)fname, "r");
+ FILE *const fd = os_fopen(fname, "r");
if (fd == NULL) {
return;
}
- long lnum = 1;
+ linenr_T lnum = 1;
while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int) {
- char_u *line = IObuff;
+ char *line = (char *)IObuff;
if (vim_regexec(p_regmatch, line, (colnr_T)0)) {
int l = (int)STRLEN(line);
@@ -6982,8 +7114,8 @@ static void hgr_search_file(qf_list_T *qfl, char_u *fname, regmatch_T *p_regmatc
line,
lnum,
0,
- (int)(p_regmatch->startp[0] - line) + 1, // col
- (int)(p_regmatch->endp[0] - line)
+ (int)(p_regmatch->startp[0] - (char_u *)line) + 1, // col
+ (int)(p_regmatch->endp[0] - (char_u *)line)
+ 1, // end_col
false, // vis_col
NULL, // search pattern
@@ -6992,13 +7124,13 @@ static void hgr_search_file(qf_list_T *qfl, char_u *fname, regmatch_T *p_regmatc
true) // valid
== QF_FAIL) {
got_int = true;
- if (line != IObuff) {
+ if ((char_u *)line != IObuff) {
xfree(line);
}
break;
}
}
- if (line != IObuff) {
+ if ((char_u *)line != IObuff) {
xfree(line);
}
lnum++;
@@ -7009,18 +7141,18 @@ static void hgr_search_file(qf_list_T *qfl, char_u *fname, regmatch_T *p_regmatc
// Search for a pattern in all the help files in the doc directory under
// the given directory.
-static void hgr_search_files_in_dir(qf_list_T *qfl, char_u *dirname, regmatch_T *p_regmatch,
- const char_u *lang)
+static void hgr_search_files_in_dir(qf_list_T *qfl, char *dirname, regmatch_T *p_regmatch,
+ const char *lang)
FUNC_ATTR_NONNULL_ARG(1, 2, 3)
{
int fcount;
- char_u **fnames;
+ char **fnames;
// Find all "*.txt" and "*.??x" files in the "doc" directory.
- add_pathsep((char *)dirname);
+ add_pathsep(dirname);
STRCAT(dirname, "doc/*.\\(txt\\|??x\\)"); // NOLINT
- if (gen_expand_wildcards(1, &dirname, &fcount,
- &fnames, EW_FILE|EW_SILENT) == OK
+ if (gen_expand_wildcards(1, (char_u **)&dirname, &fcount,
+ (char_u ***)&fnames, EW_FILE|EW_SILENT) == OK
&& fcount > 0) {
for (int fi = 0; fi < fcount && !got_int; fi++) {
// Skip files for a different language.
@@ -7034,7 +7166,7 @@ static void hgr_search_files_in_dir(qf_list_T *qfl, char_u *dirname, regmatch_T
hgr_search_file(qfl, fnames[fi], p_regmatch);
}
- FreeWild(fcount, fnames);
+ FreeWild(fcount, (char_u **)fnames);
}
}
@@ -7042,15 +7174,15 @@ static void hgr_search_files_in_dir(qf_list_T *qfl, char_u *dirname, regmatch_T
// and add the matches to a quickfix list.
// 'lang' is the language specifier. If supplied, then only matches in the
// specified language are found.
-static void hgr_search_in_rtp(qf_list_T *qfl, regmatch_T *p_regmatch, const char_u *lang)
+static void hgr_search_in_rtp(qf_list_T *qfl, regmatch_T *p_regmatch, const char *lang)
FUNC_ATTR_NONNULL_ARG(1, 2)
{
// Go through all directories in 'runtimepath'
- char_u *p = p_rtp;
+ char *p = (char *)p_rtp;
while (*p != NUL && !got_int) {
- copy_option_part(&p, NameBuff, MAXPATHL, ",");
+ copy_option_part(&p, (char *)NameBuff, MAXPATHL, ",");
- hgr_search_files_in_dir(qfl, NameBuff, p_regmatch, lang);
+ hgr_search_files_in_dir(qfl, (char *)NameBuff, p_regmatch, (char *)lang);
}
}
@@ -7059,13 +7191,13 @@ void ex_helpgrep(exarg_T *eap)
{
qf_info_T *qi = &ql_info;
bool new_qi = false;
- char_u *au_name = NULL;
+ char *au_name = NULL;
switch (eap->cmdidx) {
case CMD_helpgrep:
- au_name = (char_u *)"helpgrep"; break;
+ au_name = "helpgrep"; break;
case CMD_lhelpgrep:
- au_name = (char_u *)"lhelpgrep"; break;
+ au_name = "lhelpgrep"; break;
default:
break;
}
@@ -7077,8 +7209,8 @@ void ex_helpgrep(exarg_T *eap)
}
// Make 'cpoptions' empty, the 'l' flag should not be used here.
- char_u *const save_cpo = p_cpo;
- p_cpo = empty_option;
+ char *const save_cpo = p_cpo;
+ p_cpo = (char *)empty_option;
if (is_loclist_cmd(eap->cmdidx)) {
qi = hgr_get_ll(&new_qi);
@@ -7087,7 +7219,7 @@ void ex_helpgrep(exarg_T *eap)
incr_quickfix_busy();
// Check for a specified language
- char_u *const lang = check_help_lang(eap->arg);
+ char *const lang = check_help_lang(eap->arg);
regmatch_T regmatch = {
.regprog = vim_regcomp(eap->arg, RE_MAGIC + RE_STRING),
.rm_ic = false,
@@ -7108,16 +7240,15 @@ void ex_helpgrep(exarg_T *eap)
qf_update_buffer(qi, NULL);
}
- if (p_cpo == empty_option) {
+ if ((char_u *)p_cpo == empty_option) {
p_cpo = save_cpo;
} else {
// Darn, some plugin changed the value.
- free_string_option(save_cpo);
+ free_string_option((char_u *)save_cpo);
}
if (au_name != NULL) {
- apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
- curbuf->b_fname, true, curbuf);
+ apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, curbuf->b_fname, true, curbuf);
// When adding a location list to an existing location list stack,
// if the autocmd made the stack invalid, then just return.
if (!new_qi && IS_LL_STACK(qi) && qf_find_win_with_loclist(qi) == NULL) {
@@ -7147,4 +7278,3 @@ void ex_helpgrep(exarg_T *eap)
}
}
}
-