aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/quickfix.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/quickfix.c')
-rw-r--r--src/nvim/quickfix.c262
1 files changed, 138 insertions, 124 deletions
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index f0c1011844..58a7379b63 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -1190,13 +1190,15 @@ static void qf_store_title(qf_list_T *qfl, const char *title)
{
XFREE_CLEAR(qfl->qf_title);
- if (title != NULL) {
- size_t len = strlen(title) + 1;
- char *p = xmallocz(len);
-
- qfl->qf_title = p;
- xstrlcpy(p, title, len + 1);
+ if (title == NULL) {
+ return;
}
+
+ size_t len = strlen(title) + 1;
+ char *p = xmallocz(len);
+
+ qfl->qf_title = p;
+ xstrlcpy(p, title, len + 1);
}
/// The title of a quickfix/location list is set, by default, to the command
@@ -1684,14 +1686,16 @@ int qf_stack_get_bufnr(void)
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;
- }
+ if (qi->qf_bufnr == INVALID_QFBUFNR) {
+ return;
+ }
+
+ 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;
}
}
@@ -3878,59 +3882,61 @@ static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last)
{
// Check if a buffer for the quickfix list exists. Update it.
buf_T *buf = qf_find_buf(qi);
- if (buf != NULL) {
- linenr_T old_line_count = buf->b_ml.ml_line_count;
- int qf_winid = 0;
-
- win_T *win;
- if (IS_LL_STACK(qi)) {
- if (curwin->w_llist == qi) {
- win = curwin;
- } else {
- // Find the file window (non-quickfix) with this location list
- win = qf_find_win_with_loclist(qi);
- if (win == NULL) {
- // File window is not found. Find the location list window.
- win = qf_find_win(qi);
- }
- if (win == NULL) {
- return;
- }
+ if (buf == NULL) {
+ return;
+ }
+
+ linenr_T old_line_count = buf->b_ml.ml_line_count;
+ int qf_winid = 0;
+
+ win_T *win;
+ if (IS_LL_STACK(qi)) {
+ if (curwin->w_llist == qi) {
+ win = curwin;
+ } else {
+ // Find the file window (non-quickfix) with this location list
+ win = qf_find_win_with_loclist(qi);
+ if (win == NULL) {
+ // File window is not found. Find the location list window.
+ win = qf_find_win(qi);
+ }
+ if (win == NULL) {
+ return;
}
- qf_winid = (int)win->handle;
}
+ qf_winid = (int)win->handle;
+ }
- // autocommands may cause trouble
- incr_quickfix_busy();
-
- aco_save_T aco;
+ // autocommands may cause trouble
+ incr_quickfix_busy();
- if (old_last == NULL) {
- // set curwin/curbuf to buf and save a few things
- aucmd_prepbuf(&aco, buf);
- }
+ aco_save_T aco;
- qf_update_win_titlevar(qi);
+ if (old_last == NULL) {
+ // set curwin/curbuf to buf and save a few things
+ aucmd_prepbuf(&aco, buf);
+ }
- qf_fill_buffer(qf_get_curlist(qi), buf, old_last, qf_winid);
- buf_inc_changedtick(buf);
+ qf_update_win_titlevar(qi);
- if (old_last == NULL) {
- (void)qf_win_pos_update(qi, 0);
+ qf_fill_buffer(qf_get_curlist(qi), buf, old_last, qf_winid);
+ buf_inc_changedtick(buf);
- // restore curwin/curbuf and a few other things
- aucmd_restbuf(&aco);
- }
+ if (old_last == NULL) {
+ (void)qf_win_pos_update(qi, 0);
- // Only redraw when added lines are visible. This avoids flickering when
- // the added lines are not visible.
- if ((win = qf_find_win(qi)) != NULL && old_line_count < win->w_botline) {
- redraw_buf_later(buf, UPD_NOT_VALID);
- }
+ // restore curwin/curbuf and a few other things
+ aucmd_restbuf(&aco);
+ }
- // always called after incr_quickfix_busy()
- decr_quickfix_busy();
+ // Only redraw when added lines are visible. This avoids flickering when
+ // the added lines are not visible.
+ if ((win = qf_find_win(qi)) != NULL && old_line_count < win->w_botline) {
+ redraw_buf_later(buf, UPD_NOT_VALID);
}
+
+ // always called after incr_quickfix_busy()
+ decr_quickfix_busy();
}
// Add an error line to the quickfix buffer.
@@ -4188,14 +4194,16 @@ static int qf_id2nr(const qf_info_T *const qi, const unsigned qfid)
static int qf_restore_list(qf_info_T *qi, unsigned save_qfid)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
- if (qf_get_curlist(qi)->qf_id != save_qfid) {
- const int curlist = qf_id2nr(qi, save_qfid);
- if (curlist < 0) {
- // list is not present
- return FAIL;
- }
- qi->qf_curlist = curlist;
+ if (qf_get_curlist(qi)->qf_id == save_qfid) {
+ return OK;
+ }
+
+ const int curlist = qf_id2nr(qi, save_qfid);
+ if (curlist < 0) {
+ // list is not present
+ return FAIL;
}
+ qi->qf_curlist = curlist;
return OK;
}
@@ -5736,12 +5744,14 @@ static void wipe_dummy_buffer(buf_T *buf, char *dirname_start)
// 'autochdir' option have changed it.
static void unload_dummy_buffer(buf_T *buf, char *dirname_start)
{
- if (curbuf != buf) { // safety check
- close_buffer(NULL, buf, DOBUF_UNLOAD, false, true);
-
- // When autocommands/'autochdir' option changed directory: go back.
- restore_start_dir(dirname_start);
+ if (curbuf == buf) { // safety check
+ return;
}
+
+ close_buffer(NULL, buf, DOBUF_UNLOAD, false, true);
+
+ // When autocommands/'autochdir' option changed directory: go back.
+ restore_start_dir(dirname_start);
}
/// Copy the specified quickfix entry items into a new dict and append the dict
@@ -5866,32 +5876,34 @@ static int qf_get_list_from_lines(dict_T *what, dictitem_T *di, dict_T *retdict)
int status = FAIL;
// Only a List value is supported
- if (di->di_tv.v_type == VAR_LIST && di->di_tv.vval.v_list != NULL) {
- char *errorformat = p_efm;
- dictitem_T *efm_di;
- // If errorformat is supplied then use it, otherwise use the 'efm'
- // option setting
- if ((efm_di = tv_dict_find(what, S_LEN("efm"))) != NULL) {
- if (efm_di->di_tv.v_type != VAR_STRING
- || efm_di->di_tv.vval.v_string == NULL) {
- return FAIL;
- }
- errorformat = efm_di->di_tv.vval.v_string;
- }
-
- list_T *l = tv_list_alloc(kListLenMayKnow);
- qf_info_T *const qi = qf_alloc_stack(QFLT_INTERNAL);
+ if (di->di_tv.v_type != VAR_LIST || di->di_tv.vval.v_list == NULL) {
+ return FAIL;
+ }
- if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, errorformat,
- true, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0) {
- (void)get_errorlist(qi, NULL, 0, 0, l);
- qf_free(&qi->qf_lists[0]);
+ char *errorformat = p_efm;
+ dictitem_T *efm_di;
+ // If errorformat is supplied then use it, otherwise use the 'efm'
+ // option setting
+ if ((efm_di = tv_dict_find(what, S_LEN("efm"))) != NULL) {
+ if (efm_di->di_tv.v_type != VAR_STRING
+ || efm_di->di_tv.vval.v_string == NULL) {
+ return FAIL;
}
- xfree(qi);
+ errorformat = efm_di->di_tv.vval.v_string;
+ }
- tv_dict_add_list(retdict, S_LEN("items"), l);
- status = OK;
+ list_T *l = tv_list_alloc(kListLenMayKnow);
+ qf_info_T *const qi = qf_alloc_stack(QFLT_INTERNAL);
+
+ if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, errorformat,
+ true, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0) {
+ (void)get_errorlist(qi, NULL, 0, 0, l);
+ qf_free(&qi->qf_lists[0]);
}
+ xfree(qi);
+
+ tv_dict_add_list(retdict, S_LEN("items"), l);
+ status = OK;
return status;
}
@@ -6934,43 +6946,45 @@ void ex_cexpr(exarg_T *eap)
// Evaluate the expression. When the result is a string or a list we can
// use it to fill the errorlist.
typval_T tv;
- if (eval0(eap->arg, &tv, &eap->nextcmd, true) != FAIL) {
- if ((tv.v_type == VAR_STRING && tv.vval.v_string != NULL)
- || tv.v_type == VAR_LIST) {
- incr_quickfix_busy();
- int res = qf_init_ext(qi, qi->qf_curlist, NULL, NULL, &tv, p_efm,
- (eap->cmdidx != CMD_caddexpr
- && eap->cmdidx != CMD_laddexpr),
- (linenr_T)0, (linenr_T)0,
- qf_cmdtitle(*eap->cmdlinep), NULL);
- if (qf_stack_empty(qi)) {
- decr_quickfix_busy();
- goto cleanup;
- }
- if (res >= 0) {
- qf_list_changed(qf_get_curlist(qi));
- }
- // 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);
- }
- // Jump to the first error for a new list and if autocmds didn't
- // free the list.
- if (res > 0
- && (eap->cmdidx == CMD_cexpr || eap->cmdidx == CMD_lexpr)
- && qflist_valid(wp, save_qfid)) {
- // display the first error
- qf_jump_first(qi, save_qfid, eap->forceit);
- }
+ if (eval0(eap->arg, &tv, &eap->nextcmd, true) == FAIL) {
+ return;
+ }
+
+ if ((tv.v_type == VAR_STRING && tv.vval.v_string != NULL)
+ || tv.v_type == VAR_LIST) {
+ incr_quickfix_busy();
+ int res = qf_init_ext(qi, qi->qf_curlist, NULL, NULL, &tv, p_efm,
+ (eap->cmdidx != CMD_caddexpr
+ && eap->cmdidx != CMD_laddexpr),
+ (linenr_T)0, (linenr_T)0,
+ qf_cmdtitle(*eap->cmdlinep), NULL);
+ if (qf_stack_empty(qi)) {
decr_quickfix_busy();
- } else {
- emsg(_("E777: String or List expected"));
+ goto cleanup;
}
-cleanup:
- tv_clear(&tv);
+ if (res >= 0) {
+ qf_list_changed(qf_get_curlist(qi));
+ }
+ // 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);
+ }
+ // Jump to the first error for a new list and if autocmds didn't
+ // free the list.
+ if (res > 0
+ && (eap->cmdidx == CMD_cexpr || eap->cmdidx == CMD_lexpr)
+ && qflist_valid(wp, save_qfid)) {
+ // display the first error
+ qf_jump_first(qi, save_qfid, eap->forceit);
+ }
+ decr_quickfix_busy();
+ } else {
+ emsg(_("E777: String or List expected"));
}
+cleanup:
+ tv_clear(&tv);
}
// Get the location list for ":lhelpgrep"