Skip to content

Commit b341459

Browse files
committed
updated for version 7.4.330
Problem: Using a regexp pattern to highlight a specific position can be slow. Solution: Add matchaddpos() to highlight specific positions efficiently. (Alexey Radkov)
1 parent ec1561c commit b341459

12 files changed

Lines changed: 462 additions & 85 deletions

File tree

runtime/doc/eval.txt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1887,6 +1887,8 @@ match( {expr}, {pat}[, {start}[, {count}]])
18871887
Number position where {pat} matches in {expr}
18881888
matchadd( {group}, {pattern}[, {priority}[, {id}]])
18891889
Number highlight {pattern} with {group}
1890+
matchaddpos( {group}, {list}[, {priority}[, {id}]])
1891+
Number highlight positions with {group}
18901892
matcharg( {nr}) List arguments of |:match|
18911893
matchdelete( {id}) Number delete match identified by {id}
18921894
matchend( {expr}, {pat}[, {start}[, {count}]])
@@ -4380,6 +4382,41 @@ matchadd({group}, {pattern}[, {priority}[, {id}]])
43804382
available from |getmatches()|. All matches can be deleted in
43814383
one operation by |clearmatches()|.
43824384

4385+
matchaddpos({group}, {pos}[, {priority}[, {id}]]) *matchaddpos()*
4386+
Same as |matchadd()|, but requires a list of positions {pos}
4387+
instead of a pattern. This command is faster than |matchadd()|
4388+
because it does not require to handle regular expressions and
4389+
sets buffer line boundaries to redraw screen. It is supposed
4390+
to be used when fast match additions and deletions are
4391+
required, for example to highlight matching parentheses.
4392+
4393+
The list {pos} can contain one of these items:
4394+
- A number. This while line will be highlighted. The first
4395+
line has number 1.
4396+
- A list with one number, e.g., [23]. The whole line with this
4397+
number will be highlighted.
4398+
- A list with two numbers, e.g., [23, 11]. The first number is
4399+
the line number, the second one the column number (first
4400+
column is 1). The character at this position will be
4401+
highlighted.
4402+
- A list with three numbers, e.g., [23, 11, 3]. As above, but
4403+
the third number gives the length of the highlight in screen
4404+
cells.
4405+
4406+
The maximum number of positions is 8.
4407+
4408+
Example: >
4409+
:highlight MyGroup ctermbg=green guibg=green
4410+
:let m = matchaddpos("MyGroup", [[23, 24], 34])
4411+
< Deletion of the pattern: >
4412+
:call matchdelete(m)
4413+
4414+
< Matches added by |matchaddpos()| are returned by
4415+
|getmatches()| with an entry "pos1", "pos2", etc., with the
4416+
value a list like the {pos} item.
4417+
These matches cannot be set via |setmatches()|, however they
4418+
can still be deleted by |clearmatches()|.
4419+
43834420
matcharg({nr}) *matcharg()*
43844421
Selects the {nr} match item, as set with a |:match|,
43854422
|:2match| or |:3match| command.

runtime/doc/usr_41.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,7 @@ Syntax and highlighting: *syntax-functions* *highlighting-functions*
827827
synconcealed() get info about concealing
828828
diff_hlID() get highlight ID for diff mode at a position
829829
matchadd() define a pattern to highlight (a "match")
830+
matchaddpos() define a list of positions to highlight
830831
matcharg() get info about |:match| arguments
831832
matchdelete() delete a match defined by |matchadd()| or a
832833
|:match| command

runtime/plugin/matchparen.vim

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
" Vim plugin for showing matching parens
22
" Maintainer: Bram Moolenaar <[email protected]>
3-
" Last Change: 2013 May 08
3+
" Last Change: 2014 Jun 17
44

55
" Exit quickly when:
66
" - this plugin was already loaded (or disabled)
@@ -39,7 +39,7 @@ set cpo-=C
3939
function! s:Highlight_Matching_Pair()
4040
" Remove any previous match.
4141
if exists('w:paren_hl_on') && w:paren_hl_on
42-
3match none
42+
silent! call matchdelete(3)
4343
let w:paren_hl_on = 0
4444
endif
4545

@@ -152,14 +152,18 @@ function! s:Highlight_Matching_Pair()
152152

153153
" If a match is found setup match highlighting.
154154
if m_lnum > 0 && m_lnum >= stoplinetop && m_lnum <= stoplinebottom
155-
exe '3match MatchParen /\(\%' . c_lnum . 'l\%' . (c_col - before) .
156-
\ 'c\)\|\(\%' . m_lnum . 'l\%' . m_col . 'c\)/'
155+
if exists('*matchaddpos')
156+
call matchaddpos('MatchParen', [[c_lnum, c_col - before], [m_lnum, m_col]], 10, 3)
157+
else
158+
exe '3match MatchParen /\(\%' . c_lnum . 'l\%' . (c_col - before) .
159+
\ 'c\)\|\(\%' . m_lnum . 'l\%' . m_col . 'c\)/'
160+
endif
157161
let w:paren_hl_on = 1
158162
endif
159163
endfunction
160164

161165
" Define commands that will disable and enable the plugin.
162-
command! NoMatchParen windo 3match none | unlet! g:loaded_matchparen |
166+
command! NoMatchParen windo silent! call matchdelete(3) | unlet! g:loaded_matchparen |
163167
\ au! matchparen
164168
command! DoMatchParen runtime plugin/matchparen.vim | windo doau CursorMoved
165169

src/eval.c

Lines changed: 85 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,7 @@ static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv));
622622
static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv));
623623
static void f_match __ARGS((typval_T *argvars, typval_T *rettv));
624624
static void f_matchadd __ARGS((typval_T *argvars, typval_T *rettv));
625+
static void f_matchaddpos __ARGS((typval_T *argvars, typval_T *rettv));
625626
static void f_matcharg __ARGS((typval_T *argvars, typval_T *rettv));
626627
static void f_matchdelete __ARGS((typval_T *argvars, typval_T *rettv));
627628
static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv));
@@ -8054,6 +8055,7 @@ static struct fst
80548055
{"mapcheck", 1, 3, f_mapcheck},
80558056
{"match", 2, 4, f_match},
80568057
{"matchadd", 2, 4, f_matchadd},
8058+
{"matchaddpos", 2, 4, f_matchaddpos},
80578059
{"matcharg", 1, 1, f_matcharg},
80588060
{"matchdelete", 1, 1, f_matchdelete},
80598061
{"matchend", 2, 4, f_matchend},
@@ -11767,6 +11769,7 @@ f_getmatches(argvars, rettv)
1176711769
#ifdef FEAT_SEARCH_EXTRA
1176811770
dict_T *dict;
1176911771
matchitem_T *cur = curwin->w_match_head;
11772+
int i;
1177011773

1177111774
if (rettv_list_alloc(rettv) == OK)
1177211775
{
@@ -11775,8 +11778,36 @@ f_getmatches(argvars, rettv)
1177511778
dict = dict_alloc();
1177611779
if (dict == NULL)
1177711780
return;
11781+
if (cur->match.regprog == NULL)
11782+
{
11783+
/* match added with matchaddpos() */
11784+
for (i = 0; i < MAXPOSMATCH; ++i)
11785+
{
11786+
llpos_T *llpos;
11787+
char buf[6];
11788+
list_T *l;
11789+
11790+
llpos = &cur->pos.pos[i];
11791+
if (llpos->lnum == 0)
11792+
break;
11793+
l = list_alloc();
11794+
if (l == NULL)
11795+
break;
11796+
list_append_number(l, (varnumber_T)llpos->lnum);
11797+
if (llpos->col > 0)
11798+
{
11799+
list_append_number(l, (varnumber_T)llpos->col);
11800+
list_append_number(l, (varnumber_T)llpos->len);
11801+
}
11802+
sprintf(buf, "pos%d", i + 1);
11803+
dict_add_list(dict, buf, l);
11804+
}
11805+
}
11806+
else
11807+
{
11808+
dict_add_nr_str(dict, "pattern", 0L, cur->pattern);
11809+
}
1177811810
dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id));
11779-
dict_add_nr_str(dict, "pattern", 0L, cur->pattern);
1178011811
dict_add_nr_str(dict, "priority", (long)cur->priority, NULL);
1178111812
dict_add_nr_str(dict, "id", (long)cur->id, NULL);
1178211813
list_append_dict(rettv->vval.v_list, dict);
@@ -14313,7 +14344,58 @@ f_matchadd(argvars, rettv)
1431314344
return;
1431414345
}
1431514346

14316-
rettv->vval.v_number = match_add(curwin, grp, pat, prio, id);
14347+
rettv->vval.v_number = match_add(curwin, grp, pat, prio, id, NULL);
14348+
#endif
14349+
}
14350+
14351+
/*
14352+
* "matchaddpos()" function
14353+
*/
14354+
static void
14355+
f_matchaddpos(argvars, rettv)
14356+
typval_T *argvars UNUSED;
14357+
typval_T *rettv UNUSED;
14358+
{
14359+
#ifdef FEAT_SEARCH_EXTRA
14360+
char_u buf[NUMBUFLEN];
14361+
char_u *group;
14362+
int prio = 10;
14363+
int id = -1;
14364+
int error = FALSE;
14365+
list_T *l;
14366+
14367+
rettv->vval.v_number = -1;
14368+
14369+
group = get_tv_string_buf_chk(&argvars[0], buf);
14370+
if (group == NULL)
14371+
return;
14372+
14373+
if (argvars[1].v_type != VAR_LIST)
14374+
{
14375+
EMSG2(_(e_listarg), "matchaddpos()");
14376+
return;
14377+
}
14378+
l = argvars[1].vval.v_list;
14379+
if (l == NULL)
14380+
return;
14381+
14382+
if (argvars[2].v_type != VAR_UNKNOWN)
14383+
{
14384+
prio = get_tv_number_chk(&argvars[2], &error);
14385+
if (argvars[3].v_type != VAR_UNKNOWN)
14386+
id = get_tv_number_chk(&argvars[3], &error);
14387+
}
14388+
if (error == TRUE)
14389+
return;
14390+
14391+
/* id == 3 is ok because matchaddpos() is supposed to substitute :3match */
14392+
if (id == 1 || id == 2)
14393+
{
14394+
EMSGN("E798: ID is reserved for \":match\": %ld", id);
14395+
return;
14396+
}
14397+
14398+
rettv->vval.v_number = match_add(curwin, group, NULL, prio, id, l);
1431714399
#endif
1431814400
}
1431914401

@@ -16816,7 +16898,7 @@ f_setmatches(argvars, rettv)
1681616898
match_add(curwin, get_dict_string(d, (char_u *)"group", FALSE),
1681716899
get_dict_string(d, (char_u *)"pattern", FALSE),
1681816900
(int)get_dict_number(d, (char_u *)"priority"),
16819-
(int)get_dict_number(d, (char_u *)"id"));
16901+
(int)get_dict_number(d, (char_u *)"id"), NULL);
1682016902
li = li->li_next;
1682116903
}
1682216904
rettv->vval.v_number = 0;

src/ex_docmd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11489,7 +11489,7 @@ ex_match(eap)
1148911489

1149011490
c = *end;
1149111491
*end = NUL;
11492-
match_add(curwin, g, p + 1, 10, id);
11492+
match_add(curwin, g, p + 1, 10, id, NULL);
1149311493
vim_free(g);
1149411494
*end = c;
1149511495
}

src/proto/window.pro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ void restore_win __ARGS((win_T *save_curwin, tabpage_T *save_curtab, int no_disp
7575
void switch_buffer __ARGS((buf_T **save_curbuf, buf_T *buf));
7676
void restore_buffer __ARGS((buf_T *save_curbuf));
7777
int win_hasvertsplit __ARGS((void));
78-
int match_add __ARGS((win_T *wp, char_u *grp, char_u *pat, int prio, int id));
78+
int match_add __ARGS((win_T *wp, char_u *grp, char_u *pat, int prio, int id, list_T *pos));
7979
int match_delete __ARGS((win_T *wp, int id, int perr));
8080
void clear_matches __ARGS((win_T *wp));
8181
matchitem_T *get_match __ARGS((win_T *wp, int id));

0 commit comments

Comments
 (0)