diff options
-rw-r--r-- | runtime/doc/eval.txt | 32 | ||||
-rw-r--r-- | runtime/doc/quickfix.txt | 7 | ||||
-rw-r--r-- | src/nvim/quickfix.c | 65 | ||||
-rw-r--r-- | src/nvim/testdir/test_quickfix.vim | 57 |
4 files changed, 147 insertions, 14 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 0f848d0c27..5dbb24276f 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -3839,7 +3839,7 @@ feedkeys({string} [, {mode}]) *feedkeys()* stuck, waiting for a character to be typed before the script continues. 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. '!' When used with 'x' will not end Insert mode. Can be 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 window used to display files from the location list. This field is applicable only when called from a location list - window. + window. See |location-list-file-window| for more details. getmatches([{win}]) *getmatches()* 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 |quickfix-ID|; zero means the id for the 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 lines parse a list of lines using 'efm' and return 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 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() 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 @@ -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 linewise |o_V|) noCTRL-V Operator-pending (forced blockwise |o_CTRL-V|) + CTRL-V is one character niI Normal using |i_CTRL-O| in |Insert-mode| niR Normal using |i_CTRL-O| in |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 "lines". If this is not present, then the 'errorformat' option value is used. + See |quickfix-parse| 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} argument. lines use 'errorformat' to parse a list of lines and add the resulting entries to the quickfix list {nr} or {id}. Only a |List| value is supported. + See |quickfix-parse| nr list number in the quickfix stack; zero means the current quickfix list and "$" means - the last quickfix list - title quickfix list title text + the last quickfix list. + title quickfix list title text. See |quickfix-title| Unsupported keys in {what} are ignored. If the "nr" item is not present, then the current quickfix list is modified. When creating a new quickfix list, "nr" can be diff --git a/runtime/doc/quickfix.txt b/runtime/doc/quickfix.txt index 188cfc91b6..9da11a553d 100644 --- a/runtime/doc/quickfix.txt +++ b/runtime/doc/quickfix.txt @@ -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 location list instead of a quickfix list as the corresponding `:vimgrep`, `:grep`, `:helpgrep`, `:make` do. + *location-list-file-window* 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 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 :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* 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 :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 :call setqflist([], 'a', {'id' : qfid, 'context' : {'val' : 100}}) diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index da7e02ff54..fa7e0e9eef 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -2936,19 +2936,20 @@ static int qf_jump_to_buffer(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, return retval; } -/// Jump to a quickfix line. -/// 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". +/// Jump to a quickfix line and try to use an existing window. void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit) { 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. static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit, bool newwin) @@ -3297,7 +3298,7 @@ void qf_history(exarg_T *eap) qf_info_T *qi = qf_cmd_get_stack(eap, false); int i; - if (qf_stack_empty(qi) || qf_list_empty(qf_get_curlist(qi))) { + if (qf_stack_empty(qi)) { MSG(_("No entries")); } else { 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; } +// 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). /// Also used to add items from parsing a list of lines. /// 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) { 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) { qf_list_changed(qfl); diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim index 4e04ea161f..6f579920bf 100644 --- a/src/nvim/testdir/test_quickfix.vim +++ b/src/nvim/testdir/test_quickfix.vim @@ -1916,6 +1916,13 @@ func HistoryTest(cchar) call g:Xsetlist([], 'f') let l = split(execute(a:cchar . 'hist'), "\n") 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 func Test_history() @@ -2173,6 +2180,56 @@ func Test_qf_property() call Xproperty_tests('l') 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 func QfAutoCmdHandler(loc, cmd) call add(g:acmds, a:loc . a:cmd) |