diff options
Diffstat (limited to 'src/nvim/quickfix.c')
-rw-r--r-- | src/nvim/quickfix.c | 93 |
1 files changed, 58 insertions, 35 deletions
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index be6e48465f..6c26e53cd7 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -728,6 +728,15 @@ static int qf_get_nextline(qfstate_T *state) return QF_OK; } +// Returns true if the specified quickfix/location list is empty. +static bool qf_list_empty(const qf_info_T *qi, int qf_idx) + FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT +{ + if (qi == NULL || qf_idx < 0 || qf_idx >= LISTCOUNT) { + return true; + } + return qi->qf_lists[qf_idx].qf_count <= 0; +} /// Parse a line and get the quickfix fields. /// Return the QF_ status. @@ -2209,7 +2218,7 @@ static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit, // set b_p_ro flag). if (!can_abandon(curbuf, forceit)) { no_write_message(); - retval = false; + retval = FAIL; } else { retval = do_ecmd(qf_ptr->qf_fnum, NULL, NULL, NULL, (linenr_T)1, ECMD_HIDE + ECMD_SET_HELP, @@ -2242,7 +2251,7 @@ static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit, } if (*abort) { - retval = false; + retval = FAIL; } } @@ -2906,8 +2915,7 @@ void qf_view_result(bool split) if (IS_LL_WINDOW(curwin)) { qi = GET_LOC_LIST(curwin); } - if (qi == NULL - || qi->qf_lists[qi->qf_curlist].qf_count == 0) { + if (qf_list_empty(qi, qi->qf_curlist)) { EMSG(_(e_quickfix)); return; } @@ -3448,6 +3456,38 @@ static int qf_id2nr(const qf_info_T *const qi, const unsigned qfid) return INVALID_QFIDX; } +// If the current list is not "save_qfid" and we can find the list with that ID +// then make it the current list. +// This is used when autocommands may have changed the current list. +// Returns OK if successfully restored the list. Returns FAIL if the list with +// the specified identifier (save_qfid) is not found in the stack. +static int qf_restore_list(qf_info_T *qi, unsigned save_qfid) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +{ + if (qi->qf_lists[qi->qf_curlist].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; + } + return OK; +} + +// Jump to the first entry if there is one. +static void qf_jump_first(qf_info_T *qi, unsigned save_qfid, int forceit) + FUNC_ATTR_NONNULL_ALL +{ + if (qf_restore_list(qi, save_qfid) == FAIL) { + return; + } + // Autocommands might have cleared the list, check for that + if (!qf_list_empty(qi, qi->qf_curlist)) { + qf_jump(qi, 0, 0, forceit); + } +} + /* * Return TRUE when using ":vimgrep" for ":grep". */ @@ -3549,11 +3589,8 @@ void ex_make(exarg_T *eap) curbuf); } if (res > 0 && !eap->forceit && qflist_valid(wp, save_qfid)) { - // If autocommands changed the current list, then restore it. - if (qi->qf_lists[qi->qf_curlist].qf_id != save_qfid) { - qi->qf_curlist = qf_id2nr(qi, save_qfid); - } - qf_jump(qi, 0, 0, false); // display first error + // display the first error + qf_jump_first(qi, save_qfid, false); } cleanup: @@ -3919,11 +3956,8 @@ void ex_cfile(exarg_T *eap) // list. if (res > 0 && (eap->cmdidx == CMD_cfile || eap->cmdidx == CMD_lfile) && qflist_valid(wp, save_qfid)) { - // If autocommands changed the current list, then restore it - if (qi->qf_lists[qi->qf_curlist].qf_id != save_qfid) { - qi->qf_curlist = qf_id2nr(qi, save_qfid); - } - qf_jump(qi, 0, 0, eap->forceit); // display first error + // display the first error + qf_jump_first(qi, save_qfid, eap->forceit); } } @@ -4022,10 +4056,8 @@ static bool vgr_qflist_valid(win_T *wp, qf_info_T *qi, unsigned qfid, return true; } } - if (qi->qf_lists[qi->qf_curlist].qf_id != qfid) { - // Autocommands changed the quickfix list. Find the one we were using - // and restore it. - qi->qf_curlist = qf_id2nr(qi, qfid); + if (qf_restore_list(qi, qfid) == FAIL) { + return false; } return true; @@ -4322,9 +4354,8 @@ void ex_vimgrep(exarg_T *eap) goto theend; } - // If autocommands changed the current list, then restore it. - if (qi->qf_lists[qi->qf_curlist].qf_id != save_qfid) { - qi->qf_curlist = qf_id2nr(qi, save_qfid); + if (qf_restore_list(qi, save_qfid) == FAIL) { + goto theend; } /* Jump to first match. */ @@ -4532,7 +4563,7 @@ int get_errorlist(const qf_info_T *qi_arg, win_T *wp, int qf_idx, list_T *list) } } - if (qf_idx == -1) { + if (qf_idx == INVALID_QFIDX) { qf_idx = qi->qf_curlist; } @@ -4625,9 +4656,7 @@ static int qf_get_list_from_lines(dict_T *what, dictitem_T *di, dict_T *retdict) } list_T *l = tv_list_alloc(kListLenMayKnow); - qf_info_T *qi = xmalloc(sizeof(*qi)); - memset(qi, 0, sizeof(*qi)); - qi->qf_refcount++; + qf_info_T *const qi = ll_new_list(); if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, errorformat, true, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0) { @@ -5421,11 +5450,8 @@ void ex_cbuffer(exarg_T *eap) // free the list. if (res > 0 && (eap->cmdidx == CMD_cbuffer || eap->cmdidx == CMD_lbuffer) && qflist_valid(wp, save_qfid)) { - // If autocommands changed the current list, then restore it. - if (qi->qf_lists[qi->qf_curlist].qf_id != save_qfid) { - qi->qf_curlist = qf_id2nr(qi, save_qfid); - } - qf_jump(qi, 0, 0, eap->forceit); // display first error + // display the first error + qf_jump_first(qi, save_qfid, eap->forceit); } } } @@ -5503,11 +5529,8 @@ void ex_cexpr(exarg_T *eap) if (res > 0 && (eap->cmdidx == CMD_cexpr || eap->cmdidx == CMD_lexpr) && qflist_valid(wp, save_qfid)) { - // If autocommands changed the current list, then restore it. - if (qi->qf_lists[qi->qf_curlist].qf_id != save_qfid) { - qi->qf_curlist = qf_id2nr(qi, save_qfid); - } - qf_jump(qi, 0, 0, eap->forceit); + // display the first error + qf_jump_first(qi, save_qfid, eap->forceit); } } else { EMSG(_("E777: String or List expected")); |