mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 03:18:16 +00:00
Merge pull request #20429 from zeertzjq/vim-9.0.0620
vim-patch:9.0.{0620,0622}: matchaddpos() can only add up to 8 matches
This commit is contained in:
@@ -5010,7 +5010,7 @@ matchadd({group}, {pattern} [, {priority} [, {id} [, {dict}]]])
|
||||
respectively. 3 is reserved for use by the |matchparen|
|
||||
plugin.
|
||||
If the {id} argument is not specified or -1, |matchadd()|
|
||||
automatically chooses a free ID.
|
||||
automatically chooses a free ID, which is at least 1000.
|
||||
|
||||
The optional {dict} argument allows for further custom
|
||||
values. Currently this is used to specify a match specific
|
||||
@@ -5068,8 +5068,6 @@ matchaddpos({group}, {pos} [, {priority} [, {id} [, {dict}]]])
|
||||
ignored, as well as entries with negative column numbers and
|
||||
lengths.
|
||||
|
||||
The maximum number of positions in {pos} is 8.
|
||||
|
||||
Returns -1 on error.
|
||||
|
||||
Example: >
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
274
src/nvim/match.c
274
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);
|
||||
|
@@ -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)
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -3,10 +3,8 @@
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local Screen = require('test.functional.ui.screen')
|
||||
|
||||
local eval, clear, command = helpers.eval, helpers.clear, helpers.command
|
||||
local eq, neq = helpers.eq, helpers.neq
|
||||
local clear, command = helpers.clear, helpers.command
|
||||
local insert = helpers.insert
|
||||
local pcall_err = helpers.pcall_err
|
||||
|
||||
describe('063: Test for ":match", "matchadd()" and related functions', function()
|
||||
setup(clear)
|
||||
@@ -19,105 +17,9 @@ describe('063: Test for ":match", "matchadd()" and related functions', function(
|
||||
[1] = {background = Screen.colors.Red},
|
||||
})
|
||||
|
||||
-- Check that "matcharg()" returns the correct group and pattern if a match
|
||||
-- is defined.
|
||||
command("highlight MyGroup1 term=bold ctermbg=red guibg=red")
|
||||
command("highlight MyGroup2 term=italic ctermbg=green guibg=green")
|
||||
command("highlight MyGroup3 term=underline ctermbg=blue guibg=blue")
|
||||
command("match MyGroup1 /TODO/")
|
||||
command("2match MyGroup2 /FIXME/")
|
||||
command("3match MyGroup3 /XXX/")
|
||||
eq({'MyGroup1', 'TODO'}, eval('matcharg(1)'))
|
||||
eq({'MyGroup2', 'FIXME'}, eval('matcharg(2)'))
|
||||
eq({'MyGroup3', 'XXX'}, eval('matcharg(3)'))
|
||||
|
||||
-- Check that "matcharg()" returns an empty list if the argument is not 1,
|
||||
-- 2 or 3 (only 0 and 4 are tested).
|
||||
eq({}, eval('matcharg(0)'))
|
||||
eq({}, eval('matcharg(4)'))
|
||||
|
||||
-- Check that "matcharg()" returns ['', ''] if a match is not defined.
|
||||
command("match")
|
||||
command("2match")
|
||||
command("3match")
|
||||
eq({'', ''}, eval('matcharg(1)'))
|
||||
eq({'', ''}, eval('matcharg(2)'))
|
||||
eq({'', ''}, eval('matcharg(3)'))
|
||||
|
||||
-- Check that "matchadd()" and "getmatches()" agree on added matches and
|
||||
-- that default values apply.
|
||||
command("let m1 = matchadd('MyGroup1', 'TODO')")
|
||||
command("let m2 = matchadd('MyGroup2', 'FIXME', 42)")
|
||||
command("let m3 = matchadd('MyGroup3', 'XXX', 60, 17)")
|
||||
eq({{group = 'MyGroup1', pattern = 'TODO', priority = 10, id = 4},
|
||||
{group = 'MyGroup2', pattern = 'FIXME', priority = 42, id = 5},
|
||||
{group = 'MyGroup3', pattern = 'XXX', priority = 60, id = 17}},
|
||||
eval('getmatches()'))
|
||||
|
||||
-- Check that "matchdelete()" deletes the matches defined in the previous
|
||||
-- test correctly.
|
||||
command("call matchdelete(m1)")
|
||||
command("call matchdelete(m2)")
|
||||
command("call matchdelete(m3)")
|
||||
eq({}, eval('getmatches()'))
|
||||
|
||||
--- Check that "matchdelete()" returns 0 if successful and otherwise -1.
|
||||
command("let m = matchadd('MyGroup1', 'TODO')")
|
||||
eq(0, eval('matchdelete(m)'))
|
||||
|
||||
-- matchdelete throws error and returns -1 on failure
|
||||
neq(true, pcall(function() eval('matchdelete(42)') end))
|
||||
eq('Vim(let):E803: ID not found: 42', pcall_err(command, 'let r2 = matchdelete(42)'))
|
||||
|
||||
-- Check that "clearmatches()" clears all matches defined by ":match" and
|
||||
-- "matchadd()".
|
||||
command("let m1 = matchadd('MyGroup1', 'TODO')")
|
||||
command("let m2 = matchadd('MyGroup2', 'FIXME', 42)")
|
||||
command("let m3 = matchadd('MyGroup3', 'XXX', 60, 17)")
|
||||
command("match MyGroup1 /COFFEE/")
|
||||
command("2match MyGroup2 /HUMPPA/")
|
||||
command("3match MyGroup3 /VIM/")
|
||||
command("call clearmatches()")
|
||||
eq({}, eval('getmatches()'))
|
||||
|
||||
-- Check that "setmatches()" restores a list of matches saved by
|
||||
-- "getmatches()" without changes. (Matches with equal priority must also
|
||||
-- remain in the same order.)
|
||||
command("let m1 = matchadd('MyGroup1', 'TODO')")
|
||||
command("let m2 = matchadd('MyGroup2', 'FIXME', 42)")
|
||||
command("let m3 = matchadd('MyGroup3', 'XXX', 60, 17)")
|
||||
command("match MyGroup1 /COFFEE/")
|
||||
command("2match MyGroup2 /HUMPPA/")
|
||||
command("3match MyGroup3 /VIM/")
|
||||
command("let ml = getmatches()")
|
||||
local ml = eval("ml")
|
||||
command("call clearmatches()")
|
||||
command("call setmatches(ml)")
|
||||
eq(ml, eval('getmatches()'))
|
||||
|
||||
-- Check that "setmatches()" can correctly restore the matches from matchaddpos()
|
||||
command("call clearmatches()")
|
||||
command("call setmatches(ml)")
|
||||
eq(ml, eval('getmatches()'))
|
||||
|
||||
-- Check that "setmatches()" will not add two matches with the same ID. The
|
||||
-- expected behaviour (for now) is to add the first match but not the
|
||||
-- second and to return -1.
|
||||
eq('Vim(let):E801: ID already taken: 1',
|
||||
pcall_err(command, "let r1 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}, {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 10, 'id': 1}])"))
|
||||
eq({{group = 'MyGroup1', pattern = 'TODO', priority = 10, id = 1}}, eval('getmatches()'))
|
||||
|
||||
-- Check that "setmatches()" returns 0 if successful and otherwise -1.
|
||||
-- (A range of valid and invalid input values are tried out to generate the
|
||||
-- return values.)
|
||||
eq(0,eval("setmatches([])"))
|
||||
eq(0,eval("setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}])"))
|
||||
command("call clearmatches()")
|
||||
eq('Vim(let):E714: List required', pcall_err(command, 'let rf1 = setmatches(0)'))
|
||||
eq('Vim(let):E474: List item 0 is either not a dictionary or an empty one',
|
||||
pcall_err(command, 'let rf2 = setmatches([0])'))
|
||||
eq('Vim(let):E474: List item 0 is missing one of the required keys',
|
||||
pcall_err(command, "let rf3 = setmatches([{'wrong key': 'wrong value'}])"))
|
||||
|
||||
-- Check that "matchaddpos()" positions matches correctly
|
||||
insert('abcdefghijklmnopq')
|
||||
|
38
test/functional/legacy/match_spec.lua
Normal file
38
test/functional/legacy/match_spec.lua
Normal file
@@ -0,0 +1,38 @@
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local Screen = require('test.functional.ui.screen')
|
||||
local clear = helpers.clear
|
||||
local exec = helpers.exec
|
||||
|
||||
before_each(clear)
|
||||
|
||||
describe('matchaddpos()', function()
|
||||
-- oldtest: Test_matchaddpos_dump()
|
||||
it('can add more than 8 match positions vim-patch:9.0.0620', function()
|
||||
local screen = Screen.new(60, 14)
|
||||
screen:set_default_attr_ids({
|
||||
[0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
|
||||
[1] = {background = Screen.colors.Yellow}, -- Search
|
||||
})
|
||||
screen:attach()
|
||||
exec([[
|
||||
call setline(1, ['1234567890123']->repeat(14))
|
||||
call matchaddpos('Search', range(1, 12)->map({i, v -> [v, v]}))
|
||||
]])
|
||||
screen:expect([[
|
||||
{1:^1}234567890123 |
|
||||
1{1:2}34567890123 |
|
||||
12{1:3}4567890123 |
|
||||
123{1:4}567890123 |
|
||||
1234{1:5}67890123 |
|
||||
12345{1:6}7890123 |
|
||||
123456{1:7}890123 |
|
||||
1234567{1:8}90123 |
|
||||
12345678{1:9}0123 |
|
||||
123456789{1:0}123 |
|
||||
1234567890{1:1}23 |
|
||||
12345678901{1:2}3 |
|
||||
1234567890123 |
|
||||
|
|
||||
]])
|
||||
end)
|
||||
end)
|
Reference in New Issue
Block a user