aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/match.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/match.c')
-rw-r--r--src/nvim/match.c87
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);