Patch 9.0.0620
Problem:    matchaddpos() can only add up to 8 matches.
Solution:   Allocate the array of positions. (closes #11248)
Files:      runtime/doc/builtin.txt, src/structs.h, src/match.c,
            src/drawscreen.c, src/testdir/test_match.vim,
            src/testdir/dumps/Test_matchaddpos_1.dump


*** ../vim-9.0.0619/runtime/doc/builtin.txt     2022-09-17 21:07:52.087993184 
+0100
--- runtime/doc/builtin.txt     2022-09-29 11:31:56.246439315 +0100
***************
*** 5908,5915 ****
                - 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: >
--- 5918,5923 ----
*** ../vim-9.0.0619/src/structs.h       2022-09-22 16:36:21.912930258 +0100
--- src/structs.h       2022-09-29 12:15:56.952524187 +0100
***************
*** 3424,3432 ****
                            // CurSearch
  } match_T;
  
- // number of positions supported by matchaddpos()
- #define MAXPOSMATCH 8
- 
  /*
   * Same as lpos_T, but with additional field len.
   */
--- 3424,3429 ----
***************
*** 3438,3472 ****
  } 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.
   */
  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
  #ifdef FEAT_CONCEAL
!     int               conceal_char; // cchar for Conceal highlighting
  #endif
  };
  
--- 3435,3465 ----
  } llpos_T;
  
  /*
!  * matchitem_T provides a linked list for storing match items for ":match",
!  * matchadd() and matchaddpos().
   */
  typedef struct matchitem matchitem_T;
  struct matchitem
  {
!     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               mit_conceal_char; // cchar for Conceal highlighting
  #endif
  };
  
*** ../vim-9.0.0619/src/match.c 2022-09-01 12:22:19.747659165 +0100
--- src/match.c 2022-09-29 12:46:56.309767449 +0100
***************
*** 18,27 ****
  # 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'.
   * Return ID of added match, -1 on failure.
   */
      static int
--- 18,29 ----
  # define SEARCH_HL_PRIORITY 0
  
  /*
!  * 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,64 ****
        cur = wp->w_match_head;
        while (cur != NULL)
        {
!           if (cur->id == id)
            {
                semsg(_(e_id_already_taken_nr), id);
                return -1;
            }
!           cur = cur->next;
        }
      }
      if ((hlg_id = syn_namen2id(grp, (int)STRLEN(grp))) == 0)
--- 55,66 ----
        cur = wp->w_match_head;
        while (cur != NULL)
        {
!           if (cur->mit_id == id)
            {
                semsg(_(e_id_already_taken_nr), id);
                return -1;
            }
!           cur = cur->mit_next;
        }
      }
      if ((hlg_id = syn_namen2id(grp, (int)STRLEN(grp))) == 0)
***************
*** 76,83 ****
      while (id == -1)
      {
        cur = wp->w_match_head;
!       while (cur != NULL && cur->id != wp->w_next_match_id)
!           cur = cur->next;
        if (cur == NULL)
            id = wp->w_next_match_id;
        wp->w_next_match_id++;
--- 78,85 ----
      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++;
***************
*** 85,101 ****
  
      // 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 defined(FEAT_CONCEAL)
!     m->conceal_char = 0;
      if (conceal_char != NULL)
!       m->conceal_char = (*mb_ptr2char)(conceal_char);
  # endif
  
      // Set up position matches
--- 87,115 ----
  
      // Build new match.
      m = ALLOC_CLEAR_ONE(matchitem_T);
!     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->mit_conceal_char = 0;
      if (conceal_char != NULL)
!       m->mit_conceal_char = (*mb_ptr2char)(conceal_char);
  # endif
  
      // Set up position matches
***************
*** 107,114 ****
        int             i;
  
        CHECK_LIST_MATERIALIZE(pos_list);
!       for (i = 0, li = pos_list->lv_first; li != NULL && i < MAXPOSMATCH;
!                                                       i++, li = li->li_next)
        {
            linenr_T    lnum = 0;
            colnr_T     col = 0;
--- 121,127 ----
        int             i;
  
        CHECK_LIST_MATERIALIZE(pos_list);
!       for (i = 0, li = pos_list->lv_first; li != NULL; i++, li = li->li_next)
        {
            linenr_T    lnum = 0;
            colnr_T     col = 0;
***************
*** 133,139 ****
                    --i;
                    continue;
                }
!               m->pos.pos[i].lnum = lnum;
                subli = subli->li_next;
                if (subli != NULL)
                {
--- 146,152 ----
                    --i;
                    continue;
                }
!               m->mit_pos_array[i].lnum = lnum;
                subli = subli->li_next;
                if (subli != NULL)
                {
***************
*** 148,155 ****
                            goto fail;
                    }
                }
!               m->pos.pos[i].col = col;
!               m->pos.pos[i].len = len;
            }
            else if (li->li_tv.v_type == VAR_NUMBER)
            {
--- 161,168 ----
                            goto fail;
                    }
                }
!               m->mit_pos_array[i].col = col;
!               m->mit_pos_array[i].len = len;
            }
            else if (li->li_tv.v_type == VAR_NUMBER)
            {
***************
*** 158,166 ****
                    --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;
            }
            else
            {
--- 171,179 ----
                    --i;
                    continue;
                }
!               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,197 ****
                wp->w_buffer->b_mod_bot = botlnum;
                wp->w_buffer->b_mod_xlines = 0;
            }
!           m->pos.toplnum = toplnum;
!           m->pos.botlnum = botlnum;
            rtype = UPD_VALID;
        }
      }
--- 203,210 ----
                wp->w_buffer->b_mod_bot = botlnum;
                wp->w_buffer->b_mod_xlines = 0;
            }
!           m->mit_toplnum = toplnum;
!           m->mit_botlnum = botlnum;
            rtype = UPD_VALID;
        }
      }
***************
*** 200,220 ****
      // the match priorities.
      cur = wp->w_match_head;
      prev = cur;
!     while (cur != NULL && prio >= cur->priority)
      {
        prev = cur;
!       cur = cur->next;
      }
      if (cur == prev)
        wp->w_match_head = m;
      else
!       prev->next = m;
!     m->next = cur;
  
      redraw_win_later(wp, rtype);
      return id;
  
  fail:
      vim_free(m);
      return -1;
  }
--- 213,235 ----
      // the match priorities.
      cur = wp->w_match_head;
      prev = cur;
!     while (cur != NULL && prio >= cur->mit_priority)
      {
        prev = cur;
!       cur = cur->mit_next;
      }
      if (cur == prev)
        wp->w_match_head = m;
      else
!       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,245 ****
      if (id < 1)
      {
        if (perr == TRUE)
!           semsg(_(e_invalid_id_nr_must_be_greater_than_or_equal_to_one_2), 
id);
        return -1;
      }
!     while (cur != NULL && cur->id != id)
      {
        prev = cur;
!       cur = cur->next;
      }
      if (cur == NULL)
      {
--- 248,261 ----
      if (id < 1)
      {
        if (perr == TRUE)
!           semsg(_(e_invalid_id_nr_must_be_greater_than_or_equal_to_one_2),
!                                                                          id);
        return -1;
      }
!     while (cur != NULL && cur->mit_id != id)
      {
        prev = cur;
!       cur = cur->mit_next;
      }
      if (cur == NULL)
      {
***************
*** 248,276 ****
        return -1;
      }
      if (cur == prev)
!       wp->w_match_head = cur->next;
      else
!       prev->next = cur->next;
!     vim_regfree(cur->match.regprog);
!     vim_free(cur->pattern);
!     if (cur->pos.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;
        }
        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_xlines = 0;
        }
        rtype = UPD_VALID;
      }
      vim_free(cur);
      redraw_win_later(wp, rtype);
      return 0;
--- 264,293 ----
        return -1;
      }
      if (cur == prev)
!       wp->w_match_head = cur->mit_next;
      else
!       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->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->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,294 ****
  
      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);
        vim_free(wp->w_match_head);
        wp->w_match_head = m;
      }
--- 303,312 ----
  
      while (wp->w_match_head != NULL)
      {
!       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,311 ****
  {
      matchitem_T *cur = wp->w_match_head;
  
!     while (cur != NULL && cur->id != id)
!       cur = cur->next;
      return cur;
  }
  
--- 322,329 ----
  {
      matchitem_T *cur = wp->w_match_head;
  
!     while (cur != NULL && cur->mit_id != id)
!       cur = cur->mit_next;
      return cur;
  }
  
***************
*** 322,336 ****
      cur = wp->w_match_head;
      while (cur != NULL)
      {
!       cur->hl.rm = cur->match;
!       if (cur->hlg_id == 0)
!           cur->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;
      }
      search_hl->buf = wp->w_buffer;
      search_hl->lnum = 0;
--- 340,354 ----
      cur = wp->w_match_head;
      while (cur != NULL)
      {
!       cur->mit_hl.rm = cur->mit_match;
!       if (cur->mit_hlg_id == 0)
!           cur->mit_hl.attr = 0;
        else
!           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,360 ****
  next_search_hl_pos(
      match_T       *shl,       // points to a match
      linenr_T      lnum,
!     posmatch_T            *posmatch,  // match positions
      colnr_T       mincol)     // minimal column for a match
  {
      int           i;
      int           found = -1;
  
!     for (i = posmatch->cur; i < MAXPOSMATCH; i++)
      {
!       llpos_T *pos = &posmatch->pos[i];
  
        if (pos->lnum == 0)
            break;
--- 364,378 ----
  next_search_hl_pos(
      match_T       *shl,       // points to a match
      linenr_T      lnum,
!     matchitem_T           *match,     // match item with positions
      colnr_T       mincol)     // minimal column for a match
  {
      int           i;
      int           found = -1;
  
!     for (i = match->mit_pos_cur; i < match->mit_pos_count; i++)
      {
!       llpos_T *pos = &match->mit_pos_array[i];
  
        if (pos->lnum == 0)
            break;
***************
*** 364,390 ****
        {
            if (found >= 0)
            {
!               // if this match comes before the one at "found" then swap
!               // them
!               if (pos->col < posmatch->pos[found].col)
                {
                    llpos_T     tmp = *pos;
  
!                   *pos = posmatch->pos[found];
!                   posmatch->pos[found] = tmp;
                }
            }
            else
                found = i;
        }
      }
!     posmatch->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;
  
        shl->lnum = lnum;
        shl->rm.startpos[0].lnum = 0;
--- 382,407 ----
        {
            if (found >= 0)
            {
!               // 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 = match->mit_pos_array[found];
!                   match->mit_pos_array[found] = tmp;
                }
            }
            else
                found = i;
        }
      }
!     match->mit_pos_cur = 0;
      if (found >= 0)
      {
!       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,399 ****
        shl->rm.endpos[0].col = end;
        shl->is_addpos = TRUE;
        shl->has_cursor = FALSE;
!       posmatch->cur = found + 1;
        return 1;
      }
      return 0;
--- 410,416 ----
        shl->rm.endpos[0].col = end;
        shl->is_addpos = TRUE;
        shl->has_cursor = FALSE;
!       match->mit_pos_cur = found + 1;
        return 1;
      }
      return 0;
***************
*** 479,494 ****
        if (shl->rm.regprog != NULL)
        {
            // Remember whether shl->rm is using a copy of the regprog in
!           // cur->match.
            int regprog_is_copy = (shl != search_hl && cur != NULL
!                               && shl == &cur->hl
!                               && cur->match.regprog == cur->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;
  
            if (called_emsg > called_emsg_before || got_int || timed_out)
            {
--- 496,511 ----
        if (shl->rm.regprog != NULL)
        {
            // Remember whether shl->rm is using a copy of the regprog in
!           // cur->mit_match.
            int regprog_is_copy = (shl != search_hl && cur != NULL
!                         && 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->mit_match.regprog = cur->mit_hl.rm.regprog;
  
            if (called_emsg > called_emsg_before || got_int || timed_out)
            {
***************
*** 506,512 ****
            }
        }
        else if (cur != NULL)
!           nmatched = next_search_hl_pos(shl, lnum, &(cur->pos), matchcol);
        else
            nmatched = 0;
        if (nmatched == 0)
--- 523,529 ----
            }
        }
        else if (cur != NULL)
!           nmatched = next_search_hl_pos(shl, lnum, cur, matchcol);
        else
            nmatched = 0;
        if (nmatched == 0)
***************
*** 552,558 ****
            shl_flag = TRUE;
        }
        else
!           shl = &cur->hl;
        if (shl->rm.regprog != NULL
                && shl->lnum == 0
                && re_multiline(shl->rm.regprog))
--- 569,575 ----
            shl_flag = TRUE;
        }
        else
!           shl = &cur->mit_hl;
        if (shl->rm.regprog != NULL
                && shl->lnum == 0
                && re_multiline(shl->rm.regprog))
***************
*** 570,576 ****
  # endif
            }
            if (cur != NULL)
!               cur->pos.cur = 0;
            pos_inprogress = TRUE;
            n = 0;
            while (shl->first_lnum < lnum && (shl->rm.regprog != NULL
--- 587,593 ----
  # endif
            }
            if (cur != NULL)
!               cur->mit_pos_cur = 0;
            pos_inprogress = TRUE;
            n = 0;
            while (shl->first_lnum < lnum && (shl->rm.regprog != NULL
***************
*** 578,584 ****
            {
                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
                                                              ? FALSE : TRUE;
                if (shl->lnum != 0)
                {
--- 595,601 ----
            {
                next_search_hl(wp, search_hl, shl, shl->first_lnum, (colnr_T)n,
                                               shl == search_hl ? NULL : cur);
!               pos_inprogress = cur == NULL || cur->mit_pos_cur == 0
                                                              ? FALSE : TRUE;
                if (shl->lnum != 0)
                {
***************
*** 595,601 ****
            }
        }
        if (shl != search_hl && cur != NULL)
!           cur = cur->next;
      }
  }
  
--- 612,618 ----
            }
        }
        if (shl != search_hl && cur != NULL)
!           cur = cur->mit_next;
      }
  }
  
***************
*** 652,665 ****
            shl_flag = TRUE;
        }
        else
!           shl = &cur->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;
        next_search_hl(wp, search_hl, shl, lnum, mincol,
                                                shl == search_hl ? NULL : cur);
  
--- 669,682 ----
            shl_flag = TRUE;
        }
        else
!           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->mit_pos_cur = 0;
        next_search_hl(wp, search_hl, shl, lnum, mincol,
                                                shl == search_hl ? NULL : cur);
  
***************
*** 699,705 ****
            area_highlighting = TRUE;
        }
        if (shl != search_hl && cur != NULL)
!           cur = cur->next;
      }
      return area_highlighting;
  }
--- 716,722 ----
            area_highlighting = TRUE;
        }
        if (shl != search_hl && cur != NULL)
!           cur = cur->mit_next;
      }
      return area_highlighting;
  }
***************
*** 743,757 ****
      {
        if (shl_flag == FALSE
                && (cur == NULL
!                       || cur->priority > SEARCH_HL_PRIORITY))
        {
            shl = search_hl;
            shl_flag = TRUE;
        }
        else
!           shl = &cur->hl;
        if (cur != NULL)
!           cur->pos.cur = 0;
        pos_inprogress = TRUE;
        while (shl->rm.regprog != NULL || (cur != NULL && pos_inprogress))
        {
--- 760,774 ----
      {
        if (shl_flag == FALSE
                && (cur == NULL
!                       || cur->mit_priority > SEARCH_HL_PRIORITY))
        {
            shl = search_hl;
            shl_flag = TRUE;
        }
        else
!           shl = &cur->mit_hl;
        if (cur != NULL)
!           cur->mit_pos_cur = 0;
        pos_inprogress = TRUE;
        while (shl->rm.regprog != NULL || (cur != NULL && pos_inprogress))
        {
***************
*** 769,778 ****
                // the match.
                if (cur != NULL
                        && shl != search_hl
!                       && syn_name2id((char_u *)"Conceal") == cur->hlg_id)
                {
                    *has_match_conc = col == shl->startcol ? 2 : 1;
!                   *match_conc = cur->conceal_char;
                }
                else
                    *has_match_conc = 0;
--- 786,795 ----
                // the match.
                if (cur != NULL
                        && shl != search_hl
!                       && syn_name2id((char_u *)"Conceal") == cur->mit_hlg_id)
                {
                    *has_match_conc = col == shl->startcol ? 2 : 1;
!                   *match_conc = cur->mit_conceal_char;
                }
                else
                    *has_match_conc = 0;
***************
*** 792,798 ****
                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);
  
                // Need to get the line again, a multi-line regexp may have
                // made it invalid.
--- 809,815 ----
                shl->attr_cur = 0;
                next_search_hl(wp, search_hl, shl, lnum, col,
                                               shl == search_hl ? NULL : cur);
!               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,842 ****
            break;
        }
        if (shl != search_hl && cur != NULL)
!           cur = cur->next;
      }
  
      // Use attributes from match with highest priority among 'search_hl' and
--- 853,859 ----
            break;
        }
        if (shl != search_hl && cur != NULL)
!           cur = cur->mit_next;
      }
  
      // Use attributes from match with highest priority among 'search_hl' and
***************
*** 847,866 ****
      {
        if (shl_flag == FALSE
                && (cur == NULL ||
!                       cur->priority > SEARCH_HL_PRIORITY))
        {
            shl = search_hl;
            shl_flag = TRUE;
        }
        else
!           shl = &cur->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;
      }
      // Only highlight one character after the last column.
      if (*(*line + col) == NUL && (did_line_attr >= 1
--- 864,883 ----
      {
        if (shl_flag == FALSE
                && (cur == NULL ||
!                       cur->mit_priority > SEARCH_HL_PRIORITY))
        {
            shl = search_hl;
            shl_flag = TRUE;
        }
        else
!           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->mit_next;
      }
      // Only highlight one character after the last column.
      if (*(*line + col) == NUL && (did_line_attr >= 1
***************
*** 898,911 ****
        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)))
            {
                prevcol_hl_flag = TRUE;
                break;
            }
!           cur = cur->next;
        }
      }
      return prevcol_hl_flag;
--- 915,928 ----
        cur = wp->w_match_head;
        while (cur != NULL)
        {
!           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->mit_next;
        }
      }
      return prevcol_hl_flag;
***************
*** 929,947 ****
      {
        if (shl_flag == FALSE
                && ((cur != NULL
!                       && cur->priority > SEARCH_HL_PRIORITY)
                    || cur == NULL))
        {
            shl = search_hl;
            shl_flag = TRUE;
        }
        else
!           shl = &cur->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;
      }
  }
  
--- 946,964 ----
      {
        if (shl_flag == FALSE
                && ((cur != NULL
!                       && cur->mit_priority > SEARCH_HL_PRIORITY)
                    || cur == NULL))
        {
            shl = search_hl;
            shl_flag = TRUE;
        }
        else
!           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->mit_next;
      }
  }
  
***************
*** 1020,1035 ****
        dict = dict_alloc();
        if (dict == NULL)
            return;
!       if (cur->match.regprog == NULL)
        {
            // match added with matchaddpos()
!           for (i = 0; i < MAXPOSMATCH; ++i)
            {
                llpos_T *llpos;
                char    buf[30];  // use 30 to avoid compiler warning
                list_T  *l;
  
!               llpos = &cur->pos.pos[i];
                if (llpos->lnum == 0)
                    break;
                l = list_alloc();
--- 1037,1052 ----
        dict = dict_alloc();
        if (dict == NULL)
            return;
!       if (cur->mit_match.regprog == NULL)
        {
            // match added with matchaddpos()
!           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->mit_pos_array[i];
                if (llpos->lnum == 0)
                    break;
                l = list_alloc();
***************
*** 1047,1068 ****
        }
        else
        {
!           dict_add_string(dict, "pattern", cur->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);
  #  if defined(FEAT_CONCEAL)
!       if (cur->conceal_char)
        {
            char_u buf[MB_MAXBYTES + 1];
  
!           buf[(*mb_char2bytes)(cur->conceal_char, buf)] = NUL;
            dict_add_string(dict, "conceal", (char_u *)&buf);
        }
  #  endif
        list_append_dict(rettv->vval.v_list, dict);
!       cur = cur->next;
      }
  # endif
  }
--- 1064,1085 ----
        }
        else
        {
!           dict_add_string(dict, "pattern", cur->mit_pattern);
        }
!       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->mit_conceal_char)
        {
            char_u buf[MB_MAXBYTES + 1];
  
!           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->mit_next;
      }
  # endif
  }
***************
*** 1330,1337 ****
            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);
            }
            else
            {
--- 1347,1354 ----
            if ((m = get_match(curwin, id)) != NULL)
            {
                list_append_string(rettv->vval.v_list,
!                                              syn_id2name(m->mit_hlg_id), -1);
!               list_append_string(rettv->vval.v_list, m->mit_pattern, -1);
            }
            else
            {
*** ../vim-9.0.0619/src/drawscreen.c    2022-08-31 14:46:07.903016994 +0100
--- src/drawscreen.c    2022-09-29 12:04:47.469066684 +0100
***************
*** 1614,1626 ****
  
                while (cur != NULL)
                {
!                   if (cur->match.regprog != NULL
!                                          && re_multiline(cur->match.regprog))
                    {
                        top_to_mod = TRUE;
                        break;
                    }
!                   cur = cur->next;
                }
            }
  #endif
--- 1614,1626 ----
  
                while (cur != NULL)
                {
!                   if (cur->mit_match.regprog != NULL
!                                      && re_multiline(cur->mit_match.regprog))
                    {
                        top_to_mod = TRUE;
                        break;
                    }
!                   cur = cur->mit_next;
                }
            }
  #endif
*** ../vim-9.0.0619/src/testdir/test_match.vim  2022-09-01 12:22:19.751659183 
+0100
--- src/testdir/test_match.vim  2022-09-29 12:42:53.942014030 +0100
***************
*** 219,224 ****
--- 219,239 ----
    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
*** ../vim-9.0.0619/src/testdir/dumps/Test_matchaddpos_1.dump   2022-09-29 
12:48:59.193650602 +0100
--- src/testdir/dumps/Test_matchaddpos_1.dump   2022-09-29 12:38:33.830314036 
+0100
***************
*** 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| 
*** ../vim-9.0.0619/src/version.c       2022-09-28 21:06:30.634345977 +0100
--- src/version.c       2022-09-29 12:40:11.274196145 +0100
***************
*** 701,702 ****
--- 701,704 ----
  {   /* Add new patch number below this line */
+ /**/
+     620,
  /**/

-- 
A scientist is someone who knows exactly how an engine works, but
can't fix his car when it fails to start.
An engineer is someone who knows only some things about an engine, but
can fix his car when it's broken.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20220929115048.C57F11C044A%40moolenaar.net.

Raspunde prin e-mail lui