mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 9.0.0622: matchaddpos() can get slow when adding many matches
Problem: matchaddpos() can get slow when adding many matches. Solution: Update the next available match ID when manually picking an ID and remove check if the available ID can be used. (idea by Rick Howe)
This commit is contained in:
parent
fc06cda837
commit
9f573a8df0
@ -5864,7 +5864,7 @@ matchadd({group}, {pattern} [, {priority} [, {id} [, {dict}]]])
|
|||||||
respectively. 3 is reserved for use by the |matchparen|
|
respectively. 3 is reserved for use by the |matchparen|
|
||||||
plugin.
|
plugin.
|
||||||
If the {id} argument is not specified or -1, |matchadd()|
|
If the {id} argument is not specified or -1, |matchadd()|
|
||||||
automatically chooses a free ID.
|
automatically chooses a free ID, which is at least 1000.
|
||||||
|
|
||||||
The optional {dict} argument allows for further custom
|
The optional {dict} argument allows for further custom
|
||||||
values. Currently this is used to specify a match specific
|
values. Currently this is used to specify a match specific
|
||||||
|
32
src/match.c
32
src/match.c
@ -50,19 +50,28 @@ match_add(
|
|||||||
semsg(_(e_invalid_id_nr_must_be_greater_than_or_equal_to_one_1), id);
|
semsg(_(e_invalid_id_nr_must_be_greater_than_or_equal_to_one_1), id);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (id != -1)
|
if (id == -1)
|
||||||
{
|
{
|
||||||
cur = wp->w_match_head;
|
// use the next available match ID
|
||||||
while (cur != NULL)
|
id = wp->w_next_match_id++;
|
||||||
{
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// check the given ID is not already in use
|
||||||
|
for (cur = wp->w_match_head; cur != NULL; cur = cur->mit_next)
|
||||||
if (cur->mit_id == id)
|
if (cur->mit_id == id)
|
||||||
{
|
{
|
||||||
semsg(_(e_id_already_taken_nr), id);
|
semsg(_(e_id_already_taken_nr), id);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cur = cur->mit_next;
|
|
||||||
}
|
// Make sure the next match ID is always higher than the highest
|
||||||
|
// manually selected ID. Add some extra in case a few more IDs are
|
||||||
|
// added soon.
|
||||||
|
if (wp->w_next_match_id < id + 100)
|
||||||
|
wp->w_next_match_id = id + 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((hlg_id = syn_namen2id(grp, (int)STRLEN(grp))) == 0)
|
if ((hlg_id = syn_namen2id(grp, (int)STRLEN(grp))) == 0)
|
||||||
{
|
{
|
||||||
semsg(_(e_no_such_highlight_group_name_str), grp);
|
semsg(_(e_no_such_highlight_group_name_str), grp);
|
||||||
@ -74,17 +83,6 @@ match_add(
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find available match ID.
|
|
||||||
while (id == -1)
|
|
||||||
{
|
|
||||||
cur = wp->w_match_head;
|
|
||||||
while (cur != NULL && cur->mit_id != wp->w_next_match_id)
|
|
||||||
cur = cur->mit_next;
|
|
||||||
if (cur == NULL)
|
|
||||||
id = wp->w_next_match_id;
|
|
||||||
wp->w_next_match_id++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build new match.
|
// Build new match.
|
||||||
m = ALLOC_CLEAR_ONE(matchitem_T);
|
m = ALLOC_CLEAR_ONE(matchitem_T);
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
|
@ -36,8 +36,8 @@ function Test_match()
|
|||||||
let m1 = matchadd("MyGroup1", "TODO")
|
let m1 = matchadd("MyGroup1", "TODO")
|
||||||
let m2 = matchadd("MyGroup2", "FIXME", 42)
|
let m2 = matchadd("MyGroup2", "FIXME", 42)
|
||||||
let m3 = matchadd("MyGroup3", "XXX", 60, 17)
|
let m3 = matchadd("MyGroup3", "XXX", 60, 17)
|
||||||
let ans = [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 4},
|
let ans = [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1000},
|
||||||
\ {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 42, 'id': 5},
|
\ {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 42, 'id': 1001},
|
||||||
\ {'group': 'MyGroup3', 'pattern': 'XXX', 'priority': 60, 'id': 17}]
|
\ {'group': 'MyGroup3', 'pattern': 'XXX', 'priority': 60, 'id': 17}]
|
||||||
call assert_equal(ans, getmatches())
|
call assert_equal(ans, getmatches())
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ function Test_match()
|
|||||||
call clearmatches()
|
call clearmatches()
|
||||||
|
|
||||||
call setline(1, 'abcdΣabcdef')
|
call setline(1, 'abcdΣabcdef')
|
||||||
eval "MyGroup1"->matchaddpos([[1, 4, 2], [1, 9, 2]])
|
eval "MyGroup1"->matchaddpos([[1, 4, 2], [1, 9, 2]], 10, 42)
|
||||||
1
|
1
|
||||||
redraw!
|
redraw!
|
||||||
let v1 = screenattr(1, 1)
|
let v1 = screenattr(1, 1)
|
||||||
@ -130,7 +130,7 @@ function Test_match()
|
|||||||
let v8 = screenattr(1, 8)
|
let v8 = screenattr(1, 8)
|
||||||
let v9 = screenattr(1, 9)
|
let v9 = screenattr(1, 9)
|
||||||
let v10 = screenattr(1, 10)
|
let v10 = screenattr(1, 10)
|
||||||
call assert_equal([{'group': 'MyGroup1', 'id': 11, 'priority': 10, 'pos1': [1, 4, 2], 'pos2': [1, 9, 2]}], getmatches())
|
call assert_equal([{'group': 'MyGroup1', 'id': 42, 'priority': 10, 'pos1': [1, 4, 2], 'pos2': [1, 9, 2]}], getmatches())
|
||||||
call assert_notequal(v1, v4)
|
call assert_notequal(v1, v4)
|
||||||
call assert_equal(v5, v4)
|
call assert_equal(v5, v4)
|
||||||
call assert_equal(v6, v1)
|
call assert_equal(v6, v1)
|
||||||
@ -144,7 +144,7 @@ function Test_match()
|
|||||||
let m=getmatches()
|
let m=getmatches()
|
||||||
call clearmatches()
|
call clearmatches()
|
||||||
call setmatches(m)
|
call setmatches(m)
|
||||||
call assert_equal([{'group': 'MyGroup1', 'id': 11, 'priority': 10, 'pos1': [1, 4, 2], 'pos2': [1,9, 2]}, {'group': 'MyGroup1', 'pattern': '\%2lmatchadd', 'priority': 10, 'id': 12}], getmatches())
|
call assert_equal([{'group': 'MyGroup1', 'id': 42, 'priority': 10, 'pos1': [1, 4, 2], 'pos2': [1,9, 2]}, {'group': 'MyGroup1', 'pattern': '\%2lmatchadd', 'priority': 10, 'id': 1106}], getmatches())
|
||||||
|
|
||||||
highlight MyGroup1 NONE
|
highlight MyGroup1 NONE
|
||||||
highlight MyGroup2 NONE
|
highlight MyGroup2 NONE
|
||||||
@ -252,8 +252,8 @@ func Test_matchaddpos_otherwin()
|
|||||||
|
|
||||||
let savematches = getmatches(winid)
|
let savematches = getmatches(winid)
|
||||||
let expect = [
|
let expect = [
|
||||||
\ {'group': 'Search', 'pattern': '4', 'priority': 10, 'id': 4},
|
\ {'group': 'Search', 'pattern': '4', 'priority': 10, 'id': 1000},
|
||||||
\ {'group': 'Error', 'id': 5, 'priority': 10, 'pos1': [1, 2, 1], 'pos2': [2, 2, 1]},
|
\ {'group': 'Error', 'id': 1001, 'priority': 10, 'pos1': [1, 2, 1], 'pos2': [2, 2, 1]},
|
||||||
\]
|
\]
|
||||||
call assert_equal(expect, savematches)
|
call assert_equal(expect, savematches)
|
||||||
|
|
||||||
|
@ -699,6 +699,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
622,
|
||||||
/**/
|
/**/
|
||||||
621,
|
621,
|
||||||
/**/
|
/**/
|
||||||
|
@ -5143,8 +5143,7 @@ win_alloc(win_T *after UNUSED, int hidden UNUSED)
|
|||||||
#endif
|
#endif
|
||||||
unblock_autocmds();
|
unblock_autocmds();
|
||||||
#ifdef FEAT_SEARCH_EXTRA
|
#ifdef FEAT_SEARCH_EXTRA
|
||||||
new_wp->w_match_head = NULL;
|
new_wp->w_next_match_id = 1000; // up to 1000 can be picked by the user
|
||||||
new_wp->w_next_match_id = 4;
|
|
||||||
#endif
|
#endif
|
||||||
return new_wp;
|
return new_wp;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user