To: vim_dev@googlegroups.com Subject: Patch 9.0.0620 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///