vim-patch:8.1.0720: cannot easily change the current quickfx list index

Problem:    Cannot easily change the current quickfx list index.
Solution:   Add the "idx" argument to setqflist(). (Yegappan Lakshmanan,
            closes vim/vim#3701)
5b69c22fd2
This commit is contained in:
Jan Edmund Lazo
2020-10-10 12:46:34 -04:00
parent 0e056d4a06
commit e9004e2af0
4 changed files with 147 additions and 14 deletions

View File

@@ -3839,7 +3839,7 @@ feedkeys({string} [, {mode}]) *feedkeys()*
stuck, waiting for a character to be typed before the stuck, waiting for a character to be typed before the
script continues. script continues.
Note that if you manage to call feedkeys() while Note that if you manage to call feedkeys() while
executing commands, thus calling it recursively, the executing commands, thus calling it recursively, then
all typehead will be consumed by the last call. all typehead will be consumed by the last call.
'!' When used with 'x' will not end Insert mode. Can be '!' When used with 'x' will not end Insert mode. Can be
used in a test when a timer is set to exit Insert mode used in a test when a timer is set to exit Insert mode
@@ -4642,7 +4642,7 @@ getloclist({nr},[, {what}]) *getloclist()*
If {what} contains 'filewinid', then returns the id of the If {what} contains 'filewinid', then returns the id of the
window used to display files from the location list. This window used to display files from the location list. This
field is applicable only when called from a location list field is applicable only when called from a location list
window. window. See |location-list-file-window| for more details.
getmatches([{win}]) *getmatches()* getmatches([{win}]) *getmatches()*
Returns a |List| with all matches previously defined for the Returns a |List| with all matches previously defined for the
@@ -4733,7 +4733,9 @@ getqflist([{what}]) *getqflist()*
id get information for the quickfix list with id get information for the quickfix list with
|quickfix-ID|; zero means the id for the |quickfix-ID|; zero means the id for the
current list or the list specified by "nr" current list or the list specified by "nr"
idx index of the current entry in the list idx index of the current entry in the quickfix
list specified by 'id' or 'nr'.
See |quickfix-index|
items quickfix list entries items quickfix list entries
lines parse a list of lines using 'efm' and return lines parse a list of lines using 'efm' and return
the resulting entries. Only a |List| type is the resulting entries. Only a |List| type is
@@ -4926,6 +4928,19 @@ getwinpos([{timeout}]) *getwinpos()*
{timeout} can be used to specify how long to wait in msec for {timeout} can be used to specify how long to wait in msec for
a response from the terminal. When omitted 100 msec is used. a response from the terminal. When omitted 100 msec is used.
Use a longer time for a remote terminal.
When using a value less than 10 and no response is received
within that time, a previously reported position is returned,
if available. This can be used to poll for the position and
do some work in the meantime: >
while 1
let res = getwinpos(1)
if res[0] >= 0
break
endif
" Do some work here
endwhile
<
*getwinposx()* *getwinposx()*
getwinposx() The result is a Number, which is the X coordinate in pixels of getwinposx() The result is a Number, which is the X coordinate in pixels of
the left hand side of the GUI Vim window. The result will be the left hand side of the GUI Vim window. The result will be
@@ -6263,6 +6278,7 @@ mode([expr]) Return a string that indicates the current mode.
nov Operator-pending (forced charwise |o_v|) nov Operator-pending (forced charwise |o_v|)
noV Operator-pending (forced linewise |o_V|) noV Operator-pending (forced linewise |o_V|)
noCTRL-V Operator-pending (forced blockwise |o_CTRL-V|) noCTRL-V Operator-pending (forced blockwise |o_CTRL-V|)
CTRL-V is one character
niI Normal using |i_CTRL-O| in |Insert-mode| niI Normal using |i_CTRL-O| in |Insert-mode|
niR Normal using |i_CTRL-O| in |Replace-mode| niR Normal using |i_CTRL-O| in |Replace-mode|
niV Normal using |i_CTRL-O| in |Virtual-Replace-mode| niV Normal using |i_CTRL-O| in |Virtual-Replace-mode|
@@ -7622,16 +7638,22 @@ setqflist({list} [, {action}[, {what}]]) *setqflist()*
efm errorformat to use when parsing text from efm errorformat to use when parsing text from
"lines". If this is not present, then the "lines". If this is not present, then the
'errorformat' option value is used. 'errorformat' option value is used.
See |quickfix-parse|
id quickfix list identifier |quickfix-ID| id quickfix list identifier |quickfix-ID|
idx index of the current entry in the quickfix
list specified by 'id' or 'nr'. If set to '$',
then the last entry in the list is set as the
current entry. See |quickfix-index|
items list of quickfix entries. Same as the {list} items list of quickfix entries. Same as the {list}
argument. argument.
lines use 'errorformat' to parse a list of lines and lines use 'errorformat' to parse a list of lines and
add the resulting entries to the quickfix list add the resulting entries to the quickfix list
{nr} or {id}. Only a |List| value is supported. {nr} or {id}. Only a |List| value is supported.
See |quickfix-parse|
nr list number in the quickfix stack; zero nr list number in the quickfix stack; zero
means the current quickfix list and "$" means means the current quickfix list and "$" means
the last quickfix list the last quickfix list.
title quickfix list title text title quickfix list title text. See |quickfix-title|
Unsupported keys in {what} are ignored. Unsupported keys in {what} are ignored.
If the "nr" item is not present, then the current quickfix list If the "nr" item is not present, then the current quickfix list
is modified. When creating a new quickfix list, "nr" can be is modified. When creating a new quickfix list, "nr" can be

View File

@@ -43,6 +43,7 @@ A location list is a window-local quickfix list. You get one after commands
like `:lvimgrep`, `:lgrep`, `:lhelpgrep`, `:lmake`, etc., which create a like `:lvimgrep`, `:lgrep`, `:lhelpgrep`, `:lmake`, etc., which create a
location list instead of a quickfix list as the corresponding `:vimgrep`, location list instead of a quickfix list as the corresponding `:vimgrep`,
`:grep`, `:helpgrep`, `:make` do. `:grep`, `:helpgrep`, `:make` do.
*location-list-file-window*
A location list is associated with a window and each window can have a A location list is associated with a window and each window can have a
separate location list. A location list can be associated with only one separate location list. A location list can be associated with only one
window. The location list is independent of the quickfix list. window. The location list is independent of the quickfix list.
@@ -718,6 +719,9 @@ using these functions are below:
" get the location list window id of the third window " get the location list window id of the third window
:echo getloclist(3, {'winid' : 0}).winid :echo getloclist(3, {'winid' : 0}).winid
" get the file window id of a location list window (winnr: 4)
:echo getloclist(4, {'filewinid' : 0}).filewinid
< <
*setqflist-examples* *setqflist-examples*
The |setqflist()| and |setloclist()| functions can be used to set the various The |setqflist()| and |setloclist()| functions can be used to set the various
@@ -732,6 +736,9 @@ using these functions are below:
" set the title of the current quickfix list " set the title of the current quickfix list
:call setqflist([], 'a', {'title' : 'Mytitle'}) :call setqflist([], 'a', {'title' : 'Mytitle'})
" change the current entry in the list specified by an identifier
:call setqflist([], 'a', {'id' : qfid, 'idx' : 10})
" set the context of a quickfix list specified by an identifier " set the context of a quickfix list specified by an identifier
:call setqflist([], 'a', {'id' : qfid, 'context' : {'val' : 100}}) :call setqflist([], 'a', {'id' : qfid, 'context' : {'val' : 100}})

View File

@@ -2936,19 +2936,20 @@ static int qf_jump_to_buffer(qf_info_T *qi, int qf_index, qfline_T *qf_ptr,
return retval; return retval;
} }
/// Jump to a quickfix line. /// Jump to a quickfix line and try to use an existing window.
/// If dir == FORWARD go "errornr" valid entries forward.
/// If dir == BACKWARD go "errornr" valid entries backward.
/// If dir == FORWARD_FILE go "errornr" valid entries files backward.
/// If dir == BACKWARD_FILE go "errornr" valid entries files backward.
/// else if "errornr" is zero, redisplay the same line
/// else go to entry "errornr".
void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit) void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit)
{ {
qf_jump_newwin(qi, dir, errornr, forceit, false); qf_jump_newwin(qi, dir, errornr, forceit, false);
} }
// As qf_info(). // Jump to a quickfix line.
// If dir == 0 go to entry "errornr".
// If dir == FORWARD go "errornr" valid entries forward.
// If dir == BACKWARD go "errornr" valid entries backward.
// If dir == FORWARD_FILE go "errornr" valid entries files backward.
// If dir == BACKWARD_FILE go "errornr" valid entries files backward
// else if "errornr" is zero, redisplay the same line
// If 'forceit' is true, then can discard changes to the current buffer.
// If 'newwin' is true, then open the file in a new window. // If 'newwin' is true, then open the file in a new window.
static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit, static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit,
bool newwin) bool newwin)
@@ -3297,7 +3298,7 @@ void qf_history(exarg_T *eap)
qf_info_T *qi = qf_cmd_get_stack(eap, false); qf_info_T *qi = qf_cmd_get_stack(eap, false);
int i; int i;
if (qf_stack_empty(qi) || qf_list_empty(qf_get_curlist(qi))) { if (qf_stack_empty(qi)) {
MSG(_("No entries")); MSG(_("No entries"));
} else { } else {
for (i = 0; i < qi->qf_listcount; i++) { for (i = 0; i < qi->qf_listcount; i++) {
@@ -6134,6 +6135,49 @@ static int qf_setprop_context(qf_list_T *qfl, dictitem_T *di)
return OK; return OK;
} }
// Set the current index in the specified quickfix list
static int qf_setprop_curidx(qf_info_T *qi, qf_list_T *qfl,
const dictitem_T *di)
FUNC_ATTR_NONNULL_ALL
{
int newidx;
// If the specified index is '$', then use the last entry
if (di->di_tv.v_type == VAR_STRING
&& di->di_tv.vval.v_string != NULL
&& STRCMP(di->di_tv.vval.v_string, "$") == 0) {
newidx = qfl->qf_count;
} else {
// Otherwise use the specified index
bool denote = false;
newidx = (int)tv_get_number_chk(&di->di_tv, &denote);
if (denote) {
return FAIL;
}
}
if (newidx < 1) { // sanity check
return FAIL;
}
if (newidx > qfl->qf_count) {
newidx = qfl->qf_count;
}
const int old_qfidx = qfl->qf_index;
qfline_T *const qf_ptr = get_nth_entry(qfl, newidx, &newidx);
if (qf_ptr == NULL) {
return FAIL;
}
qfl->qf_ptr = qf_ptr;
qfl->qf_index = newidx;
// If the current list is modified and it is displayed in the quickfix
// window, then Update it.
if (qi->qf_lists[qi->qf_curlist].qf_id == qfl->qf_id) {
qf_win_pos_update(qi, old_qfidx);
}
return OK;
}
/// Set quickfix/location list properties (title, items, context). /// Set quickfix/location list properties (title, items, context).
/// Also used to add items from parsing a list of lines. /// Also used to add items from parsing a list of lines.
/// Used by the setqflist() and setloclist() Vim script functions. /// Used by the setqflist() and setloclist() Vim script functions.
@@ -6169,6 +6213,9 @@ static int qf_set_properties(qf_info_T *qi, const dict_T *what, int action,
if ((di = tv_dict_find(what, S_LEN("context"))) != NULL) { if ((di = tv_dict_find(what, S_LEN("context"))) != NULL) {
retval = qf_setprop_context(qfl, di); retval = qf_setprop_context(qfl, di);
} }
if ((di = tv_dict_find(what, S_LEN("idx"))) != NULL) {
retval = qf_setprop_curidx(qi, qfl, di);
}
if (retval == OK) { if (retval == OK) {
qf_list_changed(qfl); qf_list_changed(qfl);

View File

@@ -1916,6 +1916,13 @@ func HistoryTest(cchar)
call g:Xsetlist([], 'f') call g:Xsetlist([], 'f')
let l = split(execute(a:cchar . 'hist'), "\n") let l = split(execute(a:cchar . 'hist'), "\n")
call assert_equal('No entries', l[0]) call assert_equal('No entries', l[0])
" An empty list should still show the stack history
call g:Xsetlist([])
let res = split(execute(a:cchar . 'hist'), "\n")
call assert_equal('> error list 1 of 1; 0 ' . common, res[0])
call g:Xsetlist([], 'f')
endfunc endfunc
func Test_history() func Test_history()
@@ -2173,6 +2180,56 @@ func Test_qf_property()
call Xproperty_tests('l') call Xproperty_tests('l')
endfunc endfunc
" Test for setting the current index in the location/quickfix list
func Xtest_setqfidx(cchar)
call s:setup_commands(a:cchar)
Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3"
Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3"
Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3"
call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2})
call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2})
call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3})
Xolder 2
Xopen
call assert_equal(3, line('.'))
Xnewer
call assert_equal(2, line('.'))
Xnewer
call assert_equal(2, line('.'))
" Update the current index with the quickfix window open
wincmd w
call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3})
Xopen
call assert_equal(3, line('.'))
Xclose
" Set the current index to the last entry
call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'})
call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
" A large value should set the index to the last index
call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1})
call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999})
call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
" Invalid index values
call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1})
call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0})
call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'})
call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:')
call g:Xsetlist([], 'f')
new | only
endfunc
func Test_setqfidx()
call Xtest_setqfidx('c')
call Xtest_setqfidx('l')
endfunc
" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands " Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
func QfAutoCmdHandler(loc, cmd) func QfAutoCmdHandler(loc, cmd)
call add(g:acmds, a:loc . a:cmd) call add(g:acmds, a:loc . a:cmd)