aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/match.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-01-25 18:31:31 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-01-25 18:31:31 +0000
commit9243becbedbb6a1592208051f8fa2b090dcc5e7d (patch)
tree607c2a862ec3f4399b8766383f6f8e04c4aa43b4 /src/nvim/match.c
parent9e40b6e9e1bc67f2d856adb837ee64dd0e25b717 (diff)
parent3c48d3c83fc21dbc0841f9210f04bdb073d73cd1 (diff)
downloadrneovim-usermarks.tar.gz
rneovim-usermarks.tar.bz2
rneovim-usermarks.zip
Merge remote-tracking branch 'upstream/master' into usermarksusermarks
Diffstat (limited to 'src/nvim/match.c')
-rw-r--r--src/nvim/match.c407
1 files changed, 221 insertions, 186 deletions
diff --git a/src/nvim/match.c b/src/nvim/match.c
index 1c34c9f004..6663dfd7ec 100644
--- a/src/nvim/match.c
+++ b/src/nvim/match.c
@@ -3,22 +3,39 @@
// match.c: functions for highlighting matches
+#include <assert.h>
+#include <inttypes.h>
#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include "nvim/ascii.h"
#include "nvim/buffer_defs.h"
#include "nvim/charset.h"
#include "nvim/drawscreen.h"
-#include "nvim/eval.h"
#include "nvim/eval/funcs.h"
+#include "nvim/eval/typval.h"
+#include "nvim/eval/typval_defs.h"
+#include "nvim/eval/window.h"
+#include "nvim/ex_cmds_defs.h"
#include "nvim/ex_docmd.h"
#include "nvim/fold.h"
+#include "nvim/gettext.h"
+#include "nvim/globals.h"
#include "nvim/highlight.h"
#include "nvim/highlight_group.h"
+#include "nvim/macros.h"
#include "nvim/match.h"
+#include "nvim/mbyte.h"
#include "nvim/memline.h"
+#include "nvim/memory.h"
+#include "nvim/message.h"
+#include "nvim/option_defs.h"
+#include "nvim/pos.h"
#include "nvim/profile.h"
#include "nvim/regexp.h"
-#include "nvim/runtime.h"
+#include "nvim/strings.h"
+#include "nvim/types.h"
#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -29,13 +46,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,
@@ -47,7 +64,7 @@ static int match_add(win_T *wp, const char *const grp, const char *const pat, in
matchitem_T *m;
int hlg_id;
regprog_T *regprog = NULL;
- int rtype = SOME_VALID;
+ int rtype = UPD_SOME_VALID;
if (*grp == NUL || (pat != NULL && *pat == NUL)) {
return -1;
@@ -58,16 +75,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 +103,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 +148,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 +169,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 +190,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,9 +207,9 @@ 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;
- rtype = VALID;
+ m->mit_toplnum = toplnum;
+ m->mit_botlnum = botlnum;
+ rtype = UPD_VALID;
}
}
@@ -201,21 +217,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;
}
@@ -227,19 +245,18 @@ static int match_delete(win_T *wp, int id, bool perr)
{
matchitem_T *cur = wp->w_match_head;
matchitem_T *prev = cur;
- int rtype = SOME_VALID;
+ int rtype = UPD_SOME_VALID;
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 +265,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 = VALID;
+ rtype = UPD_VALID;
}
+ xfree(cur->mit_pos_array);
xfree(cur);
redraw_later(wp, rtype);
return 0;
@@ -281,23 +299,24 @@ 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;
}
- redraw_later(wp, SOME_VALID);
+ redraw_later(wp, UPD_SOME_VALID);
}
/// 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 +329,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 +351,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 +373,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 +399,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;
@@ -407,7 +425,7 @@ static void next_search_hl(win_T *win, match_T *search_hl, match_T *shl, linenr_
const int called_emsg_before = called_emsg;
// for :{range}s/pat only highlight inside the range
- if (lnum < search_first_line || lnum > search_last_line) {
+ if ((lnum < search_first_line || lnum > search_last_line) && cur == NULL) {
shl->lnum = 0;
return;
}
@@ -443,7 +461,7 @@ static void next_search_hl(win_T *win, match_T *search_hl, match_T *shl, linenr_
} else if (vim_strchr(p_cpo, CPO_SEARCH) == NULL
|| (shl->rm.endpos[0].lnum == 0
&& shl->rm.endpos[0].col <= shl->rm.startpos[0].col)) {
- char_u *ml;
+ char *ml;
matchcol = shl->rm.startpos[0].col;
ml = ml_get_buf(shl->buf, lnum, false) + matchcol;
@@ -452,7 +470,7 @@ static void next_search_hl(win_T *win, match_T *search_hl, match_T *shl, linenr_
shl->lnum = 0;
break;
}
- matchcol += utfc_ptr2len((char *)ml);
+ matchcol += utfc_ptr2len(ml);
} else {
matchcol = shl->rm.endpos[0].col;
}
@@ -460,18 +478,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 +503,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 +538,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 +553,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 +562,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 +575,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;
}
}
}
@@ -580,9 +597,10 @@ static void check_cur_search_hl(win_T *wp, match_T *shl)
}
/// Prepare for 'hlsearch' and match highlighting in one window line.
-/// Return true if there is such highlighting and set "search_attr" to the
-/// current highlight attribute.
-bool prepare_search_hl_line(win_T *wp, linenr_T lnum, colnr_T mincol, char_u **line,
+///
+/// @return true if there is such highlighting and set "search_attr" to the
+/// current highlight attribute.
+bool prepare_search_hl_line(win_T *wp, linenr_T lnum, colnr_T mincol, char **line,
match_T *search_hl, int *search_attr, bool *search_attr_from_match)
{
matchitem_T *cur = wp->w_match_head; // points to the match list
@@ -598,7 +616,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 +624,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);
@@ -636,7 +654,7 @@ bool prepare_search_hl_line(win_T *wp, linenr_T lnum, colnr_T mincol, char_u **l
// Highlight one character for an empty match.
if (shl->startcol == shl->endcol) {
if ((*line)[shl->endcol] != NUL) {
- shl->endcol += utfc_ptr2len((char *)(*line) + shl->endcol);
+ shl->endcol += utfc_ptr2len(*line + shl->endcol);
} else {
shl->endcol++;
}
@@ -649,7 +667,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;
@@ -660,9 +678,11 @@ bool prepare_search_hl_line(win_T *wp, linenr_T lnum, colnr_T mincol, char_u **l
/// After end, check for start/end of next match.
/// When another match, have to check for start again.
/// Watch out for matching an empty string!
+/// "on_last_col" is set to true with non-zero search_attr and the next column
+/// is endcol.
/// Return the updated search_attr.
-int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char_u **line, match_T *search_hl,
- int *has_match_conc, int *match_conc, int lcs_eol_one,
+int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char **line, match_T *search_hl,
+ int *has_match_conc, int *match_conc, int lcs_eol_one, bool *on_last_col,
bool *search_attr_from_match)
{
matchitem_T *cur = wp->w_match_head; // points to the match list
@@ -674,14 +694,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
@@ -690,7 +710,7 @@ int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char_u **line, match
if (shl->startcol != MAXCOL
&& col >= shl->startcol
&& col < shl->endcol) {
- int next_col = col + utfc_ptr2len((char *)(*line) + col);
+ int next_col = col + utfc_ptr2len(*line + col);
if (shl->endcol < next_col) {
shl->endcol = next_col;
@@ -706,9 +726,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 +737,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.
@@ -738,7 +758,13 @@ int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char_u **line, match
if (shl->startcol == shl->endcol) {
// highlight empty match, try again after it
- shl->endcol += utfc_ptr2len((char *)(*line) + shl->endcol);
+ char *p = *line + shl->endcol;
+
+ if (*p == NUL) {
+ shl->endcol++;
+ } else {
+ shl->endcol += utfc_ptr2len(p);
+ }
}
// Loop to check if the match starts at the
@@ -749,30 +775,31 @@ 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;
+ *on_last_col = col + 1 >= shl->endcol;
*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.
@@ -792,17 +819,24 @@ bool get_prevcol_hl_flag(win_T *wp, match_T *search_hl, long curcol)
prevcol++;
}
- if (!search_hl->is_addpos && prevcol == search_hl->startcol) {
+ // Highlight a character after the end of the line if the match started
+ // at the end of the line or when the match continues in the next line
+ // (match includes the line break).
+ if (!search_hl->is_addpos && (prevcol == (long)search_hl->startcol
+ || (prevcol > (long)search_hl->startcol
+ && search_hl->endcol == MAXCOL))) {
return true;
- } else {
- cur = wp->w_match_head;
- while (cur != NULL) {
- if (!cur->hl.is_addpos && prevcol == cur->hl.startcol) {
- return true;
- }
- cur = cur->next;
+ }
+ 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))) {
+ return true;
}
+ cur = cur->mit_next;
}
+
return false;
}
@@ -815,21 +849,20 @@ void get_search_match_hl(win_T *wp, match_T *search_hl, long col, int *char_attr
bool shl_flag = false; // flag to indicate whether search_hl
// has been processed or not
- *char_attr = search_hl->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;
}
}
}
@@ -847,19 +880,21 @@ static int matchadd_dict_arg(typval_T *tv, const char **conceal_char, win_T **wi
*conceal_char = tv_get_string(&di->di_tv);
}
- if ((di = tv_dict_find(tv->vval.v_dict, S_LEN("window"))) != NULL) {
- *win = find_win_by_nr_or_id(&di->di_tv);
- if (*win == NULL) {
- emsg(_(e_invalwindow));
- return FAIL;
- }
+ if ((di = tv_dict_find(tv->vval.v_dict, S_LEN("window"))) == NULL) {
+ return OK;
+ }
+
+ *win = find_win_by_nr_or_id(&di->di_tv);
+ if (*win == NULL) {
+ emsg(_(e_invalwindow));
+ return FAIL;
}
return OK;
}
/// "clearmatches()" function
-void f_clearmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+void f_clearmatches(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
win_T *win = get_optional_window(argvars, 0);
@@ -869,7 +904,7 @@ void f_clearmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
/// "getmatches()" function
-void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+void f_getmatches(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
matchitem_T *cur;
int i;
@@ -883,13 +918,13 @@ void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr 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;
}
@@ -904,27 +939,27 @@ void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr 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;
}
}
/// "setmatches()" function
-void f_setmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+void f_setmatches(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
dict_T *d;
list_T *s = NULL;
@@ -1027,7 +1062,7 @@ void f_setmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
/// "matchadd()" function
-void f_matchadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+void f_matchadd(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
char grpbuf[NUMBUFLEN];
char patbuf[NUMBUFLEN];
@@ -1069,7 +1104,7 @@ void f_matchadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
/// "matchaddpo()" function
-void f_matchaddpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+void f_matchaddpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
rettv->vval.v_number = -1;
@@ -1120,7 +1155,7 @@ void f_matchaddpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
/// "matcharg()" function
-void f_matcharg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+void f_matcharg(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
const int id = (int)tv_get_number(&argvars[0]);
@@ -1133,8 +1168,8 @@ void f_matcharg(typval_T *argvars, typval_T *rettv, FunPtr 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);
@@ -1143,7 +1178,7 @@ void f_matcharg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
/// "matchdelete()" function
-void f_matchdelete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+void f_matchdelete(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
win_T *win = get_optional_window(argvars, 1);
if (win == NULL) {
@@ -1159,9 +1194,9 @@ void f_matchdelete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/// skipping commands to find the next command.
void ex_match(exarg_T *eap)
{
- char_u *p;
- char_u *g = NULL;
- char_u *end;
+ char *p;
+ char *g = NULL;
+ char *end;
int c;
int id;
@@ -1178,25 +1213,25 @@ void ex_match(exarg_T *eap)
}
if (ends_excmd(*eap->arg)) {
- end = (char_u *)eap->arg;
+ end = eap->arg;
} else if ((STRNICMP(eap->arg, "none", 4) == 0
&& (ascii_iswhite(eap->arg[4]) || ends_excmd(eap->arg[4])))) {
- end = (char_u *)eap->arg + 4;
+ end = eap->arg + 4;
} else {
- p = skiptowhite((char_u *)eap->arg);
+ p = skiptowhite(eap->arg);
if (!eap->skip) {
- g = vim_strnsave((char_u *)eap->arg, (size_t)(p - (char_u *)eap->arg));
+ g = xstrnsave(eap->arg, (size_t)(p - eap->arg));
}
- p = (char_u *)skipwhite((char *)p);
+ p = skipwhite(p);
if (*p == NUL) {
// There must be two arguments.
xfree(g);
semsg(_(e_invarg2), eap->arg);
return;
}
- end = skip_regexp(p + 1, *p, true, NULL);
+ end = skip_regexp(p + 1, *p, true);
if (!eap->skip) {
- if (*end != NUL && !ends_excmd(*skipwhite((char *)end + 1))) {
+ if (*end != NUL && !ends_excmd(*skipwhite(end + 1))) {
xfree(g);
eap->errmsg = ex_errmsg(e_trailing_arg, (const char *)end);
return;
@@ -1207,13 +1242,13 @@ void ex_match(exarg_T *eap)
return;
}
- c = *end;
+ c = (uint8_t)(*end);
*end = NUL;
match_add(curwin, (const char *)g, (const char *)p + 1, 10, id,
NULL, NULL);
xfree(g);
- *end = (char_u)c;
+ *end = (char)c;
}
}
- eap->nextcmd = (char *)find_nextcmd(end);
+ eap->nextcmd = find_nextcmd(end);
}