diff options
Diffstat (limited to 'src/nvim/match.c')
-rw-r--r-- | src/nvim/match.c | 87 |
1 files changed, 55 insertions, 32 deletions
diff --git a/src/nvim/match.c b/src/nvim/match.c index b422dc0ba8..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 @@ -408,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; } @@ -444,16 +461,16 @@ 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 = (char_u *)ml_get_buf(shl->buf, lnum, false) + matchcol; + ml = ml_get_buf(shl->buf, lnum, false) + matchcol; if (*ml == NUL) { matchcol++; shl->lnum = 0; break; } - matchcol += utfc_ptr2len((char *)ml); + matchcol += utfc_ptr2len(ml); } else { matchcol = shl->rm.endpos[0].col; } @@ -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 @@ -613,7 +631,7 @@ bool prepare_search_hl_line(win_T *wp, linenr_T lnum, colnr_T mincol, char_u **l // Need to get the line again, a multi-line regexp may have made it // invalid. - *line = (char_u *)ml_get_buf(wp->w_buffer, lnum, false); + *line = ml_get_buf(wp->w_buffer, lnum, false); if (shl->lnum != 0 && shl->lnum <= lnum) { if (shl->lnum == lnum) { @@ -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++; } @@ -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 @@ -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; @@ -721,7 +741,7 @@ int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char_u **line, match // Need to get the line again, a multi-line regexp // may have made it invalid. - *line = (char_u *)ml_get_buf(wp->w_buffer, lnum, false); + *line = ml_get_buf(wp->w_buffer, lnum, false); if (shl->lnum == lnum) { shl->startcol = shl->rm.startpos[0].col; @@ -738,7 +758,7 @@ 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 - char *p = (char *)(*line) + shl->endcol; + char *p = *line + shl->endcol; if (*p == NUL) { shl->endcol++; @@ -775,6 +795,7 @@ int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char_u **line, match } 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) { @@ -805,17 +826,17 @@ bool get_prevcol_hl_flag(win_T *wp, match_T *search_hl, long curcol) || (prevcol > (long)search_hl->startcol && search_hl->endcol == MAXCOL))) { return true; - } else { - 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; + } + 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; } @@ -859,12 +880,14 @@ 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; @@ -1206,7 +1229,7 @@ void ex_match(exarg_T *eap) 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(end + 1))) { xfree(g); |