summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ex_cmds.c4
-rw-r--r--src/ex_docmd.c5
-rw-r--r--src/ex_getln.c48
-rw-r--r--src/globals.h7
-rw-r--r--src/option.c6
-rw-r--r--src/proto/regexp.pro2
-rw-r--r--src/regexp.c16
-rw-r--r--src/search.c2
-rw-r--r--src/structs.h18
-rw-r--r--src/tag.c4
-rw-r--r--src/testdir/dumps/Test_incsearch_sub_01.dump9
-rw-r--r--src/testdir/dumps/Test_incsearch_sub_02.dump9
-rw-r--r--src/testdir/test_search.vim29
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c4
15 files changed, 125 insertions, 40 deletions
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index 734949c33..c61810fe6 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -3672,7 +3672,7 @@ ex_substitute(exarg_T *eap)
delimiter = *cmd++; // remember delimiter character
pat = cmd; // remember start of search pat
cmd = skip_regexp_ex(cmd, delimiter, magic_isset(),
- &eap->arg, NULL);
+ &eap->arg, NULL, NULL);
if (cmd[0] == delimiter) // end delimiter found
*cmd++ = NUL; // replace it with a NUL
}
@@ -4856,7 +4856,7 @@ ex_global(exarg_T *eap)
if (delim)
++cmd; // skip delimiter if there is one
pat = cmd; // remember start of pattern
- cmd = skip_regexp_ex(cmd, delim, magic_isset(), &eap->arg, NULL);
+ cmd = skip_regexp_ex(cmd, delim, magic_isset(), &eap->arg, NULL, NULL);
if (cmd[0] == delim) // end delimiter found
*cmd++ = NUL; // replace it with a NUL
}
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index dc9ea165f..044c18a85 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -7529,9 +7529,10 @@ ex_may_print(exarg_T *eap)
static void
ex_submagic(exarg_T *eap)
{
- magic_T saved = magic_overruled;
+ optmagic_T saved = magic_overruled;
- magic_overruled = eap->cmdidx == CMD_smagic ? MAGIC_ON : MAGIC_OFF;
+ magic_overruled = eap->cmdidx == CMD_smagic
+ ? OPTION_MAGIC_ON : OPTION_MAGIC_OFF;
ex_substitute(eap);
magic_overruled = saved;
}
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 04b10ead4..a3e1f4995 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -52,6 +52,9 @@ static void restore_cmdline(cmdline_info_T *ccp);
static int cmdline_paste(int regname, int literally, int remcr);
static void redrawcmdprompt(void);
static int ccheck_abbr(int);
+#ifdef FEAT_SEARCH_EXTRA
+static int empty_pattern_magic(char_u *pat, size_t len, magic_T magic_val);
+#endif
#ifdef FEAT_CMDWIN
static int open_cmdwin(void);
@@ -89,15 +92,34 @@ abandon_cmdline(void)
* as a trailing \|, which can happen while typing a pattern.
*/
static int
-empty_pattern(char_u *p)
+empty_pattern(char_u *p, int delim)
{
- size_t n = STRLEN(p);
+ size_t n = STRLEN(p);
+ magic_T magic_val = MAGIC_ON;
+
+ if (n > 0)
+ (void) skip_regexp_ex(p, delim, magic_isset(), NULL, NULL, &magic_val);
+ else
+ return TRUE;
+ return empty_pattern_magic(p, n, magic_val);
+}
+
+ static int
+empty_pattern_magic(char_u *p, size_t len, magic_T magic_val)
+{
// remove trailing \v and the like
- while (n >= 2 && p[n - 2] == '\\'
- && vim_strchr((char_u *)"mMvVcCZ", p[n - 1]) != NULL)
- n -= 2;
- return n == 0 || (n >= 2 && p[n - 2] == '\\' && p[n - 1] == '|');
+ while (len >= 2 && p[len - 2] == '\\'
+ && vim_strchr((char_u *)"mMvVcCZ", p[len - 1]) != NULL)
+ len -= 2;
+
+ // true, if the pattern is empty, or the pattern ends with \| and magic is
+ // set (or it ends with '|' and very magic is set)
+ return len == 0 || (len > 1
+ && ((p[len - 2] == '\\'
+ && p[len - 1] == '|' && magic_val == MAGIC_ON)
+ || (p[len - 2] != '\\'
+ && p[len - 1] == '|' && magic_val == MAGIC_ALL)));
}
// Struct to store the viewstate during 'incsearch' highlighting.
@@ -149,7 +171,7 @@ typedef struct {
pos_T match_end;
int did_incsearch;
int incsearch_postponed;
- magic_T magic_overruled_save;
+ optmagic_T magic_overruled_save;
} incsearch_state_T;
static void
@@ -207,6 +229,7 @@ do_incsearch_highlighting(
pos_T save_cursor;
int use_last_pat;
int retval = FALSE;
+ magic_T magic = 0;
*skiplen = 0;
*patlen = ccline.cmdlen;
@@ -252,9 +275,9 @@ do_incsearch_highlighting(
|| STRNCMP(cmd, "vglobal", p - cmd) == 0)
{
if (*cmd == 's' && cmd[1] == 'm')
- magic_overruled = MAGIC_ON;
+ magic_overruled = OPTION_MAGIC_ON;
else if (*cmd == 's' && cmd[1] == 'n')
- magic_overruled = MAGIC_OFF;
+ magic_overruled = OPTION_MAGIC_OFF;
}
else if (STRNCMP(cmd, "sort", MAX(p - cmd, 3)) == 0)
{
@@ -288,7 +311,7 @@ do_incsearch_highlighting(
p = skipwhite(p);
delim = (delim_optional && vim_isIDc(*p)) ? ' ' : *p++;
*search_delim = delim;
- end = skip_regexp(p, delim, magic_isset());
+ end = skip_regexp_ex(p, delim, magic_isset(), NULL, NULL, &magic);
use_last_pat = end == p && *end == delim;
@@ -302,7 +325,7 @@ do_incsearch_highlighting(
int empty;
*end = NUL;
- empty = empty_pattern(p);
+ empty = empty_pattern_magic(p, STRLEN(p), magic);
*end = c;
if (empty)
goto theend;
@@ -535,7 +558,8 @@ may_do_incsearch_highlighting(
{
next_char = ccline.cmdbuff[skiplen + patlen];
ccline.cmdbuff[skiplen + patlen] = NUL;
- if (empty_pattern(ccline.cmdbuff) && !no_hlsearch)
+ if (empty_pattern(ccline.cmdbuff + skiplen, search_delim)
+ && !no_hlsearch)
{
redraw_all_later(SOME_VALID);
set_no_hlsearch(TRUE);
diff --git a/src/globals.h b/src/globals.h
index dcb0f6324..e4e73f210 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -1945,7 +1945,6 @@ EXTERN int channel_need_redraw INIT(= FALSE);
#define FOR_ALL_LIST_ITEMS(l, li) \
for ((li) = (l)->lv_first; (li) != NULL; (li) = (li)->li_next)
-// While executing a regexp and set to MAGIC_ON or MAGIC_OFF this overrules
-// p_magic. Otherwise set to MAGIC_NOT_SET.
-
-EXTERN magic_T magic_overruled INIT(= MAGIC_NOT_SET);
+// While executing a regexp and set to OPTION_MAGIC_ON or OPTION_MAGIC_OFF this
+// overrules p_magic. Otherwise set to OPTION_MAGIC_NOT_SET.
+EXTERN optmagic_T magic_overruled INIT(= OPTION_MAGIC_NOT_SET);
diff --git a/src/option.c b/src/option.c
index 094a72354..b4893a10a 100644
--- a/src/option.c
+++ b/src/option.c
@@ -7009,9 +7009,9 @@ magic_isset(void)
{
switch (magic_overruled)
{
- case MAGIC_ON: return TRUE;
- case MAGIC_OFF: return FALSE;
- case MAGIC_NOT_SET: break;
+ case OPTION_MAGIC_ON: return TRUE;
+ case OPTION_MAGIC_OFF: return FALSE;
+ case OPTION_MAGIC_NOT_SET: break;
}
#ifdef FEAT_EVAL
if (in_vim9script())
diff --git a/src/proto/regexp.pro b/src/proto/regexp.pro
index d3a775415..15b1225b0 100644
--- a/src/proto/regexp.pro
+++ b/src/proto/regexp.pro
@@ -2,7 +2,7 @@
int re_multiline(regprog_T *prog);
char_u *skip_regexp(char_u *startp, int delim, int magic);
char_u *skip_regexp_err(char_u *startp, int delim, int magic);
-char_u *skip_regexp_ex(char_u *startp, int dirc, int magic, char_u **newp, int *dropped);
+char_u *skip_regexp_ex(char_u *startp, int dirc, int magic, char_u **newp, int *dropped, magic_T *magic_val);
reg_extmatch_T *ref_extmatch(reg_extmatch_T *em);
void unref_extmatch(reg_extmatch_T *em);
char_u *regtilde(char_u *source, int magic);
diff --git a/src/regexp.c b/src/regexp.c
index 0fd6de61e..9d2d441fc 100644
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -304,11 +304,7 @@ static unsigned regflags; // RF_ flags for prog
static int had_eol; // TRUE when EOL found by vim_regcomp()
#endif
-static int reg_magic; // magicness of the pattern:
-#define MAGIC_NONE 1 // "\V" very unmagic
-#define MAGIC_OFF 2 // "\M" or 'magic' off
-#define MAGIC_ON 3 // "\m" or 'magic'
-#define MAGIC_ALL 4 // "\v" very magic
+static magic_T reg_magic; // magicness of the pattern
static int reg_string; // matching with a string instead of a buffer
// line
@@ -548,7 +544,7 @@ skip_regexp(
int delim,
int magic)
{
- return skip_regexp_ex(startp, delim, magic, NULL, NULL);
+ return skip_regexp_ex(startp, delim, magic, NULL, NULL, NULL);
}
/*
@@ -577,6 +573,7 @@ skip_regexp_err(
* expression and change "\?" to "?". If "*newp" is not NULL the expression
* is changed in-place.
* If a "\?" is changed to "?" then "dropped" is incremented, unless NULL.
+ * If "magic_val" is not NULL, returns the effective magicness of the pattern
*/
char_u *
skip_regexp_ex(
@@ -584,9 +581,10 @@ skip_regexp_ex(
int dirc,
int magic,
char_u **newp,
- int *dropped)
+ int *dropped,
+ magic_T *magic_val)
{
- int mymagic;
+ magic_T mymagic;
char_u *p = startp;
if (magic)
@@ -632,6 +630,8 @@ skip_regexp_ex(
mymagic = MAGIC_NONE;
}
}
+ if (magic_val != NULL)
+ *magic_val = mymagic;
return p;
}
diff --git a/src/search.c b/src/search.c
index 6305b58b1..3a4d4589a 100644
--- a/src/search.c
+++ b/src/search.c
@@ -1342,7 +1342,7 @@ do_search(
*/
ps = strcopy;
p = skip_regexp_ex(pat, search_delim, magic_isset(),
- &strcopy, NULL);
+ &strcopy, NULL, NULL);
if (strcopy != ps)
{
// made a copy of "pat" to change "\?" to "?"
diff --git a/src/structs.h b/src/structs.h
index e2045104c..c016f1997 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -4321,8 +4321,20 @@ typedef struct
// with iconv() to be able to allocate a buffer.
#define ICONV_MULT 8
+// Used for "magic_overruled".
typedef enum {
- MAGIC_NOT_SET, // p_magic not overruled
- MAGIC_ON, // magic on inside regexp
- MAGIC_OFF // magic off inside regexp
+ OPTION_MAGIC_NOT_SET, // p_magic not overruled
+ OPTION_MAGIC_ON, // magic on inside regexp
+ OPTION_MAGIC_OFF // magic off inside regexp
+} optmagic_T;
+
+// Magicness of a pattern, used by regexp code.
+// The order and values matter:
+// magic <= MAGIC_OFF includes MAGIC_NONE
+// magic >= MAGIC_ON includes MAGIC_ALL
+typedef enum {
+ MAGIC_NONE = 1, // "\V" very unmagic
+ MAGIC_OFF = 2, // "\M" or 'magic' off
+ MAGIC_ON = 3, // "\m" or 'magic'
+ MAGIC_ALL = 4 // "\v" very magic
} magic_T;
diff --git a/src/tag.c b/src/tag.c
index c4896b384..3dfb8fee5 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -3312,7 +3312,7 @@ jumpto_tag(
int keep_help) // keep help flag (FALSE for cscope)
{
int save_secure;
- int save_magic_overruled;
+ optmagic_T save_magic_overruled;
int save_p_ws, save_p_scs, save_p_ic;
linenr_T save_lnum;
char_u *str;
@@ -3505,7 +3505,7 @@ jumpto_tag(
++sandbox;
#endif
save_magic_overruled = magic_overruled;
- magic_overruled = MAGIC_OFF; // always execute with 'nomagic'
+ magic_overruled = OPTION_MAGIC_OFF; // always execute with 'nomagic'
#ifdef FEAT_SEARCH_EXTRA
// Save value of no_hlsearch, jumping to a tag is not a real search
save_no_hlsearch = no_hlsearch;
diff --git a/src/testdir/dumps/Test_incsearch_sub_01.dump b/src/testdir/dumps/Test_incsearch_sub_01.dump
new file mode 100644
index 000000000..5924fbde8
--- /dev/null
+++ b/src/testdir/dumps/Test_incsearch_sub_01.dump
@@ -0,0 +1,9 @@
+|f+0&#ffffff0|o@1| |1| @64
+|f|o@1| |2| @64
+|f|o@1| |3| @64
+|f|o@1| |4| @64
+|a|b|c|||d|e|f| @62
+|~+0#4040ff13&| @68
+|~| @68
+|~| @68
+|:+0#0000000&|%|s|/|\|v|a|b|c||> @59
diff --git a/src/testdir/dumps/Test_incsearch_sub_02.dump b/src/testdir/dumps/Test_incsearch_sub_02.dump
new file mode 100644
index 000000000..c6b58cb5e
--- /dev/null
+++ b/src/testdir/dumps/Test_incsearch_sub_02.dump
@@ -0,0 +1,9 @@
+|f+0&#ffffff0|o@1| |1| @64
+|f|o@1| |2| @64
+|f|o@1| |3| @64
+|f|o@1| |4| @64
+|a|b|c|||d|e|f| @62
+|~+0#4040ff13&| @68
+|~| @68
+|~| @68
+|:+0#0000000&|1|,|5|s|/|\|v||> @60
diff --git a/src/testdir/test_search.vim b/src/testdir/test_search.vim
index 101829461..2dc53d97d 100644
--- a/src/testdir/test_search.vim
+++ b/src/testdir/test_search.vim
@@ -1808,4 +1808,33 @@ func Test_incsearch_highlighting_newline()
bw
endfunc
+func Test_incsearch_substitute_dump2()
+ CheckOption incsearch
+ CheckScreendump
+
+ call writefile([
+ \ 'set incsearch hlsearch scrolloff=0',
+ \ 'for n in range(1, 4)',
+ \ ' call setline(n, "foo " . n)',
+ \ 'endfor',
+ \ 'call setline(5, "abc|def")',
+ \ '3',
+ \ ], 'Xis_subst_script2')
+ let buf = RunVimInTerminal('-S Xis_subst_script2', {'rows': 9, 'cols': 70})
+
+ call term_sendkeys(buf, ':%s/\vabc|')
+ sleep 100m
+ call VerifyScreenDump(buf, 'Test_incsearch_sub_01', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ " The following should not be highlighted
+ call term_sendkeys(buf, ':1,5s/\v|')
+ sleep 100m
+ call VerifyScreenDump(buf, 'Test_incsearch_sub_02', {})
+
+
+ call StopVimInTerminal(buf)
+ call delete('Xis_subst_script2')
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index db20152a3..12877de0a 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2295,
+/**/
2294,
/**/
2293,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index 3eae641f2..80f918d9e 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -7048,7 +7048,7 @@ compile_catch(char_u *arg, cctx_T *cctx UNUSED)
// Push v:exception, push {expr} and MATCH
generate_instr_type(cctx, ISN_PUSHEXC, &t_string);
- end = skip_regexp_ex(p + 1, *p, TRUE, &tofree, &dropped);
+ end = skip_regexp_ex(p + 1, *p, TRUE, &tofree, &dropped, NULL);
if (*end != *p)
{
semsg(_(e_separator_mismatch_str), p);
@@ -7372,7 +7372,7 @@ compile_exec(char_u *line, exarg_T *eap, cctx_T *cctx)
{
int delim = *eap->arg;
- p = skip_regexp_ex(eap->arg + 1, delim, TRUE, NULL, NULL);
+ p = skip_regexp_ex(eap->arg + 1, delim, TRUE, NULL, NULL, NULL);
if (*p == delim)
{
eap->arg = p + 1;