]> granicus.if.org Git - vim/commitdiff
patch 9.0.0620: matchaddpos() can only add up to 8 matches v9.0.0620
authorBram Moolenaar <Bram@vim.org>
Thu, 29 Sep 2022 11:50:17 +0000 (12:50 +0100)
committerBram Moolenaar <Bram@vim.org>
Thu, 29 Sep 2022 11:50:17 +0000 (12:50 +0100)
Problem:    matchaddpos() can only add up to 8 matches.
Solution:   Allocate the array of positions. (closes #11248)

runtime/doc/builtin.txt
src/drawscreen.c
src/match.c
src/structs.h
src/testdir/dumps/Test_matchaddpos_1.dump [new file with mode: 0644]
src/testdir/test_match.vim
src/version.c

index 80300113f22074c5ca318113cb1d5fb7db8a9656..81758aff4e60cd39a781683aafa5adc8925378af 100644 (file)
@@ -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: >
index 4e8ef4e876f96b9b0dc644e1607cf4fb08e4ed03..47066995a5f3681bc8d0ce90fe8c93148136ff58 100644 (file)
@@ -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
index ebdaeabcfff5d9fb180cf694404ab48213c53ee6..ecab28cef38645b0da311332c565871f77628eab 100644 (file)
 # 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
            {
index 31889f6ef64c5181a1005cba2ef861ef2811cfdf..27fb5bdf8447f566ef3bbd76248473fe80519bcb 100644 (file)
@@ -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 (file)
index 0000000..b282b24
--- /dev/null
@@ -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| 
index f654761d643a32fc11b06115e4f2ecca2dae26da..91e78a76827f92073a453945ae5085c14fa7384c 100644 (file)
@@ -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
index 276b37aced6c977ba11849ca3ba36a956bf9f1f7..e264b55ee8bcdc3216176804105331670d2725f7 100644 (file)
@@ -699,6 +699,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    620,
 /**/
     619,
 /**/