vim-patch:8.0.1406: difficult to track changes to a quickfix list

Problem:    Difficult to track changes to a quickfix list.
Solution:   Add a "changedtick" value. (Yegappan Lakshmanan)

b254af312d
This commit is contained in:
Marco Hinz 2019-04-19 13:13:24 +02:00
parent 6d314484d4
commit 37d666bc80
No known key found for this signature in database
GPG Key ID: 1C980A1B657B4A4F
2 changed files with 112 additions and 7 deletions

View File

@ -101,6 +101,7 @@ typedef struct qf_list_S {
bool qf_multiline; bool qf_multiline;
bool qf_multiignore; bool qf_multiignore;
bool qf_multiscan; bool qf_multiscan;
long qf_changedtick;
} qf_list_T; } qf_list_T;
/// Quickfix/Location list stack definition /// Quickfix/Location list stack definition
@ -1473,6 +1474,7 @@ void copy_loclist(win_T *from, win_T *to)
// Assign a new ID for the location list // Assign a new ID for the location list
to_qfl->qf_id = ++last_qf_id; to_qfl->qf_id = ++last_qf_id;
to_qfl->qf_changedtick = 0L;
/* When no valid entries are present in the list, qf_ptr points to /* When no valid entries are present in the list, qf_ptr points to
* the first item in the list */ * the first item in the list */
@ -2575,6 +2577,7 @@ static void qf_free(qf_info_T *qi, int idx)
tv_free(qfl->qf_ctx); tv_free(qfl->qf_ctx);
qfl->qf_ctx = NULL; qfl->qf_ctx = NULL;
qfl->qf_id = 0; qfl->qf_id = 0;
qfl->qf_changedtick = 0L;
} }
/* /*
@ -3165,6 +3168,11 @@ static void qf_fill_buffer(qf_info_T *qi, buf_T *buf, qfline_T *old_last)
KeyTyped = old_KeyTyped; KeyTyped = old_KeyTyped;
} }
static void qf_list_changed(qf_info_T *qi, int qf_idx)
{
qi->qf_lists[qf_idx].qf_changedtick++;
}
/* /*
* Return TRUE when using ":vimgrep" for ":grep". * Return TRUE when using ":vimgrep" for ":grep".
*/ */
@ -3252,6 +3260,9 @@ void ex_make(exarg_T *eap)
if (wp != NULL) { if (wp != NULL) {
qi = GET_LOC_LIST(wp); qi = GET_LOC_LIST(wp);
} }
if (res >= 0 && qi != NULL) {
qf_list_changed(qi, qi->qf_curlist);
}
if (au_name != NULL) { if (au_name != NULL) {
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
curbuf->b_fname, TRUE, curbuf); curbuf->b_fname, TRUE, curbuf);
@ -3605,13 +3616,16 @@ void ex_cfile(exarg_T *eap)
int res = qf_init(wp, p_ef, p_efm, (eap->cmdidx != CMD_caddfile int res = qf_init(wp, p_ef, p_efm, (eap->cmdidx != CMD_caddfile
&& eap->cmdidx != CMD_laddfile), && eap->cmdidx != CMD_laddfile),
*eap->cmdlinep,enc); *eap->cmdlinep,enc);
if (wp != NULL) {
qi = GET_LOC_LIST(wp);
}
if (res >= 0 && qi != NULL) {
qf_list_changed(qi, qi->qf_curlist);
}
if (au_name != NULL) { if (au_name != NULL) {
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, NULL, false, curbuf); apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, NULL, false, curbuf);
} }
if (res > 0 && (eap->cmdidx == CMD_cfile || eap->cmdidx == CMD_lfile)) { if (res > 0 && (eap->cmdidx == CMD_cfile || eap->cmdidx == CMD_lfile)) {
if (wp != NULL) {
qi = GET_LOC_LIST(wp);
}
qf_jump(qi, 0, 0, eap->forceit); // display first error qf_jump(qi, 0, 0, eap->forceit); // display first error
} }
} }
@ -3912,6 +3926,7 @@ void ex_vimgrep(exarg_T *eap)
qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE; qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE;
qi->qf_lists[qi->qf_curlist].qf_ptr = qi->qf_lists[qi->qf_curlist].qf_start; qi->qf_lists[qi->qf_curlist].qf_ptr = qi->qf_lists[qi->qf_curlist].qf_start;
qi->qf_lists[qi->qf_curlist].qf_index = 1; qi->qf_lists[qi->qf_curlist].qf_index = 1;
qf_list_changed(qi, qi->qf_curlist);
qf_update_buffer(qi, NULL); qf_update_buffer(qi, NULL);
@ -4201,7 +4216,8 @@ enum {
QF_GETLIST_ID = 0x20, QF_GETLIST_ID = 0x20,
QF_GETLIST_IDX = 0x40, QF_GETLIST_IDX = 0x40,
QF_GETLIST_SIZE = 0x80, QF_GETLIST_SIZE = 0x80,
QF_GETLIST_ALL = 0xFF QF_GETLIST_TICK = 0x100,
QF_GETLIST_ALL = 0x1FF
}; };
// Parse text from 'di' and return the quickfix list items // Parse text from 'di' and return the quickfix list items
@ -4299,6 +4315,9 @@ int qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
if (tv_dict_find(what, S_LEN("size")) != NULL) { if (tv_dict_find(what, S_LEN("size")) != NULL) {
flags |= QF_GETLIST_SIZE; flags |= QF_GETLIST_SIZE;
} }
if (tv_dict_find(what, S_LEN("changedtick")) != NULL) {
flags |= QF_GETLIST_TICK;
}
int qf_idx; int qf_idx;
@ -4367,6 +4386,9 @@ int qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
if ((status == OK) && (flags & QF_GETLIST_SIZE)) { if ((status == OK) && (flags & QF_GETLIST_SIZE)) {
status = tv_dict_add_nr(retdict, S_LEN("size"), 0); status = tv_dict_add_nr(retdict, S_LEN("size"), 0);
} }
if ((status == OK) && (flags & QF_GETLIST_TICK)) {
status = tv_dict_add_nr(retdict, S_LEN("changedtick"), 0);
}
return status; return status;
} }
@ -4423,6 +4445,11 @@ int qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
qi->qf_lists[qf_idx].qf_count); qi->qf_lists[qf_idx].qf_count);
} }
if ((status == OK) && (flags & QF_GETLIST_TICK)) {
status = tv_dict_add_nr(retdict, S_LEN("changedtick"),
qi->qf_lists[qf_idx].qf_changedtick);
}
return status; return status;
} }
@ -4658,6 +4685,10 @@ static int qf_set_properties(qf_info_T *qi, dict_T *what, int action,
retval = OK; retval = OK;
} }
if (retval == OK) {
qf_list_changed(qi, qf_idx);
}
return retval; return retval;
} }
@ -4739,6 +4770,9 @@ int set_errorlist(win_T *wp, list_T *list, int action, char_u *title,
retval = qf_set_properties(qi, what, action, title); retval = qf_set_properties(qi, what, action, title);
} else { } else {
retval = qf_add_entries(qi, qi->qf_curlist, list, title, action); retval = qf_add_entries(qi, qi->qf_curlist, list, title, action);
if (retval == OK) {
qf_list_changed(qi, qi->qf_curlist);
}
} }
return retval; return retval;
@ -4860,6 +4894,9 @@ void ex_cbuffer(exarg_T *eap)
(eap->cmdidx != CMD_caddbuffer (eap->cmdidx != CMD_caddbuffer
&& eap->cmdidx != CMD_laddbuffer), && eap->cmdidx != CMD_laddbuffer),
eap->line1, eap->line2, qf_title, NULL); eap->line1, eap->line2, qf_title, NULL);
if (res >= 0) {
qf_list_changed(qi, qi->qf_curlist);
}
if (au_name != NULL) { if (au_name != NULL) {
apply_autocmds(EVENT_QUICKFIXCMDPOST, (char_u *)au_name, apply_autocmds(EVENT_QUICKFIXCMDPOST, (char_u *)au_name,
curbuf->b_fname, true, curbuf); curbuf->b_fname, true, curbuf);
@ -4925,6 +4962,9 @@ void ex_cexpr(exarg_T *eap)
(eap->cmdidx != CMD_caddexpr (eap->cmdidx != CMD_caddexpr
&& eap->cmdidx != CMD_laddexpr), && eap->cmdidx != CMD_laddexpr),
(linenr_T)0, (linenr_T)0, *eap->cmdlinep, NULL); (linenr_T)0, (linenr_T)0, *eap->cmdlinep, NULL);
if (res >= 0) {
qf_list_changed(qi, qi->qf_curlist);
}
if (au_name != NULL) { if (au_name != NULL) {
apply_autocmds(EVENT_QUICKFIXCMDPOST, (char_u *)au_name, apply_autocmds(EVENT_QUICKFIXCMDPOST, (char_u *)au_name,
curbuf->b_fname, true, curbuf); curbuf->b_fname, true, curbuf);
@ -5097,6 +5137,7 @@ void ex_helpgrep(exarg_T *eap)
/* Darn, some plugin changed the value. */ /* Darn, some plugin changed the value. */
free_string_option(save_cpo); free_string_option(save_cpo);
qf_list_changed(qi, qi->qf_curlist);
qf_update_buffer(qi, NULL); qf_update_buffer(qi, NULL);
if (au_name != NULL) { if (au_name != NULL) {

View File

@ -2084,6 +2084,8 @@ func Test_Autocmd()
call delete('Xtest') call delete('Xtest')
call delete('Xempty') call delete('Xempty')
au! QuickFixCmdPre
au! QuickFixCmdPost
endfunc endfunc
func Test_Autocmd_Exception() func Test_Autocmd_Exception()
@ -2854,7 +2856,8 @@ func Xgetlist_empty_tests(cchar)
call assert_equal(0, g:Xgetlist({'size' : 0}).size) call assert_equal(0, g:Xgetlist({'size' : 0}).size)
call assert_equal('', g:Xgetlist({'title' : 0}).title) call assert_equal('', g:Xgetlist({'title' : 0}).title)
call assert_equal(0, g:Xgetlist({'winid' : 0}).winid) call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0}, g:Xgetlist({'all' : 0})) call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 'changedtick': 0}, g:Xgetlist({'all' : 0}))
" Empty quickfix list " Empty quickfix list
Xexpr "" Xexpr ""
@ -2866,6 +2869,7 @@ func Xgetlist_empty_tests(cchar)
call assert_equal(0, g:Xgetlist({'size' : 0}).size) call assert_equal(0, g:Xgetlist({'size' : 0}).size)
call assert_notequal('', g:Xgetlist({'title' : 0}).title) call assert_notequal('', g:Xgetlist({'title' : 0}).title)
call assert_equal(0, g:Xgetlist({'winid' : 0}).winid) call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
let qfid = g:Xgetlist({'id' : 0}).id let qfid = g:Xgetlist({'id' : 0}).id
call g:Xsetlist([], 'f') call g:Xsetlist([], 'f')
@ -2879,7 +2883,8 @@ func Xgetlist_empty_tests(cchar)
call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size) call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title) call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid) call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0})) call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
" Non-existing quickfix list number " Non-existing quickfix list number
call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context) call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
@ -2890,10 +2895,69 @@ func Xgetlist_empty_tests(cchar)
call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size) call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title) call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid) call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0}, g:Xgetlist({'nr' : 5, 'all' : 0})) call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 'changedtick' : 0}, g:Xgetlist({'nr' : 5, 'all' : 0}))
endfunc endfunc
func Test_getqflist() func Test_getqflist()
call Xgetlist_empty_tests('c') call Xgetlist_empty_tests('c')
call Xgetlist_empty_tests('l') call Xgetlist_empty_tests('l')
endfunc endfunc
" Tests for the quickfix/location list changedtick
func Xqftick_tests(cchar)
call s:setup_commands(a:cchar)
call g:Xsetlist([], 'f')
Xexpr "F1:10:Line10"
let qfid = g:Xgetlist({'id' : 0}).id
call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Xaddexpr "F2:20:Line20\nF2:21:Line21"
call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
call g:Xsetlist([], 'a', {'title' : 'New Title'})
call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
enew!
call append(0, ["F5:50:L50", "F6:60:L60"])
Xaddbuffer
call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
enew!
call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
\ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
\ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
\ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
call writefile(["F8:80:L80", "F8:81:L81"], "Xone")
Xfile Xone
call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Xaddfile Xone
call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
" Test case for updating a non-current quickfix list
call g:Xsetlist([], 'f')
Xexpr "F1:1:L1"
Xexpr "F2:2:L2"
call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
call delete("Xone")
endfunc
func Test_qf_tick()
call Xqftick_tests('c')
call Xqftick_tests('l')
endfunc