# HG changeset patch # User Bram Moolenaar # Date 1608577206 -3600 # Node ID a84e7abb0c92ee1f32a172b0688af7dd5b7f6247 # Parent 50ebb4982f373f0e7b0eb37a9fa4f3ccf66d69cc patch 8.2.2182: Vim9: value of 'magic' is still relevant Commit: https://github.com/vim/vim/commit/f4e2099e39ed4d71aed0f9a9579455aed5ec6cc2 Author: Bram Moolenaar Date: Mon Dec 21 19:59:08 2020 +0100 patch 8.2.2182: Vim9: value of 'magic' is still relevant Problem: Vim9: value of 'magic' is still relevant. Solution: Always behave like 'magic' is on in Vim9 script (closes https://github.com/vim/vim/issues/7509) diff --git a/src/arglist.c b/src/arglist.c --- a/src/arglist.c +++ b/src/arglist.c @@ -409,7 +409,7 @@ do_arglist( p = file_pat_to_reg_pat(p, NULL, NULL, FALSE); if (p == NULL) break; - regmatch.regprog = vim_regcomp(p, p_magic ? RE_MAGIC : 0); + regmatch.regprog = vim_regcomp(p, magic_isset() ? RE_MAGIC : 0); if (regmatch.regprog == NULL) { vim_free(p); diff --git a/src/buffer.c b/src/buffer.c --- a/src/buffer.c +++ b/src/buffer.c @@ -2605,7 +2605,7 @@ buflist_findpat( p = pat; if (*p == '^' && !(attempt & 1)) // add/remove '^' ++p; - regmatch.regprog = vim_regcomp(p, p_magic ? RE_MAGIC : 0); + regmatch.regprog = vim_regcomp(p, magic_isset() ? RE_MAGIC : 0); if (regmatch.regprog == NULL) { vim_free(pat); diff --git a/src/cmdexpand.c b/src/cmdexpand.c --- a/src/cmdexpand.c +++ b/src/cmdexpand.c @@ -1391,7 +1391,7 @@ set_one_cmd_context( if (*arg != NUL) { xp->xp_context = EXPAND_NOTHING; - arg = skip_regexp(arg + 1, *arg, p_magic); + arg = skip_regexp(arg + 1, *arg, magic_isset()); } } return find_nextcmd(arg); @@ -1429,7 +1429,7 @@ set_one_cmd_context( { // skip "from" part ++arg; - arg = skip_regexp(arg, delim, p_magic); + arg = skip_regexp(arg, delim, magic_isset()); } // skip "to" part while (arg[0] != NUL && arg[0] != delim) @@ -2077,7 +2077,7 @@ ExpandFromContext( pat = tofree; } - regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0); + regmatch.regprog = vim_regcomp(pat, magic_isset() ? RE_MAGIC : 0); if (regmatch.regprog == NULL) return FAIL; diff --git a/src/ex_cmds.c b/src/ex_cmds.c --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -3671,7 +3671,8 @@ ex_substitute(exarg_T *eap) which_pat = RE_LAST; // use last used regexp delimiter = *cmd++; // remember delimiter character pat = cmd; // remember start of search pat - cmd = skip_regexp_ex(cmd, delimiter, p_magic, &eap->arg, NULL); + cmd = skip_regexp_ex(cmd, delimiter, magic_isset(), + &eap->arg, NULL); if (cmd[0] == delimiter) // end delimiter found *cmd++ = NUL; // replace it with a NUL } @@ -3763,7 +3764,7 @@ ex_substitute(exarg_T *eap) } if ((cmdmod.cmod_flags & CMOD_KEEPPATTERNS) == 0) - save_re_pat(RE_SUBST, pat, p_magic); + save_re_pat(RE_SUBST, pat, magic_isset()); // put pattern in history add_to_history(HIST_SEARCH, pat, TRUE, NUL); @@ -3897,7 +3898,7 @@ ex_substitute(exarg_T *eap) * But don't do it when it starts with "\=", then it's an expression. */ if (!(sub[0] == '\\' && sub[1] == '=')) - sub = regtilde(sub, p_magic); + sub = regtilde(sub, magic_isset()); /* * Check for a match on each line. @@ -4309,7 +4310,7 @@ ex_substitute(exarg_T *eap) // get length of substitution part sublen = vim_regsub_multi(®match, sub_firstlnum - regmatch.startpos[0].lnum, - sub, sub_firstline, FALSE, p_magic, TRUE); + sub, sub_firstline, FALSE, magic_isset(), TRUE); #ifdef FEAT_EVAL // If getting the substitute string caused an error, don't do // the replacement. @@ -4413,7 +4414,7 @@ ex_substitute(exarg_T *eap) (void)vim_regsub_multi(®match, sub_firstlnum - regmatch.startpos[0].lnum, - sub, new_end, TRUE, p_magic, TRUE); + sub, new_end, TRUE, magic_isset(), TRUE); sub_nsubs++; did_sub = TRUE; @@ -4846,7 +4847,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, p_magic, &eap->arg, NULL); + cmd = skip_regexp_ex(cmd, delim, magic_isset(), &eap->arg, NULL); if (cmd[0] == delim) // end delimiter found *cmd++ = NUL; // replace it with a NUL } diff --git a/src/ex_cmds.h b/src/ex_cmds.h --- a/src/ex_cmds.h +++ b/src/ex_cmds.h @@ -1371,7 +1371,7 @@ EXCMD(CMD_slast, "slast", ex_last, EX_EXTRA|EX_BANG|EX_CMDARG|EX_ARGOPT|EX_TRLBAR, ADDR_NONE), EXCMD(CMD_smagic, "smagic", ex_submagic, - EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_CMDWIN|EX_LOCK_OK, + EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_CMDWIN|EX_LOCK_OK|EX_NONWHITE_OK, ADDR_LINES), EXCMD(CMD_smap, "smap", ex_map, EX_EXTRA|EX_TRLBAR|EX_NOTRLCOM|EX_CTRLV|EX_CMDWIN|EX_LOCK_OK, @@ -1386,7 +1386,7 @@ EXCMD(CMD_snext, "snext", ex_next, EX_RANGE|EX_BANG|EX_FILES|EX_CMDARG|EX_ARGOPT|EX_TRLBAR, ADDR_OTHER), EXCMD(CMD_snomagic, "snomagic", ex_submagic, - EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_CMDWIN|EX_LOCK_OK, + EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_CMDWIN|EX_LOCK_OK|EX_NONWHITE_OK, ADDR_LINES), EXCMD(CMD_snoremap, "snoremap", ex_map, EX_EXTRA|EX_TRLBAR|EX_NOTRLCOM|EX_CTRLV|EX_CMDWIN|EX_LOCK_OK, diff --git a/src/ex_docmd.c b/src/ex_docmd.c --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -3951,7 +3951,7 @@ get_address( } if (skip) // skip "/pat/" { - cmd = skip_regexp(cmd, c, (int)p_magic); + cmd = skip_regexp(cmd, c, magic_isset()); if (*cmd == c) ++cmd; } @@ -6535,9 +6535,9 @@ ex_open(exarg_T *eap) { // ":open /pattern/": put cursor in column found with pattern ++eap->arg; - p = skip_regexp(eap->arg, '/', p_magic); + p = skip_regexp(eap->arg, '/', magic_isset()); *p = NUL; - regmatch.regprog = vim_regcomp(eap->arg, p_magic ? RE_MAGIC : 0); + regmatch.regprog = vim_regcomp(eap->arg, magic_isset() ? RE_MAGIC : 0); if (regmatch.regprog != NULL) { regmatch.rm_ic = p_ic; @@ -7529,11 +7529,11 @@ ex_may_print(exarg_T *eap) static void ex_submagic(exarg_T *eap) { - int magic_save = p_magic; - - p_magic = (eap->cmdidx == CMD_smagic); + magic_T saved = magic_overruled; + + magic_overruled = eap->cmdidx == CMD_smagic ? MAGIC_ON : MAGIC_OFF; ex_substitute(eap); - p_magic = magic_save; + magic_overruled = saved; } /* @@ -8333,7 +8333,7 @@ ex_findpat(exarg_T *eap) { whole = FALSE; ++eap->arg; - p = skip_regexp(eap->arg, '/', p_magic); + p = skip_regexp(eap->arg, '/', magic_isset()); if (*p) { *p++ = NUL; diff --git a/src/ex_getln.c b/src/ex_getln.c --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -149,7 +149,7 @@ typedef struct { pos_T match_end; int did_incsearch; int incsearch_postponed; - int magic_save; + magic_T magic_overruled_save; } incsearch_state_T; static void @@ -159,7 +159,7 @@ init_incsearch_state(incsearch_state_T * is_state->match_start = curwin->w_cursor; is_state->did_incsearch = FALSE; is_state->incsearch_postponed = FALSE; - is_state->magic_save = p_magic; + is_state->magic_overruled_save = magic_overruled; CLEAR_POS(&is_state->match_end); is_state->save_cursor = curwin->w_cursor; // may be restored later is_state->search_start = curwin->w_cursor; @@ -252,9 +252,9 @@ do_incsearch_highlighting( || STRNCMP(cmd, "vglobal", p - cmd) == 0) { if (*cmd == 's' && cmd[1] == 'm') - p_magic = TRUE; + magic_overruled = MAGIC_ON; else if (*cmd == 's' && cmd[1] == 'n') - p_magic = FALSE; + magic_overruled = MAGIC_OFF; } else if (STRNCMP(cmd, "sort", MAX(p - cmd, 3)) == 0) { @@ -288,7 +288,7 @@ do_incsearch_highlighting( p = skipwhite(p); delim = (delim_optional && vim_isIDc(*p)) ? ' ' : *p++; *search_delim = delim; - end = skip_regexp(p, delim, p_magic); + end = skip_regexp(p, delim, magic_isset()); use_last_pat = end == p && *end == delim; @@ -372,7 +372,7 @@ finish_incsearch_highlighting( search_first_line = 0; search_last_line = MAXLNUM; - p_magic = is_state->magic_save; + magic_overruled = is_state->magic_overruled_save; validate_cursor(); // needed for TAB redraw_all_later(SOME_VALID); @@ -713,7 +713,7 @@ may_add_char_to_search(int firstc, int * if (p_ic && p_scs && !pat_has_uppercase(ccline.cmdbuff + skiplen)) *c = MB_TOLOWER(*c); if (*c == search_delim || vim_strchr((char_u *)( - p_magic ? "\\~^$.*[" : "\\^$"), *c) != NULL) + magic_isset() ? "\\~^$.*[" : "\\^$"), *c) != NULL) { // put a backslash before special characters stuffcharReadbuff(*c); diff --git a/src/globals.h b/src/globals.h --- a/src/globals.h +++ b/src/globals.h @@ -1938,3 +1938,8 @@ EXTERN int channel_need_redraw INIT(= FA #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); diff --git a/src/insexpand.c b/src/insexpand.c --- a/src/insexpand.c +++ b/src/insexpand.c @@ -1216,7 +1216,7 @@ ins_compl_dictionaries( } else { - regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0); + regmatch.regprog = vim_regcomp(pat, magic_isset() ? RE_MAGIC : 0); if (regmatch.regprog == NULL) goto theend; } @@ -4175,7 +4175,7 @@ quote_meta(char_u *dest, char_u *src, in break; // FALLTHROUGH case '~': - if (!p_magic) // quote these only if magic is set + if (!magic_isset()) // quote these only if magic is set break; // FALLTHROUGH case '\\': diff --git a/src/normal.c b/src/normal.c --- a/src/normal.c +++ b/src/normal.c @@ -3738,9 +3738,9 @@ nv_ident(cmdarg_T *cap) else { if (cmdchar == '*') - aux_ptr = (char_u *)(p_magic ? "/.*~[^$\\" : "/^$\\"); + aux_ptr = (char_u *)(magic_isset() ? "/.*~[^$\\" : "/^$\\"); else if (cmdchar == '#') - aux_ptr = (char_u *)(p_magic ? "/?.*~[^$\\" : "/?^$\\"); + aux_ptr = (char_u *)(magic_isset() ? "/?.*~[^$\\" : "/?^$\\"); else if (tag_cmd) { if (curbuf->b_help) diff --git a/src/option.c b/src/option.c --- a/src/option.c +++ b/src/option.c @@ -6996,3 +6996,22 @@ fill_culopt_flags(char_u *val, win_T *wp return OK; } #endif + +/* + * Get the value of 'magic' adjusted for Vim9 script. + */ + int +magic_isset(void) +{ + switch (magic_overruled) + { + case MAGIC_ON: return TRUE; + case MAGIC_OFF: return FALSE; + case MAGIC_NOT_SET: break; + } +#ifdef FEAT_EVAL + if (in_vim9script()) + return TRUE; +#endif + return p_magic; +} diff --git a/src/proto/option.pro b/src/proto/option.pro --- a/src/proto/option.pro +++ b/src/proto/option.pro @@ -75,4 +75,5 @@ unsigned int get_bkc_value(buf_T *buf); char_u *get_showbreak_value(win_T *win); dict_T *get_winbuf_options(int bufopt); int fill_culopt_flags(char_u *val, win_T *wp); +int magic_isset(void); /* vim: set ft=c : */ diff --git a/src/search.c b/src/search.c --- a/src/search.c +++ b/src/search.c @@ -134,7 +134,7 @@ search_regcomp( int i; rc_did_emsg = FALSE; - magic = p_magic; + magic = magic_isset(); /* * If no pattern given, use a previously defined pattern. @@ -1341,7 +1341,8 @@ do_search( * If there is a matching '/' or '?', toss it. */ ps = strcopy; - p = skip_regexp_ex(pat, search_delim, (int)p_magic, &strcopy, NULL); + p = skip_regexp_ex(pat, search_delim, magic_isset(), + &strcopy, NULL); if (strcopy != ps) { // made a copy of "pat" to change "\?" to "?" @@ -3385,7 +3386,7 @@ find_pattern_in_path( sprintf((char *)pat, whole ? "\\<%.*s\\>" : "%.*s", len, ptr); // ignore case according to p_ic, p_scs and pat regmatch.rm_ic = ignorecase(pat); - regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0); + regmatch.regprog = vim_regcomp(pat, magic_isset() ? RE_MAGIC : 0); vim_free(pat); if (regmatch.regprog == NULL) goto fpip_end; @@ -3393,7 +3394,8 @@ find_pattern_in_path( inc_opt = (*curbuf->b_p_inc == NUL) ? p_inc : curbuf->b_p_inc; if (*inc_opt != NUL) { - incl_regmatch.regprog = vim_regcomp(inc_opt, p_magic ? RE_MAGIC : 0); + incl_regmatch.regprog = vim_regcomp(inc_opt, + magic_isset() ? RE_MAGIC : 0); if (incl_regmatch.regprog == NULL) goto fpip_end; incl_regmatch.rm_ic = FALSE; // don't ignore case in incl. pat. @@ -3401,7 +3403,8 @@ find_pattern_in_path( if (type == FIND_DEFINE && (*curbuf->b_p_def != NUL || *p_def != NUL)) { def_regmatch.regprog = vim_regcomp(*curbuf->b_p_def == NUL - ? p_def : curbuf->b_p_def, p_magic ? RE_MAGIC : 0); + ? p_def : curbuf->b_p_def, + magic_isset() ? RE_MAGIC : 0); if (def_regmatch.regprog == NULL) goto fpip_end; def_regmatch.rm_ic = FALSE; // don't ignore case in define pat. diff --git a/src/structs.h b/src/structs.h --- a/src/structs.h +++ b/src/structs.h @@ -4309,3 +4309,9 @@ typedef struct // We have to guess how much a sequence of bytes may expand when converting // with iconv() to be able to allocate a buffer. #define ICONV_MULT 8 + +typedef enum { + MAGIC_NOT_SET, // p_magic not overruled + MAGIC_ON, // magic on inside regexp + MAGIC_OFF // magic off inside regexp +} magic_T; diff --git a/src/tag.c b/src/tag.c --- a/src/tag.c +++ b/src/tag.c @@ -1271,7 +1271,7 @@ prepare_pats(pat_T *pats, int has_re) else for (pats->headlen = 0; pats->head[pats->headlen] != NUL; ++pats->headlen) - if (vim_strchr((char_u *)(p_magic ? ".[~*\\$" : "\\$"), + if (vim_strchr((char_u *)(magic_isset() ? ".[~*\\$" : "\\$"), pats->head[pats->headlen]) != NULL) break; if (p_tl != 0 && pats->headlen > p_tl) // adjust for 'taglength' @@ -1279,7 +1279,8 @@ prepare_pats(pat_T *pats, int has_re) } if (has_re) - pats->regmatch.regprog = vim_regcomp(pats->pat, p_magic ? RE_MAGIC : 0); + pats->regmatch.regprog = vim_regcomp(pats->pat, + magic_isset() ? RE_MAGIC : 0); else pats->regmatch.regprog = NULL; } @@ -3311,7 +3312,7 @@ jumpto_tag( int keep_help) // keep help flag (FALSE for cscope) { int save_secure; - int save_magic; + int save_magic_overruled; int save_p_ws, save_p_scs, save_p_ic; linenr_T save_lnum; char_u *str; @@ -3503,8 +3504,8 @@ jumpto_tag( #ifdef HAVE_SANDBOX ++sandbox; #endif - save_magic = p_magic; - p_magic = FALSE; // always execute with 'nomagic' + save_magic_overruled = magic_overruled; + magic_overruled = 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; @@ -3626,7 +3627,7 @@ jumpto_tag( if (secure == 2) wait_return(TRUE); secure = save_secure; - p_magic = save_magic; + magic_overruled = save_magic_overruled; #ifdef HAVE_SANDBOX --sandbox; #endif diff --git a/src/testdir/test_vim9_cmd.vim b/src/testdir/test_vim9_cmd.vim --- a/src/testdir/test_vim9_cmd.vim +++ b/src/testdir/test_vim9_cmd.vim @@ -722,4 +722,22 @@ def Test_command_not_recognized() CheckDefFailure(lines, 'E1146:', 1) enddef +def Test_magic_not_used() + new + for cmd in ['set magic', 'set nomagic'] + exe cmd + setline(1, 'aaa') + s/.../bbb/ + assert_equal('bbb', getline(1)) + endfor + + set magic + setline(1, 'aaa') + assert_fails('s/.\M../bbb/', 'E486:') + assert_fails('snomagic/.../bbb/', 'E486:') + assert_equal('aaa', getline(1)) + + bwipe! +enddef + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/version.c b/src/version.c --- 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 */ /**/ + 2182, +/**/ 2181, /**/ 2180,