diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/buffer_defs.h | 44 | ||||
-rw-r--r-- | src/nvim/drawscreen.c | 6 | ||||
-rw-r--r-- | src/nvim/match.c | 274 | ||||
-rw-r--r-- | src/nvim/testdir/test_match.vim | 32 | ||||
-rw-r--r-- | src/nvim/window.c | 3 |
5 files changed, 185 insertions, 174 deletions
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index a8834b85aa..1212dffcec 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -984,9 +984,6 @@ typedef struct { proftime_T tm; // for a time limit } match_T; -/// number of positions supported by matchaddpos() -#define MAXPOSMATCH 8 - /// Same as lpos_T, but with additional field len. typedef struct { linenr_T lnum; ///< line number @@ -994,29 +991,28 @@ typedef struct { int len; ///< length: 0 - to the end of line } 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 *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 - int conceal_char; ///< cchar for Conceal highlighting + 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 *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 + int mit_conceal_char; ///< cchar for Conceal highlighting }; typedef int FloatAnchor; diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index fdf70a081c..e2bf3ed60d 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -1126,12 +1126,12 @@ win_update_start: } else { const matchitem_T *cur = wp->w_match_head; 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; } } } diff --git a/src/nvim/match.c b/src/nvim/match.c index f41eab889b..b422dc0ba8 100644 --- a/src/nvim/match.c +++ b/src/nvim/match.c @@ -29,13 +29,13 @@ static char *e_invalwindow = N_("E957: Invalid window number"); #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). +/// 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". /// -/// @param[in] id a desired ID 'id' can be specified -/// (greater than or equal to 1). -1 must be specified if no -/// particular ID is desired /// @param[in] conceal_char pointer to conceal replacement char /// @return ID of added match, -1 on failure. static int match_add(win_T *wp, const char *const grp, const char *const pat, int prio, int id, @@ -58,16 +58,26 @@ static int match_add(win_T *wp, const char *const grp, const char *const pat, in (int64_t)id); return -1; } - if (id != -1) { - cur = wp->w_match_head; - while (cur != NULL) { - if (cur->id == id) { + if (id == -1) { + // use the next available match ID + id = wp->w_next_match_id++; + } else { + // check the given ID is not already in use + for (cur = wp->w_match_head; cur != NULL; cur = cur->mit_next) { + if (cur->mit_id == id) { semsg(_("E801: ID already taken: %" PRId64), (int64_t)id); return -1; } - cur = cur->next; + } + + // Make sure the next match ID is always higher than the highest + // manually selected ID. Add some extra in case a few more IDs are + // added soon. + if (wp->w_next_match_id < id + 100) { + wp->w_next_match_id = id + 100; } } + if ((hlg_id = syn_check_group(grp, strlen(grp))) == 0) { return -1; } @@ -76,30 +86,22 @@ static int match_add(win_T *wp, const char *const grp, const char *const pat, in return -1; } - // Find available match ID. - 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++; - } - // Build new match. m = xcalloc(1, sizeof(matchitem_T)); - m->id = id; - m->priority = prio; - m->pattern = pat == NULL ? NULL: xstrdup(pat); - m->hlg_id = hlg_id; - m->match.regprog = regprog; - m->match.rmm_ic = false; - m->match.rmm_maxcol = 0; - m->conceal_char = 0; + if (pos_list != NULL) { + m->mit_pos_array = xcalloc((size_t)tv_list_len(pos_list), sizeof(llpos_T)); + m->mit_pos_count = tv_list_len(pos_list); + } + m->mit_id = id; + m->mit_priority = prio; + m->mit_pattern = pat == NULL ? NULL: xstrdup(pat); + m->mit_hlg_id = hlg_id; + m->mit_match.regprog = regprog; + m->mit_match.rmm_ic = false; + m->mit_match.rmm_maxcol = 0; + m->mit_conceal_char = 0; if (conceal_char != NULL) { - m->conceal_char = utf_ptr2char(conceal_char); + m->mit_conceal_char = utf_ptr2char(conceal_char); } // Set up position matches @@ -129,7 +131,7 @@ static int match_add(win_T *wp, const char *const grp, const char *const pat, in if (lnum <= 0) { continue; } - m->pos.pos[i].lnum = lnum; + m->mit_pos_array[i].lnum = lnum; subli = TV_LIST_ITEM_NEXT(subl, subli); if (subli != NULL) { col = (colnr_T)tv_get_number_chk(TV_LIST_ITEM_TV(subli), &error); @@ -150,15 +152,15 @@ static int match_add(win_T *wp, const char *const grp, const char *const pat, in } } } - 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 (TV_LIST_ITEM_TV(li)->v_type == VAR_NUMBER) { if (TV_LIST_ITEM_TV(li)->vval.v_number <= 0) { continue; } - m->pos.pos[i].lnum = (linenr_T)TV_LIST_ITEM_TV(li)->vval.v_number; - m->pos.pos[i].col = 0; - m->pos.pos[i].len = 0; + m->mit_pos_array[i].lnum = (linenr_T)TV_LIST_ITEM_TV(li)->vval.v_number; + m->mit_pos_array[i].col = 0; + m->mit_pos_array[i].len = 0; } else { semsg(_("E5031: List or number required at position %d"), (int)tv_list_idx_of_item(pos_list, li)); @@ -171,9 +173,6 @@ static int match_add(win_T *wp, const char *const grp, const char *const pat, in botlnum = lnum + 1; } i++; - if (i >= MAXPOSMATCH) { - break; - } }); // Calculate top and bottom lines for redrawing area @@ -191,8 +190,8 @@ static int match_add(win_T *wp, const char *const grp, const char *const pat, in 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; } } @@ -201,21 +200,23 @@ static int match_add(win_T *wp, const char *const grp, const char *const pat, in // 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; + prev->mit_next = m; } - m->next = cur; + m->mit_next = cur; redraw_later(wp, rtype); return id; fail: + xfree(m->mit_pattern); + xfree(m->mit_pos_array); xfree(m); return -1; } @@ -231,15 +232,14 @@ static int match_delete(win_T *wp, int id, bool perr) if (id < 1) { if (perr) { - semsg(_("E802: Invalid ID: %" PRId64 - " (must be greater than or equal to 1)"), + semsg(_("E802: Invalid ID: %" PRId64 " (must be greater than or equal to 1)"), (int64_t)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) { if (perr) { @@ -248,28 +248,29 @@ static int match_delete(win_T *wp, int id, bool perr) return -1; } if (cur == prev) { - wp->w_match_head = cur->next; + wp->w_match_head = cur->mit_next; } else { - prev->next = cur->next; + prev->mit_next = cur->mit_next; } - vim_regfree(cur->match.regprog); - xfree(cur->pattern); - if (cur->pos.toplnum != 0) { + vim_regfree(cur->mit_match.regprog); + xfree(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_top > cur->mit_toplnum) { + wp->w_buffer->b_mod_top = cur->mit_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_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; } + xfree(cur->mit_pos_array); xfree(cur); redraw_later(wp, rtype); return 0; @@ -281,9 +282,10 @@ void clear_matches(win_T *wp) matchitem_T *m; while (wp->w_match_head != NULL) { - m = wp->w_match_head->next; - vim_regfree(wp->w_match_head->match.regprog); - xfree(wp->w_match_head->pattern); + m = wp->w_match_head->mit_next; + vim_regfree(wp->w_match_head->mit_match.regprog); + xfree(wp->w_match_head->mit_pattern); + xfree(wp->w_match_head->mit_pos_array); xfree(wp->w_match_head); wp->w_match_head = m; } @@ -292,12 +294,12 @@ void clear_matches(win_T *wp) /// Get match from ID 'id' in window 'wp'. /// Return NULL if match not found. -matchitem_T *get_match(win_T *wp, int id) +static matchitem_T *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; } @@ -310,18 +312,18 @@ void init_search_hl(win_T *wp, match_T *search_hl) // match matchitem_T *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->mit_hl.attr = syn_id2attr(cur->mit_hlg_id); } - cur->hl.buf = wp->w_buffer; - cur->hl.lnum = 0; - cur->hl.first_lnum = 0; + cur->mit_hl.buf = wp->w_buffer; + cur->mit_hl.lnum = 0; + cur->mit_hl.first_lnum = 0; // Set the time limit to 'redrawtime'. - cur->hl.tm = profile_setlimit(p_rdt); - cur = cur->next; + cur->mit_hl.tm = profile_setlimit(p_rdt); + cur = cur->mit_next; } search_hl->buf = wp->w_buffer; search_hl->lnum = 0; @@ -332,19 +334,19 @@ void init_search_hl(win_T *wp, match_T *search_hl) } /// @param shl points to a match. Fill on match. -/// @param posmatch match positions +/// @param posmatch match item with positions /// @param mincol minimal column for a match /// /// @return one on match, otherwise return zero. -static int next_search_hl_pos(match_T *shl, linenr_T lnum, posmatch_T *posmatch, colnr_T mincol) +static int next_search_hl_pos(match_T *shl, linenr_T lnum, matchitem_T *match, colnr_T mincol) FUNC_ATTR_NONNULL_ALL { int i; int found = -1; shl->lnum = 0; - for (i = posmatch->cur; i < MAXPOSMATCH; i++) { - llpos_T *pos = &posmatch->pos[i]; + 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; @@ -354,25 +356,24 @@ static int next_search_hl_pos(match_T *shl, linenr_T lnum, posmatch_T *posmatch, } if (pos->lnum == lnum) { 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; @@ -381,7 +382,7 @@ static int next_search_hl_pos(match_T *shl, linenr_T lnum, posmatch_T *posmatch, 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; @@ -460,18 +461,17 @@ static void next_search_hl(win_T *win, match_T *search_hl, match_T *shl, linenr_ shl->lnum = lnum; if (shl->rm.regprog != NULL) { // Remember whether shl->rm is using a copy of the regprog in - // cur->match. - bool regprog_is_copy = (shl != search_hl - && cur != NULL - && shl == &cur->hl - && cur->match.regprog == cur->hl.rm.regprog); + // cur->mit_match. + bool regprog_is_copy = (shl != search_hl && cur != NULL + && shl == &cur->mit_hl + && cur->mit_match.regprog == cur->mit_hl.rm.regprog); int timed_out = false; nmatched = vim_regexec_multi(&shl->rm, win, shl->buf, lnum, matchcol, &(shl->tm), &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) { // Error while handling regexp: stop using this regexp. @@ -486,7 +486,7 @@ static void next_search_hl(win_T *win, match_T *search_hl, match_T *shl, linenr_ break; } } else if (cur != NULL) { - nmatched = next_search_hl_pos(shl, lnum, &(cur->pos), matchcol); + nmatched = next_search_hl_pos(shl, lnum, cur, matchcol); } if (nmatched == 0) { shl->lnum = 0; // no match found @@ -521,7 +521,7 @@ void prepare_search_hl(win_T *wp, match_T *search_hl, linenr_T lnum) shl = search_hl; shl_flag = true; } else { - shl = &cur->hl; // -V595 + shl = &cur->mit_hl; // -V595 } if (shl->rm.regprog != NULL && shl->lnum == 0 @@ -536,7 +536,7 @@ void prepare_search_hl(win_T *wp, match_T *search_hl, linenr_T lnum) } } if (cur != NULL) { - cur->pos.cur = 0; + cur->mit_pos_cur = 0; } bool pos_inprogress = true; // mark that a position match search is // in progress @@ -545,7 +545,7 @@ void prepare_search_hl(win_T *wp, match_T *search_hl, linenr_T lnum) || (cur != NULL && pos_inprogress))) { 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); if (shl->lnum != 0) { shl->first_lnum = shl->lnum + shl->rm.endpos[0].lnum @@ -558,7 +558,7 @@ void 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; } } } @@ -598,7 +598,7 @@ bool prepare_search_hl_line(win_T *wp, linenr_T lnum, colnr_T mincol, char_u **l shl = search_hl; shl_flag = true; } else { - shl = &cur->hl; // -V595 + shl = &cur->mit_hl; // -V595 } shl->startcol = MAXCOL; shl->endcol = MAXCOL; @@ -606,7 +606,7 @@ bool prepare_search_hl_line(win_T *wp, linenr_T lnum, colnr_T mincol, char_u **l 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); @@ -649,7 +649,7 @@ bool prepare_search_hl_line(win_T *wp, linenr_T lnum, colnr_T mincol, char_u **l area_highlighting = true; } if (shl != search_hl && cur != NULL) { - cur = cur->next; + cur = cur->mit_next; } } return area_highlighting; @@ -674,14 +674,14 @@ int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char_u **line, match // Do this for 'search_hl' and the match list (ordered by priority). while (cur != NULL || !shl_flag) { if (!shl_flag - && (cur == NULL || cur->priority > SEARCH_HL_PRIORITY)) { + && (cur == NULL || 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; } bool pos_inprogress = true; // mark that a position match search is // in progress @@ -706,9 +706,9 @@ int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char_u **line, match // the match. if (cur != NULL && shl != search_hl - && syn_name2id("Conceal") == cur->hlg_id) { + && syn_name2id("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; } @@ -717,7 +717,7 @@ int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char_u **line, match 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. @@ -755,30 +755,30 @@ int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char_u **line, match 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 the match list. + // Use attributes from match with highest priority among 'search_hl' and + // the match list. *search_attr_from_match = false; search_attr = search_hl->attr_cur; cur = wp->w_match_head; shl_flag = false; while (cur != NULL || !shl_flag) { if (!shl_flag - && (cur == NULL || cur->priority > SEARCH_HL_PRIORITY)) { + && (cur == NULL || 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; *search_attr_from_match = shl != search_hl; } if (shl != search_hl && cur != NULL) { - cur = cur->next; + cur = cur->mit_next; } } // Only highlight one character after the last column. @@ -808,12 +808,12 @@ bool get_prevcol_hl_flag(win_T *wp, match_T *search_hl, long curcol) } else { 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))) { return true; } - cur = cur->next; + cur = cur->mit_next; } } return false; @@ -830,18 +830,18 @@ void get_search_match_hl(win_T *wp, match_T *search_hl, long col, int *char_attr while (cur != NULL || !shl_flag) { if (!shl_flag - && (cur == NULL || cur->priority > SEARCH_HL_PRIORITY)) { + && (cur == NULL || cur->mit_priority > SEARCH_HL_PRIORITY)) { 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; } } } @@ -895,13 +895,13 @@ void f_getmatches(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) cur = win->w_match_head; while (cur != NULL) { dict_T *dict = tv_dict_alloc(); - 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 - llpos = &cur->pos.pos[i]; + llpos = &cur->mit_pos_array[i]; if (llpos->lnum == 0) { break; } @@ -916,22 +916,22 @@ void f_getmatches(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) tv_dict_add_list(dict, buf, (size_t)len, l); } } else { - tv_dict_add_str(dict, S_LEN("pattern"), (const char *)cur->pattern); + tv_dict_add_str(dict, S_LEN("pattern"), (const char *)cur->mit_pattern); } tv_dict_add_str(dict, S_LEN("group"), - (const char *)syn_id2name(cur->hlg_id)); - tv_dict_add_nr(dict, S_LEN("priority"), (varnumber_T)cur->priority); - tv_dict_add_nr(dict, S_LEN("id"), (varnumber_T)cur->id); + (const char *)syn_id2name(cur->mit_hlg_id)); + tv_dict_add_nr(dict, S_LEN("priority"), (varnumber_T)cur->mit_priority); + tv_dict_add_nr(dict, S_LEN("id"), (varnumber_T)cur->mit_id); - if (cur->conceal_char) { + if (cur->mit_conceal_char) { char buf[MB_MAXBYTES + 1]; - buf[utf_char2bytes(cur->conceal_char, buf)] = NUL; + buf[utf_char2bytes(cur->mit_conceal_char, buf)] = NUL; tv_dict_add_str(dict, S_LEN("conceal"), buf); } tv_list_append_dict(rettv->vval.v_list, dict); - cur = cur->next; + cur = cur->mit_next; } } @@ -1145,8 +1145,8 @@ void f_matcharg(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) if (m != NULL) { tv_list_append_string(rettv->vval.v_list, - (const char *)syn_id2name(m->hlg_id), -1); - tv_list_append_string(rettv->vval.v_list, (const char *)m->pattern, -1); + (const char *)syn_id2name(m->mit_hlg_id), -1); + tv_list_append_string(rettv->vval.v_list, (const char *)m->mit_pattern, -1); } else { tv_list_append_string(rettv->vval.v_list, NULL, 0); tv_list_append_string(rettv->vval.v_list, NULL, 0); diff --git a/src/nvim/testdir/test_match.vim b/src/nvim/testdir/test_match.vim index 70271aa32f..4f22e54563 100644 --- a/src/nvim/testdir/test_match.vim +++ b/src/nvim/testdir/test_match.vim @@ -2,6 +2,7 @@ " matchaddpos(), matcharg(), matchdelete(), and setmatches(). source screendump.vim +source check.vim function Test_match() highlight MyGroup1 term=bold ctermbg=red guibg=red @@ -35,8 +36,8 @@ function Test_match() let m1 = matchadd("MyGroup1", "TODO") let m2 = matchadd("MyGroup2", "FIXME", 42) let m3 = matchadd("MyGroup3", "XXX", 60, 17) - let ans = [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 4}, - \ {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 42, 'id': 5}, + let ans = [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1000}, + \ {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 42, 'id': 1001}, \ {'group': 'MyGroup3', 'pattern': 'XXX', 'priority': 60, 'id': 17}] call assert_equal(ans, getmatches()) @@ -117,7 +118,7 @@ function Test_match() call clearmatches() call setline(1, 'abcdΣabcdef') - eval "MyGroup1"->matchaddpos([[1, 4, 2], [1, 9, 2]]) + eval "MyGroup1"->matchaddpos([[1, 4, 2], [1, 9, 2]], 10, 42) 1 redraw! let v1 = screenattr(1, 1) @@ -128,7 +129,7 @@ function Test_match() let v8 = screenattr(1, 8) let v9 = screenattr(1, 9) let v10 = screenattr(1, 10) - call assert_equal([{'group': 'MyGroup1', 'id': 11, 'priority': 10, 'pos1': [1, 4, 2], 'pos2': [1, 9, 2]}], getmatches()) + call assert_equal([{'group': 'MyGroup1', 'id': 42, 'priority': 10, 'pos1': [1, 4, 2], 'pos2': [1, 9, 2]}], getmatches()) call assert_notequal(v1, v4) call assert_equal(v5, v4) call assert_equal(v6, v1) @@ -142,7 +143,7 @@ function Test_match() let m=getmatches() call clearmatches() call setmatches(m) - call assert_equal([{'group': 'MyGroup1', 'id': 11, 'priority': 10, 'pos1': [1, 4, 2], 'pos2': [1,9, 2]}, {'group': 'MyGroup1', 'pattern': '\%2lmatchadd', 'priority': 10, 'id': 12}], getmatches()) + call assert_equal([{'group': 'MyGroup1', 'id': 42, 'priority': 10, 'pos1': [1, 4, 2], 'pos2': [1,9, 2]}, {'group': 'MyGroup1', 'pattern': '\%2lmatchadd', 'priority': 10, 'id': 1106}], getmatches()) highlight MyGroup1 NONE highlight MyGroup2 NONE @@ -160,7 +161,7 @@ func Test_matchadd_error() call clearmatches() " Nvim: not an error anymore: call matchadd('GroupDoesNotExist', 'X') - call assert_equal([{'group': 'GroupDoesNotExist', 'pattern': 'X', 'priority': 10, 'id': 13}], getmatches()) + call assert_equal([{'group': 'GroupDoesNotExist', 'pattern': 'X', 'priority': 10, 'id': 1206}], getmatches()) call assert_fails("call matchadd('Search', '\\(')", 'E475:') call assert_fails("call matchadd('Search', 'XXX', 1, 123, 1)", 'E715:') call assert_fails("call matchadd('Error', 'XXX', 1, 3)", 'E798:') @@ -219,6 +220,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 @@ -237,8 +253,8 @@ func Test_matchaddpos_otherwin() let savematches = getmatches(winid) let expect = [ - \ {'group': 'Search', 'pattern': '4', 'priority': 10, 'id': 4}, - \ {'group': 'Error', 'id': 5, 'priority': 10, 'pos1': [1, 2, 1], 'pos2': [2, 2, 1]}, + \ {'group': 'Search', 'pattern': '4', 'priority': 10, 'id': 1000}, + \ {'group': 'Error', 'id': 1001, 'priority': 10, 'pos1': [1, 2, 1], 'pos2': [2, 2, 1]}, \] call assert_equal(expect, savematches) diff --git a/src/nvim/window.c b/src/nvim/window.c index adcf9cdd56..c3806e10ff 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -4981,8 +4981,7 @@ static win_T *win_alloc(win_T *after, bool hidden) foldInitWin(new_wp); unblock_autocmds(); - new_wp->w_match_head = NULL; - new_wp->w_next_match_id = 4; + new_wp->w_next_match_id = 1000; // up to 1000 can be picked by the user return new_wp; } |