summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-09-29 12:50:17 +0100
committerBram Moolenaar <Bram@vim.org>2022-09-29 12:50:17 +0100
commit50faf02f43d7f1a56ec2023028fca7c72dbce83e (patch)
tree50ac366830d44eb27a8c7a183c6ae040f771468a
parent572a4433c8276d8e8f228a09f43b11afe0c85f6f (diff)
patch 9.0.0620: matchaddpos() can only add up to 8 matchesv9.0.0620
Problem: matchaddpos() can only add up to 8 matches. Solution: Allocate the array of positions. (closes #11248)
-rw-r--r--runtime/doc/builtin.txt2
-rw-r--r--src/drawscreen.c6
-rw-r--r--src/match.c243
-rw-r--r--src/structs.h47
-rw-r--r--src/testdir/dumps/Test_matchaddpos_1.dump14
-rw-r--r--src/testdir/test_match.vim15
-rw-r--r--src/version.c2
7 files changed, 184 insertions, 145 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index 80300113f2..81758aff4e 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -5918,8 +5918,6 @@ matchaddpos({group}, {pos} [, {priority} [, {id} [, {dict}]]])
- A list with three numbers, e.g., [23, 11, 3]. As above, but
the third number gives the length of the highlight in bytes.
- The maximum number of positions in {pos} is 8.
-
Returns -1 on error.
Example: >
diff --git a/src/drawscreen.c b/src/drawscreen.c
index 4e8ef4e876..47066995a5 100644
--- a/src/drawscreen.c
+++ b/src/drawscreen.c
@@ -1614,13 +1614,13 @@ win_update(win_T *wp)
while (cur != NULL)
{
- if (cur->match.regprog != NULL
- && re_multiline(cur->match.regprog))
+ if (cur->mit_match.regprog != NULL
+ && re_multiline(cur->mit_match.regprog))
{
top_to_mod = TRUE;
break;
}
- cur = cur->next;
+ cur = cur->mit_next;
}
}
#endif
diff --git a/src/match.c b/src/match.c
index ebdaeabcff..ecab28cef3 100644
--- a/src/match.c
+++ b/src/match.c
@@ -18,10 +18,12 @@
# define SEARCH_HL_PRIORITY 0
/*
- * Add match to the match list of window 'wp'. The pattern 'pat' will be
- * highlighted with the group 'grp' with priority 'prio'.
- * Optionally, a desired ID 'id' can be specified (greater than or equal to 1).
- * If no particular ID is desired, -1 must be specified for 'id'.
+ * Add match to the match list of window "wp".
+ * If "pat" is not NULL the pattern will be highlighted with the group "grp"
+ * with priority "prio".
+ * If "pos_list" is not NULL the list of posisions defines the highlights.
+ * Optionally, a desired ID "id" can be specified (greater than or equal to 1).
+ * If no particular ID is desired, -1 must be specified for "id".
* Return ID of added match, -1 on failure.
*/
static int
@@ -53,12 +55,12 @@ match_add(
cur = wp->w_match_head;
while (cur != NULL)
{
- if (cur->id == id)
+ if (cur->mit_id == id)
{
semsg(_(e_id_already_taken_nr), id);
return -1;
}
- cur = cur->next;
+ cur = cur->mit_next;
}
}
if ((hlg_id = syn_namen2id(grp, (int)STRLEN(grp))) == 0)
@@ -76,8 +78,8 @@ match_add(
while (id == -1)
{
cur = wp->w_match_head;
- while (cur != NULL && cur->id != wp->w_next_match_id)
- cur = cur->next;
+ 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++;
@@ -85,17 +87,29 @@ match_add(
// Build new match.
m = ALLOC_CLEAR_ONE(matchitem_T);
- m->id = id;
- m->priority = prio;
- m->pattern = pat == NULL ? NULL : vim_strsave(pat);
- m->hlg_id = hlg_id;
- m->match.regprog = regprog;
- m->match.rmm_ic = FALSE;
- m->match.rmm_maxcol = 0;
+ if (m == NULL)
+ return -1;
+ if (pos_list != NULL)
+ {
+ m->mit_pos_array = ALLOC_CLEAR_MULT(llpos_T, pos_list->lv_len);
+ if (m->mit_pos_array == NULL)
+ {
+ vim_free(m);
+ return -1;
+ }
+ m->mit_pos_count = pos_list->lv_len;
+ }
+ m->mit_id = id;
+ m->mit_priority = prio;
+ m->mit_pattern = pat == NULL ? NULL : vim_strsave(pat);
+ m->mit_hlg_id = hlg_id;
+ m->mit_match.regprog = regprog;
+ m->mit_match.rmm_ic = FALSE;
+ m->mit_match.rmm_maxcol = 0;
# if defined(FEAT_CONCEAL)
- m->conceal_char = 0;
+ m->mit_conceal_char = 0;
if (conceal_char != NULL)
- m->conceal_char = (*mb_ptr2char)(conceal_char);
+ m->mit_conceal_char = (*mb_ptr2char)(conceal_char);
# endif
// Set up position matches
@@ -107,8 +121,7 @@ match_add(
int i;
CHECK_LIST_MATERIALIZE(pos_list);
- for (i = 0, li = pos_list->lv_first; li != NULL && i < MAXPOSMATCH;
- i++, li = li->li_next)
+ for (i = 0, li = pos_list->lv_first; li != NULL; i++, li = li->li_next)
{
linenr_T lnum = 0;
colnr_T col = 0;
@@ -133,7 +146,7 @@ match_add(
--i;
continue;
}
- m->pos.pos[i].lnum = lnum;
+ m->mit_pos_array[i].lnum = lnum;
subli = subli->li_next;
if (subli != NULL)
{
@@ -148,8 +161,8 @@ match_add(
goto fail;
}
}
- m->pos.pos[i].col = col;
- m->pos.pos[i].len = len;
+ m->mit_pos_array[i].col = col;
+ m->mit_pos_array[i].len = len;
}
else if (li->li_tv.v_type == VAR_NUMBER)
{
@@ -158,9 +171,9 @@ match_add(
--i;
continue;
}
- m->pos.pos[i].lnum = li->li_tv.vval.v_number;
- m->pos.pos[i].col = 0;
- m->pos.pos[i].len = 0;
+ m->mit_pos_array[i].lnum = li->li_tv.vval.v_number;
+ m->mit_pos_array[i].col = 0;
+ m->mit_pos_array[i].len = 0;
}
else
{
@@ -190,8 +203,8 @@ match_add(
wp->w_buffer->b_mod_bot = botlnum;
wp->w_buffer->b_mod_xlines = 0;
}
- m->pos.toplnum = toplnum;
- m->pos.botlnum = botlnum;
+ m->mit_toplnum = toplnum;
+ m->mit_botlnum = botlnum;
rtype = UPD_VALID;
}
}
@@ -200,21 +213,23 @@ match_add(
// the match priorities.
cur = wp->w_match_head;
prev = cur;
- while (cur != NULL && prio >= cur->priority)
+ while (cur != NULL && prio >= cur->mit_priority)
{
prev = cur;
- cur = cur->next;
+ cur = cur->mit_next;
}
if (cur == prev)
wp->w_match_head = m;
else
- prev->next = m;
- m->next = cur;
+ prev->mit_next = m;
+ m->mit_next = cur;
redraw_win_later(wp, rtype);
return id;
fail:
+ vim_free(m->mit_pattern);
+ vim_free(m->mit_pos_array);
vim_free(m);
return -1;
}
@@ -233,13 +248,14 @@ match_delete(win_T *wp, int id, int perr)
if (id < 1)
{
if (perr == TRUE)
- semsg(_(e_invalid_id_nr_must_be_greater_than_or_equal_to_one_2), id);
+ semsg(_(e_invalid_id_nr_must_be_greater_than_or_equal_to_one_2),
+ id);
return -1;
}
- while (cur != NULL && cur->id != id)
+ while (cur != NULL && cur->mit_id != id)
{
prev = cur;
- cur = cur->next;
+ cur = cur->mit_next;
}
if (cur == NULL)
{
@@ -248,29 +264,30 @@ match_delete(win_T *wp, int id, int perr)
return -1;
}
if (cur == prev)
- wp->w_match_head = cur->next;
+ wp->w_match_head = cur->mit_next;
else
- prev->next = cur->next;
- vim_regfree(cur->match.regprog);
- vim_free(cur->pattern);
- if (cur->pos.toplnum != 0)
+ prev->mit_next = cur->mit_next;
+ vim_regfree(cur->mit_match.regprog);
+ vim_free(cur->mit_pattern);
+ if (cur->mit_toplnum != 0)
{
if (wp->w_buffer->b_mod_set)
{
- if (wp->w_buffer->b_mod_top > cur->pos.toplnum)
- wp->w_buffer->b_mod_top = cur->pos.toplnum;
- if (wp->w_buffer->b_mod_bot < cur->pos.botlnum)
- wp->w_buffer->b_mod_bot = cur->pos.botlnum;
+ if (wp->w_buffer->b_mod_top > cur->mit_toplnum)
+ wp->w_buffer->b_mod_top = cur->mit_toplnum;
+ if (wp->w_buffer->b_mod_bot < cur->mit_botlnum)
+ wp->w_buffer->b_mod_bot = cur->mit_botlnum;
}
else
{
wp->w_buffer->b_mod_set = TRUE;
- wp->w_buffer->b_mod_top = cur->pos.toplnum;
- wp->w_buffer->b_mod_bot = cur->pos.botlnum;
+ wp->w_buffer->b_mod_top = cur->mit_toplnum;
+ wp->w_buffer->b_mod_bot = cur->mit_botlnum;
wp->w_buffer->b_mod_xlines = 0;
}
rtype = UPD_VALID;
}
+ vim_free(cur->mit_pos_array);
vim_free(cur);
redraw_win_later(wp, rtype);
return 0;
@@ -286,9 +303,10 @@ clear_matches(win_T *wp)
while (wp->w_match_head != NULL)
{
- m = wp->w_match_head->next;
- vim_regfree(wp->w_match_head->match.regprog);
- vim_free(wp->w_match_head->pattern);
+ m = wp->w_match_head->mit_next;
+ vim_regfree(wp->w_match_head->mit_match.regprog);
+ vim_free(wp->w_match_head->mit_pattern);
+ vim_free(wp->w_match_head->mit_pos_array);
vim_free(wp->w_match_head);
wp->w_match_head = m;
}
@@ -304,8 +322,8 @@ get_match(win_T *wp, int id)
{
matchitem_T *cur = wp->w_match_head;
- while (cur != NULL && cur->id != id)
- cur = cur->next;
+ while (cur != NULL && cur->mit_id != id)
+ cur = cur->mit_next;
return cur;
}
@@ -322,15 +340,15 @@ init_search_hl(win_T *wp, match_T *search_hl)
cur = wp->w_match_head;
while (cur != NULL)
{
- cur->hl.rm = cur->match;
- if (cur->hlg_id == 0)
- cur->hl.attr = 0;
+ cur->mit_hl.rm = cur->mit_match;
+ if (cur->mit_hlg_id == 0)
+ cur->mit_hl.attr = 0;
else
- cur->hl.attr = syn_id2attr(cur->hlg_id);
- cur->hl.buf = wp->w_buffer;
- cur->hl.lnum = 0;
- cur->hl.first_lnum = 0;
- cur = cur->next;
+ cur->mit_hl.attr = syn_id2attr(cur->mit_hlg_id);
+ cur->mit_hl.buf = wp->w_buffer;
+ cur->mit_hl.lnum = 0;
+ cur->mit_hl.first_lnum = 0;
+ cur = cur->mit_next;
}
search_hl->buf = wp->w_buffer;
search_hl->lnum = 0;
@@ -346,15 +364,15 @@ init_search_hl(win_T *wp, match_T *search_hl)
next_search_hl_pos(
match_T *shl, // points to a match
linenr_T lnum,
- posmatch_T *posmatch, // match positions
+ matchitem_T *match, // match item with positions
colnr_T mincol) // minimal column for a match
{
int i;
int found = -1;
- for (i = posmatch->cur; i < MAXPOSMATCH; i++)
+ for (i = match->mit_pos_cur; i < match->mit_pos_count; i++)
{
- llpos_T *pos = &posmatch->pos[i];
+ llpos_T *pos = &match->mit_pos_array[i];
if (pos->lnum == 0)
break;
@@ -364,27 +382,26 @@ next_search_hl_pos(
{
if (found >= 0)
{
- // if this match comes before the one at "found" then swap
- // them
- if (pos->col < posmatch->pos[found].col)
+ // if this match comes before the one at "found" then swap them
+ if (pos->col < match->mit_pos_array[found].col)
{
llpos_T tmp = *pos;
- *pos = posmatch->pos[found];
- posmatch->pos[found] = tmp;
+ *pos = match->mit_pos_array[found];
+ match->mit_pos_array[found] = tmp;
}
}
else
found = i;
}
}
- posmatch->cur = 0;
+ match->mit_pos_cur = 0;
if (found >= 0)
{
- colnr_T start = posmatch->pos[found].col == 0
- ? 0 : posmatch->pos[found].col - 1;
- colnr_T end = posmatch->pos[found].col == 0
- ? MAXCOL : start + posmatch->pos[found].len;
+ colnr_T start = match->mit_pos_array[found].col == 0
+ ? 0 : match->mit_pos_array[found].col - 1;
+ colnr_T end = match->mit_pos_array[found].col == 0
+ ? MAXCOL : start + match->mit_pos_array[found].len;
shl->lnum = lnum;
shl->rm.startpos[0].lnum = 0;
@@ -393,7 +410,7 @@ next_search_hl_pos(
shl->rm.endpos[0].col = end;
shl->is_addpos = TRUE;
shl->has_cursor = FALSE;
- posmatch->cur = found + 1;
+ match->mit_pos_cur = found + 1;
return 1;
}
return 0;
@@ -479,16 +496,16 @@ next_search_hl(
if (shl->rm.regprog != NULL)
{
// Remember whether shl->rm is using a copy of the regprog in
- // cur->match.
+ // cur->mit_match.
int regprog_is_copy = (shl != search_hl && cur != NULL
- && shl == &cur->hl
- && cur->match.regprog == cur->hl.rm.regprog);
+ && shl == &cur->mit_hl
+ && cur->mit_match.regprog == cur->mit_hl.rm.regprog);
nmatched = vim_regexec_multi(&shl->rm, win, shl->buf, lnum,
matchcol, &timed_out);
// Copy the regprog, in case it got freed and recompiled.
if (regprog_is_copy)
- cur->match.regprog = cur->hl.rm.regprog;
+ cur->mit_match.regprog = cur->mit_hl.rm.regprog;
if (called_emsg > called_emsg_before || got_int || timed_out)
{
@@ -506,7 +523,7 @@ next_search_hl(
}
}
else if (cur != NULL)
- nmatched = next_search_hl_pos(shl, lnum, &(cur->pos), matchcol);
+ nmatched = next_search_hl_pos(shl, lnum, cur, matchcol);
else
nmatched = 0;
if (nmatched == 0)
@@ -552,7 +569,7 @@ prepare_search_hl(win_T *wp, match_T *search_hl, linenr_T lnum)
shl_flag = TRUE;
}
else
- shl = &cur->hl;
+ shl = &cur->mit_hl;
if (shl->rm.regprog != NULL
&& shl->lnum == 0
&& re_multiline(shl->rm.regprog))
@@ -570,7 +587,7 @@ prepare_search_hl(win_T *wp, match_T *search_hl, linenr_T lnum)
# endif
}
if (cur != NULL)
- cur->pos.cur = 0;
+ cur->mit_pos_cur = 0;
pos_inprogress = TRUE;
n = 0;
while (shl->first_lnum < lnum && (shl->rm.regprog != NULL
@@ -578,7 +595,7 @@ prepare_search_hl(win_T *wp, match_T *search_hl, linenr_T lnum)
{
next_search_hl(wp, search_hl, shl, shl->first_lnum, (colnr_T)n,
shl == search_hl ? NULL : cur);
- pos_inprogress = cur == NULL || cur->pos.cur == 0
+ pos_inprogress = cur == NULL || cur->mit_pos_cur == 0
? FALSE : TRUE;
if (shl->lnum != 0)
{
@@ -595,7 +612,7 @@ prepare_search_hl(win_T *wp, match_T *search_hl, linenr_T lnum)
}
}
if (shl != search_hl && cur != NULL)
- cur = cur->next;
+ cur = cur->mit_next;
}
}
@@ -652,14 +669,14 @@ prepare_search_hl_line(
shl_flag = TRUE;
}
else
- shl = &cur->hl;
+ shl = &cur->mit_hl;
shl->startcol = MAXCOL;
shl->endcol = MAXCOL;
shl->attr_cur = 0;
shl->is_addpos = FALSE;
shl->has_cursor = FALSE;
if (cur != NULL)
- cur->pos.cur = 0;
+ cur->mit_pos_cur = 0;
next_search_hl(wp, search_hl, shl, lnum, mincol,
shl == search_hl ? NULL : cur);
@@ -699,7 +716,7 @@ prepare_search_hl_line(
area_highlighting = TRUE;
}
if (shl != search_hl && cur != NULL)
- cur = cur->next;
+ cur = cur->mit_next;
}
return area_highlighting;
}
@@ -743,15 +760,15 @@ update_search_hl(
{
if (shl_flag == FALSE
&& (cur == NULL
- || cur->priority > SEARCH_HL_PRIORITY))
+ || cur->mit_priority > SEARCH_HL_PRIORITY))
{
shl = search_hl;
shl_flag = TRUE;
}
else
- shl = &cur->hl;
+ shl = &cur->mit_hl;
if (cur != NULL)
- cur->pos.cur = 0;
+ cur->mit_pos_cur = 0;
pos_inprogress = TRUE;
while (shl->rm.regprog != NULL || (cur != NULL && pos_inprogress))
{
@@ -769,10 +786,10 @@ update_search_hl(
// the match.
if (cur != NULL
&& shl != search_hl
- && syn_name2id((char_u *)"Conceal") == cur->hlg_id)
+ && syn_name2id((char_u *)"Conceal") == cur->mit_hlg_id)
{
*has_match_conc = col == shl->startcol ? 2 : 1;
- *match_conc = cur->conceal_char;
+ *match_conc = cur->mit_conceal_char;
}
else
*has_match_conc = 0;
@@ -792,7 +809,7 @@ update_search_hl(
shl->attr_cur = 0;
next_search_hl(wp, search_hl, shl, lnum, col,
shl == search_hl ? NULL : cur);
- pos_inprogress = !(cur == NULL || cur->pos.cur == 0);
+ pos_inprogress = !(cur == NULL || cur->mit_pos_cur == 0);
// Need to get the line again, a multi-line regexp may have
// made it invalid.
@@ -836,7 +853,7 @@ update_search_hl(
break;
}
if (shl != search_hl && cur != NULL)
- cur = cur->next;
+ cur = cur->mit_next;
}
// Use attributes from match with highest priority among 'search_hl' and
@@ -847,20 +864,20 @@ update_search_hl(
{
if (shl_flag == FALSE
&& (cur == NULL ||
- cur->priority > SEARCH_HL_PRIORITY))
+ cur->mit_priority > SEARCH_HL_PRIORITY))
{
shl = search_hl;
shl_flag = TRUE;
}
else
- shl = &cur->hl;
+ shl = &cur->mit_hl;
if (shl->attr_cur != 0)
{
search_attr = shl->attr_cur;
*on_last_col = col + 1 >= shl->endcol;
}
if (shl != search_hl && cur != NULL)
- cur = cur->next;
+ cur = cur->mit_next;
}
// Only highlight one character after the last column.
if (*(*line + col) == NUL && (did_line_attr >= 1
@@ -898,14 +915,14 @@ get_prevcol_hl_flag(win_T *wp, match_T *search_hl, long curcol)
cur = wp->w_match_head;
while (cur != NULL)
{
- if (!cur->hl.is_addpos && (prevcol == (long)cur->hl.startcol
- || (prevcol > (long)cur->hl.startcol
- && cur->hl.endcol == MAXCOL)))
+ if (!cur->mit_hl.is_addpos && (prevcol == (long)cur->mit_hl.startcol
+ || (prevcol > (long)cur->mit_hl.startcol
+ && cur->mit_hl.endcol == MAXCOL)))
{
prevcol_hl_flag = TRUE;
break;
}
- cur = cur->next;
+ cur = cur->mit_next;
}
}
return prevcol_hl_flag;
@@ -929,19 +946,19 @@ get_search_match_hl(win_T *wp, match_T *search_hl, long col, int *char_attr)
{
if (shl_flag == FALSE
&& ((cur != NULL
- && cur->priority > SEARCH_HL_PRIORITY)
+ && cur->mit_priority > SEARCH_HL_PRIORITY)
|| cur == NULL))
{
shl = search_hl;
shl_flag = TRUE;
}
else
- shl = &cur->hl;
+ shl = &cur->mit_hl;
if (col - 1 == (long)shl->startcol
&& (shl == search_hl || !shl->is_addpos))
*char_attr = shl->attr;
if (shl != search_hl && cur != NULL)
- cur = cur->next;
+ cur = cur->mit_next;
}
}
@@ -1020,16 +1037,16 @@ f_getmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
dict = dict_alloc();
if (dict == NULL)
return;
- if (cur->match.regprog == NULL)
+ if (cur->mit_match.regprog == NULL)
{
// match added with matchaddpos()
- for (i = 0; i < MAXPOSMATCH; ++i)
+ for (i = 0; i < cur->mit_pos_count; ++i)
{
llpos_T *llpos;
char buf[30]; // use 30 to avoid compiler warning
list_T *l;
- llpos = &cur->pos.pos[i];
+ llpos = &cur->mit_pos_array[i];
if (llpos->lnum == 0)
break;
l = list_alloc();
@@ -1047,22 +1064,22 @@ f_getmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
}
else
{
- dict_add_string(dict, "pattern", cur->pattern);
+ dict_add_string(dict, "pattern", cur->mit_pattern);
}
- dict_add_string(dict, "group", syn_id2name(cur->hlg_id));
- dict_add_number(dict, "priority", (long)cur->priority);
- dict_add_number(dict, "id", (long)cur->id);
+ dict_add_string(dict, "group", syn_id2name(cur->mit_hlg_id));
+ dict_add_number(dict, "priority", (long)cur->mit_priority);
+ dict_add_number(dict, "id", (long)cur->mit_id);
# if defined(FEAT_CONCEAL)
- if (cur->conceal_char)
+ if (cur->mit_conceal_char)
{
char_u buf[MB_MAXBYTES + 1];
- buf[(*mb_char2bytes)(cur->conceal_char, buf)] = NUL;
+ buf[(*mb_char2bytes)(cur->mit_conceal_char, buf)] = NUL;
dict_add_string(dict, "conceal", (char_u *)&buf);
}
# endif
list_append_dict(rettv->vval.v_list, dict);
- cur = cur->next;
+ cur = cur->mit_next;
}
# endif
}
@@ -1330,8 +1347,8 @@ f_matcharg(typval_T *argvars UNUSED, typval_T *rettv)
if ((m = get_match(curwin, id)) != NULL)
{
list_append_string(rettv->vval.v_list,
- syn_id2name(m->hlg_id), -1);
- list_append_string(rettv->vval.v_list, m->pattern, -1);
+ syn_id2name(m->mit_hlg_id), -1);
+ list_append_string(rettv->vval.v_list, m->mit_pattern, -1);
}
else
{
diff --git a/src/structs.h b/src/structs.h
index 31889f6ef6..27fb5bdf84 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -3424,9 +3424,6 @@ typedef struct
// CurSearch
} match_T;
-// number of positions supported by matchaddpos()
-#define MAXPOSMATCH 8
-
/*
* Same as lpos_T, but with additional field len.
*/
@@ -3438,35 +3435,31 @@ typedef struct
} llpos_T;
/*
- * posmatch_T provides an array for storing match items for matchaddpos()
- * function.
- */
-typedef struct posmatch posmatch_T;
-struct posmatch
-{
- llpos_T pos[MAXPOSMATCH]; // array of positions
- int cur; // internal position counter
- linenr_T toplnum; // top buffer line
- linenr_T botlnum; // bottom buffer line
-};
-
-/*
- * matchitem_T provides a linked list for storing match items for ":match" and
- * the match functions.
+ * matchitem_T provides a linked list for storing match items for ":match",
+ * matchadd() and matchaddpos().
*/
typedef struct matchitem matchitem_T;
struct matchitem
{
- matchitem_T *next;
- int id; // match ID
- int priority; // match priority
- char_u *pattern; // pattern to highlight
- regmmatch_T match; // regexp program for pattern
- posmatch_T pos; // position matches
- match_T hl; // struct for doing the actual highlighting
- int hlg_id; // highlight group ID
+ matchitem_T *mit_next;
+ int mit_id; // match ID
+ int mit_priority; // match priority
+
+ // Either a pattern is defined (mit_pattern is not NUL) or a list of
+ // positions is given (mit_pos is not NULL and mit_pos_count > 0).
+ char_u *mit_pattern; // pattern to highlight
+ regmmatch_T mit_match; // regexp program for pattern
+
+ llpos_T *mit_pos_array; // array of positions
+ int mit_pos_count; // nr of entries in mit_pos
+ int mit_pos_cur; // internal position counter
+ linenr_T mit_toplnum; // top buffer line
+ linenr_T mit_botlnum; // bottom buffer line
+
+ match_T mit_hl; // struct for doing the actual highlighting
+ int mit_hlg_id; // highlight group ID
#ifdef FEAT_CONCEAL
- int conceal_char; // cchar for Conceal highlighting
+ int mit_conceal_char; // cchar for Conceal highlighting
#endif
};
diff --git a/src/testdir/dumps/Test_matchaddpos_1.dump b/src/testdir/dumps/Test_matchaddpos_1.dump
new file mode 100644
index 0000000000..b282b2428b
--- /dev/null
+++ b/src/testdir/dumps/Test_matchaddpos_1.dump
@@ -0,0 +1,14 @@
+>1+0&#ffff4012|2+0&#ffffff0|3|4|5|6|7|8|9|0|1|2|3| @61
+|1|2+0&#ffff4012|3+0&#ffffff0|4|5|6|7|8|9|0|1|2|3| @61
+|1|2|3+0&#ffff4012|4+0&#ffffff0|5|6|7|8|9|0|1|2|3| @61
+|1|2|3|4+0&#ffff4012|5+0&#ffffff0|6|7|8|9|0|1|2|3| @61
+|1|2|3|4|5+0&#ffff4012|6+0&#ffffff0|7|8|9|0|1|2|3| @61
+|1|2|3|4|5|6+0&#ffff4012|7+0&#ffffff0|8|9|0|1|2|3| @61
+|1|2|3|4|5|6|7+0&#ffff4012|8+0&#ffffff0|9|0|1|2|3| @61
+|1|2|3|4|5|6|7|8+0&#ffff4012|9+0&#ffffff0|0|1|2|3| @61
+|1|2|3|4|5|6|7|8|9+0&#ffff4012|0+0&#ffffff0|1|2|3| @61
+|1|2|3|4|5|6|7|8|9|0+0&#ffff4012|1+0&#ffffff0|2|3| @61
+|1|2|3|4|5|6|7|8|9|0|1+0&#ffff4012|2+0&#ffffff0|3| @61
+|1|2|3|4|5|6|7|8|9|0|1|2+0&#ffff4012|3+0&#ffffff0| @61
+|1|2|3|4|5|6|7|8|9|0|1|2|3| @61
+@57|1|,|1| @10|T|o|p|
diff --git a/src/testdir/test_match.vim b/src/testdir/test_match.vim
index f654761d64..91e78a7682 100644
--- a/src/testdir/test_match.vim
+++ b/src/testdir/test_match.vim
@@ -219,6 +219,21 @@ func Test_matchaddpos()
set hlsearch&
endfunc
+" Add 12 match positions (previously the limit was 8 positions).
+func Test_matchaddpos_dump()
+ CheckScreendump
+
+ let lines =<< trim END
+ call setline(1, ['1234567890123']->repeat(14))
+ call matchaddpos('Search', range(1, 12)->map({i, v -> [v, v]}))
+ END
+ call writefile(lines, 'Xmatchaddpos', 'D')
+ let buf = RunVimInTerminal('-S Xmatchaddpos', #{rows: 14})
+ call VerifyScreenDump(buf, 'Test_matchaddpos_1', {})
+
+ call StopVimInTerminal(buf)
+endfunc
+
func Test_matchaddpos_otherwin()
syntax on
new
diff --git a/src/version.c b/src/version.c
index 276b37aced..e264b55ee8 100644
--- a/src/version.c
+++ b/src/version.c
@@ -700,6 +700,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 620,
+/**/
619,
/**/
618,