Mercurial > vim
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; |