diff options
-rw-r--r-- | runtime/doc/eval.txt | 28 | ||||
-rw-r--r-- | src/nvim/eval.c | 3 | ||||
-rw-r--r-- | src/nvim/eval.lua | 8 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 53 | ||||
-rw-r--r-- | src/nvim/testdir/test_match.vim | 13 |
5 files changed, 80 insertions, 25 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 6f13b34876..1992c34102 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2059,7 +2059,7 @@ chanclose({id}[, {stream}]) Number Closes a channel or one of its streams chansend({id}, {data}) Number Writes {data} to channel char2nr({expr}[, {utf8}]) Number ASCII/UTF8 value of first char in {expr} cindent({lnum}) Number C indent for line {lnum} -clearmatches() none clear all matches +clearmatches([{win}]) none clear all matches col({expr}) Number column nr of cursor or mark complete({startcol}, {matches}) none set Insert mode completion complete_add({expr}) Number add completion match @@ -2167,7 +2167,7 @@ getjumplist([{winnr} [, {tabnr}]]) getline({lnum}) String line {lnum} of current buffer getline({lnum}, {end}) List lines {lnum} to {end} of current buffer getloclist({nr} [, {what}]) List list of location list items -getmatches() List list of current matches +getmatches([{win}]) List list of current matches getpid() Number process ID of Vim getpos({expr}) List position of cursor, mark, etc. getqflist([{what}]) List list of quickfix items @@ -2259,7 +2259,7 @@ matchadd({group}, {pattern}[, {priority}[, {id}]]) matchaddpos({group}, {list}[, {priority}[, {id}]]) Number highlight positions with {group} matcharg({nr}) List arguments of |:match| -matchdelete({id}) Number delete match identified by {id} +matchdelete({id} [, {win}]) Number delete match identified by {id} matchend({expr}, {pat}[, {start}[, {count}]]) Number position where {pat} ends in {expr} matchlist({expr}, {pat}[, {start}[, {count}]]) @@ -2352,7 +2352,7 @@ setfperm({fname}, {mode} Number set {fname} file permissions to {mode} setline({lnum}, {line}) Number set line {lnum} to {line} setloclist({nr}, {list}[, {action}[, {what}]]) Number modify location list using {list} -setmatches({list}) Number restore a list of matches +setmatches({list} [, {win}]) Number restore a list of matches setpos({expr}, {list}) Number set the {expr} position to {list} setqflist({list}[, {action}[, {what}]] Number modify quickfix list using {list} @@ -3005,9 +3005,11 @@ cindent({lnum}) *cindent()* When {lnum} is invalid -1 is returned. See |C-indenting|. -clearmatches() *clearmatches()* - Clears all matches previously defined for the current window - by |matchadd()| and the |:match| commands. +clearmatches([{win}]) *clearmatches()* + Clears all matches previously defined for the current window + by |matchadd()| and the |:match| commands. + If {win} is specified, use the window with this number or + window ID instead of the current window. *col()* col({expr}) The result is a Number, which is the byte index of the column @@ -4602,7 +4604,7 @@ getloclist({nr},[, {what}]) *getloclist()* field is applicable only when called from a location list window. -getmatches() *getmatches()* +getmatches([{win}]) *getmatches()* Returns a |List| with all matches previously defined for the current window by |matchadd()| and the |:match| commands. |getmatches()| is useful in combination with |setmatches()|, @@ -5943,7 +5945,7 @@ matchadd({group}, {pattern}[, {priority}[, {id} [, {dict}]]]) Defines a pattern to be highlighted in the current window (a "match"). It will be highlighted with {group}. Returns an identification number (ID), which can be used to delete the - match using |matchdelete()|. + match using |matchdelete()|. The ID is bound to the window. Matching is case sensitive and magic, unless case sensitivity or magicness are explicitly overridden in {pattern}. The 'magic', 'smartcase' and 'ignorecase' options are not used. @@ -6043,11 +6045,13 @@ matcharg({nr}) *matcharg()* Highlighting matches using the |:match| commands are limited to three matches. |matchadd()| does not have this limitation. -matchdelete({id}) *matchdelete()* *E802* *E803* +matchdelete({id} [, {win}) *matchdelete()* *E802* *E803* Deletes a match with ID {id} previously defined by |matchadd()| or one of the |:match| commands. Returns 0 if successful, otherwise -1. See example for |matchadd()|. All matches can be deleted in one operation by |clearmatches()|. + If {win} is specified, use the window with this number or + window ID instead of the current window. matchend({expr}, {pat} [, {start} [, {count}]]) *matchend()* Same as |match()|, but return the index of first character @@ -7420,11 +7424,13 @@ setloclist({nr}, {list}[, {action}[, {what}]]) *setloclist()* only the items listed in {what} are set. Refer to |setqflist()| for the list of supported keys in {what}. -setmatches({list}) *setmatches()* +setmatches({list} [, {win}]) *setmatches()* Restores a list of matches saved by |getmatches() for the current window|. Returns 0 if successful, otherwise -1. All current matches are cleared before the list is restored. See example for |getmatches()|. + If {win} is specified, use the window with this number or + window ID instead of the current window. *setpos()* setpos({expr}, {list}) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 4a0876a952..4acee7b453 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -63,6 +63,7 @@ static char *e_missbrac = N_("E111: Missing ']'"); static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary"); static char *e_illvar = N_("E461: Illegal variable name: %s"); static char *e_cannot_mod = N_("E995: Cannot modify existing variable"); +static char *e_invalwindow = N_("E957: Invalid window number"); // TODO(ZyX-I): move to eval/executor static char *e_letwrong = N_("E734: Wrong variable type for %s="); @@ -6776,7 +6777,7 @@ int matchadd_dict_arg(typval_T *tv, const char **conceal_char, if ((di = tv_dict_find(tv->vval.v_dict, S_LEN("window"))) != NULL) { *win = find_win_by_nr_or_id(&di->di_tv); if (*win == NULL) { - EMSG(_("E957: Invalid window number")); + EMSG(_(e_invalwindow)); return FAIL; } } diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 65c4cfe553..51872a7ba8 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -64,7 +64,7 @@ return { chansend={args=2}, char2nr={args={1, 2}}, cindent={args=1}, - clearmatches={}, + clearmatches={args={0, 1}}, col={args=1}, complete={args=2}, complete_add={args=1}, @@ -149,7 +149,7 @@ return { getjumplist={args={0, 2}}, getline={args={1, 2}}, getloclist={args={1, 2}}, - getmatches={}, + getmatches={args={0, 1}}, getpid={}, getpos={args=1}, getqflist={args={0, 1}}, @@ -227,7 +227,7 @@ return { matchadd={args={2, 5}}, matchaddpos={args={2, 5}}, matcharg={args=1}, - matchdelete={args=1}, + matchdelete={args={1, 2}}, matchend={args={2, 4}}, matchlist={args={2, 4}}, matchstr={args={2, 4}}, @@ -293,7 +293,7 @@ return { setfperm={args=2}, setline={args=2}, setloclist={args={2, 4}}, - setmatches={args=1}, + setmatches={args={1, 2}}, setpos={args=2}, setqflist={args={1, 3}}, setreg={args={2, 3}}, diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index c7df1d6753..8289f9515c 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -93,6 +93,7 @@ PRAGMA_DIAG_POP static char *e_listarg = N_("E686: Argument of %s must be a List"); static char *e_stringreq = N_("E928: String required"); +static char *e_invalwindow = N_("E957: Invalid window number"); /// Dummy va_list for passing to vim_snprintf /// @@ -952,12 +953,30 @@ static void f_cindent(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->vval.v_number = -1; } +static win_T * get_optional_window(typval_T *argvars, int idx) +{ + win_T *win = curwin; + + if (argvars[idx].v_type != VAR_UNKNOWN) { + win = find_win_by_nr_or_id(&argvars[idx]); + if (win == NULL) { + EMSG(_(e_invalwindow)); + return NULL; + } + } + return win; +} + /* * "clearmatches()" function */ static void f_clearmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - clear_matches(curwin); + win_T *win = get_optional_window(argvars, 0); + + if (win != NULL) { + clear_matches(win); + } } /* @@ -3452,10 +3471,16 @@ static void f_getloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - matchitem_T *cur = curwin->w_match_head; + matchitem_T *cur; int i; + win_T *win = get_optional_window(argvars, 0); + + if (win == NULL) { + return; + } tv_list_alloc_ret(rettv, kListLenMayKnow); + cur = win->w_match_head; while (cur != NULL) { dict_T *dict = tv_dict_alloc(); if (cur->match.regprog == NULL) { @@ -5771,8 +5796,13 @@ static void f_matcharg(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_matchdelete(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - rettv->vval.v_number = match_delete(curwin, - (int)tv_get_number(&argvars[0]), true); + win_T *win = get_optional_window(argvars, 1); + if (win == NULL) { + rettv->vval.v_number = -1; + } else { + rettv->vval.v_number = match_delete(curwin, + (int)tv_get_number(&argvars[0]), true); + } } /* @@ -8136,14 +8166,19 @@ static void f_setloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_setmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - dict_T *d; - list_T *s = NULL; + dict_T *d; + list_T *s = NULL; + win_T *win = get_optional_window(argvars, 1); rettv->vval.v_number = -1; if (argvars[0].v_type != VAR_LIST) { EMSG(_(e_listreq)); return; } + if (win == NULL) { + return; + } + list_T *const l = argvars[0].vval.v_list; // To some extent make sure that we are dealing with a list from // "getmatches()". @@ -8167,7 +8202,7 @@ static void f_setmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) li_idx++; }); - clear_matches(curwin); + clear_matches(win); bool match_add_failed = false; TV_LIST_ITER_CONST(l, li, { int i = 0; @@ -8213,13 +8248,13 @@ static void f_setmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) ? tv_get_string(&conceal_di->di_tv) : NULL); if (i == 0) { - if (match_add(curwin, group, + if (match_add(win, group, tv_dict_get_string(d, "pattern", false), priority, id, NULL, conceal) != id) { match_add_failed = true; } } else { - if (match_add(curwin, group, NULL, priority, id, s, conceal) != id) { + if (match_add(win, group, NULL, priority, id, s, conceal) != id) { match_add_failed = true; } tv_list_unref(s); diff --git a/src/nvim/testdir/test_match.vim b/src/nvim/testdir/test_match.vim index c134cfb1c0..7a1894bc16 100644 --- a/src/nvim/testdir/test_match.vim +++ b/src/nvim/testdir/test_match.vim @@ -217,6 +217,19 @@ func Test_matchaddpos_otherwin() call assert_equal(screenattr(1,2), screenattr(2,2)) call assert_notequal(screenattr(1,2), screenattr(1,4)) + let savematches = getmatches(winid) + let expect = [ + \ {'group': 'Search', 'pattern': '4', 'priority': 10, 'id': 4}, + \ {'group': 'Error', 'id': 5, 'priority': 10, 'pos1': [1, 2, 1], 'pos2': [2, 2, 1]}, + \] + call assert_equal(expect, savematches) + + call clearmatches(winid) + call assert_equal([], getmatches(winid)) + + call setmatches(savematches, winid) + call assert_equal(expect, savematches) + wincmd w bwipe! call clearmatches() |