comparison src/ex_getln.c @ 23505:bb29b09902d5 v8.2.2295

patch 8.2.2295: incsearch does not detect empty pattern properly Commit: https://github.com/vim/vim/commit/d93a7fc1a98a58f8101ee780d4735079ad99ae35 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Jan 4 12:42:13 2021 +0100 patch 8.2.2295: incsearch does not detect empty pattern properly Problem: Incsearch does not detect empty pattern properly. Solution: Return magic state when skipping over a pattern. (Christian Brabandt, closes #7612, closes #6420)
author Bram Moolenaar <Bram@vim.org>
date Mon, 04 Jan 2021 12:45:05 +0100
parents a84e7abb0c92
children fc031340f8f9
comparison
equal deleted inserted replaced
23504:25d5c354a83e 23505:bb29b09902d5
50 static void save_cmdline(cmdline_info_T *ccp); 50 static void save_cmdline(cmdline_info_T *ccp);
51 static void restore_cmdline(cmdline_info_T *ccp); 51 static void restore_cmdline(cmdline_info_T *ccp);
52 static int cmdline_paste(int regname, int literally, int remcr); 52 static int cmdline_paste(int regname, int literally, int remcr);
53 static void redrawcmdprompt(void); 53 static void redrawcmdprompt(void);
54 static int ccheck_abbr(int); 54 static int ccheck_abbr(int);
55 #ifdef FEAT_SEARCH_EXTRA
56 static int empty_pattern_magic(char_u *pat, size_t len, magic_T magic_val);
57 #endif
55 58
56 #ifdef FEAT_CMDWIN 59 #ifdef FEAT_CMDWIN
57 static int open_cmdwin(void); 60 static int open_cmdwin(void);
58 61
59 static int cedit_key INIT(= -1); // key value of 'cedit' option 62 static int cedit_key INIT(= -1); // key value of 'cedit' option
87 /* 90 /*
88 * Guess that the pattern matches everything. Only finds specific cases, such 91 * Guess that the pattern matches everything. Only finds specific cases, such
89 * as a trailing \|, which can happen while typing a pattern. 92 * as a trailing \|, which can happen while typing a pattern.
90 */ 93 */
91 static int 94 static int
92 empty_pattern(char_u *p) 95 empty_pattern(char_u *p, int delim)
93 { 96 {
94 size_t n = STRLEN(p); 97 size_t n = STRLEN(p);
95 98 magic_T magic_val = MAGIC_ON;
99
100 if (n > 0)
101 (void) skip_regexp_ex(p, delim, magic_isset(), NULL, NULL, &magic_val);
102 else
103 return TRUE;
104
105 return empty_pattern_magic(p, n, magic_val);
106 }
107
108 static int
109 empty_pattern_magic(char_u *p, size_t len, magic_T magic_val)
110 {
96 // remove trailing \v and the like 111 // remove trailing \v and the like
97 while (n >= 2 && p[n - 2] == '\\' 112 while (len >= 2 && p[len - 2] == '\\'
98 && vim_strchr((char_u *)"mMvVcCZ", p[n - 1]) != NULL) 113 && vim_strchr((char_u *)"mMvVcCZ", p[len - 1]) != NULL)
99 n -= 2; 114 len -= 2;
100 return n == 0 || (n >= 2 && p[n - 2] == '\\' && p[n - 1] == '|'); 115
116 // true, if the pattern is empty, or the pattern ends with \| and magic is
117 // set (or it ends with '|' and very magic is set)
118 return len == 0 || (len > 1
119 && ((p[len - 2] == '\\'
120 && p[len - 1] == '|' && magic_val == MAGIC_ON)
121 || (p[len - 2] != '\\'
122 && p[len - 1] == '|' && magic_val == MAGIC_ALL)));
101 } 123 }
102 124
103 // Struct to store the viewstate during 'incsearch' highlighting. 125 // Struct to store the viewstate during 'incsearch' highlighting.
104 typedef struct { 126 typedef struct {
105 colnr_T vs_curswant; 127 colnr_T vs_curswant;
147 viewstate_T old_viewstate; 169 viewstate_T old_viewstate;
148 pos_T match_start; 170 pos_T match_start;
149 pos_T match_end; 171 pos_T match_end;
150 int did_incsearch; 172 int did_incsearch;
151 int incsearch_postponed; 173 int incsearch_postponed;
152 magic_T magic_overruled_save; 174 optmagic_T magic_overruled_save;
153 } incsearch_state_T; 175 } incsearch_state_T;
154 176
155 static void 177 static void
156 init_incsearch_state(incsearch_state_T *is_state) 178 init_incsearch_state(incsearch_state_T *is_state)
157 { 179 {
205 char *dummy; 227 char *dummy;
206 exarg_T ea; 228 exarg_T ea;
207 pos_T save_cursor; 229 pos_T save_cursor;
208 int use_last_pat; 230 int use_last_pat;
209 int retval = FALSE; 231 int retval = FALSE;
232 magic_T magic = 0;
210 233
211 *skiplen = 0; 234 *skiplen = 0;
212 *patlen = ccline.cmdlen; 235 *patlen = ccline.cmdlen;
213 236
214 if (!p_is || cmd_silent) 237 if (!p_is || cmd_silent)
250 || STRNCMP(cmd, "smagic", p - cmd) == 0 273 || STRNCMP(cmd, "smagic", p - cmd) == 0
251 || STRNCMP(cmd, "snomagic", MAX(p - cmd, 3)) == 0 274 || STRNCMP(cmd, "snomagic", MAX(p - cmd, 3)) == 0
252 || STRNCMP(cmd, "vglobal", p - cmd) == 0) 275 || STRNCMP(cmd, "vglobal", p - cmd) == 0)
253 { 276 {
254 if (*cmd == 's' && cmd[1] == 'm') 277 if (*cmd == 's' && cmd[1] == 'm')
255 magic_overruled = MAGIC_ON; 278 magic_overruled = OPTION_MAGIC_ON;
256 else if (*cmd == 's' && cmd[1] == 'n') 279 else if (*cmd == 's' && cmd[1] == 'n')
257 magic_overruled = MAGIC_OFF; 280 magic_overruled = OPTION_MAGIC_OFF;
258 } 281 }
259 else if (STRNCMP(cmd, "sort", MAX(p - cmd, 3)) == 0) 282 else if (STRNCMP(cmd, "sort", MAX(p - cmd, 3)) == 0)
260 { 283 {
261 // skip over ! and flags 284 // skip over ! and flags
262 if (*p == '!') 285 if (*p == '!')
286 goto theend; 309 goto theend;
287 310
288 p = skipwhite(p); 311 p = skipwhite(p);
289 delim = (delim_optional && vim_isIDc(*p)) ? ' ' : *p++; 312 delim = (delim_optional && vim_isIDc(*p)) ? ' ' : *p++;
290 *search_delim = delim; 313 *search_delim = delim;
291 end = skip_regexp(p, delim, magic_isset()); 314 end = skip_regexp_ex(p, delim, magic_isset(), NULL, NULL, &magic);
292 315
293 use_last_pat = end == p && *end == delim; 316 use_last_pat = end == p && *end == delim;
294 317
295 if (end == p && !use_last_pat) 318 if (end == p && !use_last_pat)
296 goto theend; 319 goto theend;
300 { 323 {
301 char c = *end; 324 char c = *end;
302 int empty; 325 int empty;
303 326
304 *end = NUL; 327 *end = NUL;
305 empty = empty_pattern(p); 328 empty = empty_pattern_magic(p, STRLEN(p), magic);
306 *end = c; 329 *end = c;
307 if (empty) 330 if (empty)
308 goto theend; 331 goto theend;
309 } 332 }
310 333
533 // Avoids a flash when typing "foo\|". 556 // Avoids a flash when typing "foo\|".
534 if (!use_last_pat) 557 if (!use_last_pat)
535 { 558 {
536 next_char = ccline.cmdbuff[skiplen + patlen]; 559 next_char = ccline.cmdbuff[skiplen + patlen];
537 ccline.cmdbuff[skiplen + patlen] = NUL; 560 ccline.cmdbuff[skiplen + patlen] = NUL;
538 if (empty_pattern(ccline.cmdbuff) && !no_hlsearch) 561 if (empty_pattern(ccline.cmdbuff + skiplen, search_delim)
562 && !no_hlsearch)
539 { 563 {
540 redraw_all_later(SOME_VALID); 564 redraw_all_later(SOME_VALID);
541 set_no_hlsearch(TRUE); 565 set_no_hlsearch(TRUE);
542 } 566 }
543 ccline.cmdbuff[skiplen + patlen] = next_char; 567 ccline.cmdbuff[skiplen + patlen] = next_char;