diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2023-01-25 18:31:31 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2023-01-25 18:31:31 +0000 |
commit | 9243becbedbb6a1592208051f8fa2b090dcc5e7d (patch) | |
tree | 607c2a862ec3f4399b8766383f6f8e04c4aa43b4 /src/nvim/match.c | |
parent | 9e40b6e9e1bc67f2d856adb837ee64dd0e25b717 (diff) | |
parent | 3c48d3c83fc21dbc0841f9210f04bdb073d73cd1 (diff) | |
download | rneovim-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.c | 407 |
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); } |