comparison src/ex_getln.c @ 14528:58ca11610819 v8.1.0277

patch 8.1.0277: 'incsearch' highlighting wrong in a few cases commit https://github.com/vim/vim/commit/c7f08b7ee1c1ff2080d425c2fcdb6907c26fc98e Author: Bram Moolenaar <Bram@vim.org> Date: Sun Aug 12 17:39:14 2018 +0200 patch 8.1.0277: 'incsearch' highlighting wrong in a few cases Problem: 'incsearch' highlighting wrong in a few cases. Solution: Fix using last search pattern. Restore highlighting when changing command. (issue #3321)
author Christian Brabandt <cb@256bit.org>
date Sun, 12 Aug 2018 17:45:04 +0200
parents e36d6e01708c
children 60e0022e6e5d
comparison
equal deleted inserted replaced
14527:6fc131355f0d 14528:58ca11610819
298 || STRNCMP(cmd, "global", p - cmd) == 0 298 || STRNCMP(cmd, "global", p - cmd) == 0
299 || STRNCMP(cmd, "vglobal", p - cmd) == 0)) 299 || STRNCMP(cmd, "vglobal", p - cmd) == 0))
300 { 300 {
301 delim = *p++; 301 delim = *p++;
302 end = skip_regexp(p, delim, p_magic, NULL); 302 end = skip_regexp(p, delim, p_magic, NULL);
303 if (end > p) 303 if (end > p || *end == delim)
304 { 304 {
305 char_u *dummy; 305 char_u *dummy;
306 exarg_T ea; 306 exarg_T ea;
307 pos_T save_cursor = curwin->w_cursor; 307 pos_T save_cursor = curwin->w_cursor;
308 308
339 } 339 }
340 340
341 return FALSE; 341 return FALSE;
342 } 342 }
343 343
344 static void
345 finish_incsearch_highlighting(
346 int gotesc,
347 incsearch_state_T *is_state,
348 int call_update_screen)
349 {
350 if (is_state->did_incsearch)
351 {
352 is_state->did_incsearch = FALSE;
353 if (gotesc)
354 curwin->w_cursor = is_state->save_cursor;
355 else
356 {
357 if (!EQUAL_POS(is_state->save_cursor, is_state->search_start))
358 {
359 // put the '" mark at the original position
360 curwin->w_cursor = is_state->save_cursor;
361 setpcmark();
362 }
363 curwin->w_cursor = is_state->search_start;
364 }
365 restore_viewstate(&is_state->old_viewstate);
366 highlight_match = FALSE;
367 validate_cursor(); /* needed for TAB */
368 if (call_update_screen)
369 update_screen(SOME_VALID);
370 else
371 redraw_all_later(SOME_VALID);
372 }
373 }
374
344 /* 375 /*
345 * Do 'incsearch' highlighting if desired. 376 * Do 'incsearch' highlighting if desired.
346 */ 377 */
347 static void 378 static void
348 may_do_incsearch_highlighting( 379 may_do_incsearch_highlighting(
355 pos_T end_pos; 386 pos_T end_pos;
356 struct cmdline_info save_ccline; 387 struct cmdline_info save_ccline;
357 #ifdef FEAT_RELTIME 388 #ifdef FEAT_RELTIME
358 proftime_T tm; 389 proftime_T tm;
359 #endif 390 #endif
360 int c; 391 int next_char;
392 int use_last_pat;
361 393
362 if (!do_incsearch_highlighting(firstc, is_state, &skiplen, &patlen)) 394 if (!do_incsearch_highlighting(firstc, is_state, &skiplen, &patlen))
395 {
396 finish_incsearch_highlighting(FALSE, is_state, TRUE);
363 return; 397 return;
398 }
364 399
365 // If there is a character waiting, search and redraw later. 400 // If there is a character waiting, search and redraw later.
366 if (char_avail()) 401 if (char_avail())
367 { 402 {
368 is_state->incsearch_postponed = TRUE; 403 is_state->incsearch_postponed = TRUE;
379 curwin->w_cursor.lnum = search_first_line; 414 curwin->w_cursor.lnum = search_first_line;
380 curwin->w_cursor.col = 0; 415 curwin->w_cursor.col = 0;
381 } 416 }
382 save_last_search_pattern(); 417 save_last_search_pattern();
383 418
384 // If there is no command line, don't do anything. 419 // Use the previous pattern for ":s//".
385 if (patlen == 0) 420 next_char = ccline.cmdbuff[skiplen + patlen];
421 use_last_pat = patlen == 0 && skiplen > 0
422 && ccline.cmdbuff[skiplen - 1] == next_char;
423
424 // If there is no pattern, don't do anything.
425 if (patlen == 0 && !use_last_pat)
386 { 426 {
387 i = 0; 427 i = 0;
388 set_no_hlsearch(TRUE); // turn off previous highlight 428 set_no_hlsearch(TRUE); // turn off previous highlight
389 redraw_all_later(SOME_VALID); 429 redraw_all_later(SOME_VALID);
390 } 430 }
401 #endif 441 #endif
402 if (!p_hls) 442 if (!p_hls)
403 search_flags += SEARCH_KEEP; 443 search_flags += SEARCH_KEEP;
404 if (search_first_line != 0) 444 if (search_first_line != 0)
405 search_flags += SEARCH_START; 445 search_flags += SEARCH_START;
406 c = ccline.cmdbuff[skiplen + patlen];
407 ccline.cmdbuff[skiplen + patlen] = NUL; 446 ccline.cmdbuff[skiplen + patlen] = NUL;
408 i = do_search(NULL, firstc == ':' ? '/' : firstc, 447 i = do_search(NULL, firstc == ':' ? '/' : firstc,
409 ccline.cmdbuff + skiplen, count, search_flags, 448 ccline.cmdbuff + skiplen, count, search_flags,
410 #ifdef FEAT_RELTIME 449 #ifdef FEAT_RELTIME
411 &tm, NULL 450 &tm, NULL
412 #else 451 #else
413 NULL, NULL 452 NULL, NULL
414 #endif 453 #endif
415 ); 454 );
416 ccline.cmdbuff[skiplen + patlen] = c; 455 ccline.cmdbuff[skiplen + patlen] = next_char;
417 --emsg_off; 456 --emsg_off;
418 457
419 if (curwin->w_cursor.lnum < search_first_line 458 if (curwin->w_cursor.lnum < search_first_line
420 || curwin->w_cursor.lnum > search_last_line) 459 || curwin->w_cursor.lnum > search_last_line)
421 // match outside of address range 460 // match outside of address range
457 else 496 else
458 end_pos = curwin->w_cursor; // shutup gcc 4 497 end_pos = curwin->w_cursor; // shutup gcc 4
459 498
460 // Disable 'hlsearch' highlighting if the pattern matches everything. 499 // Disable 'hlsearch' highlighting if the pattern matches everything.
461 // Avoids a flash when typing "foo\|". 500 // Avoids a flash when typing "foo\|".
462 c = ccline.cmdbuff[skiplen + patlen]; 501 if (!use_last_pat)
463 ccline.cmdbuff[skiplen + patlen] = NUL; 502 {
464 if (empty_pattern(ccline.cmdbuff)) 503 next_char = ccline.cmdbuff[skiplen + patlen];
465 set_no_hlsearch(TRUE); 504 ccline.cmdbuff[skiplen + patlen] = NUL;
466 ccline.cmdbuff[skiplen + patlen] = c; 505 if (empty_pattern(ccline.cmdbuff))
506 set_no_hlsearch(TRUE);
507 ccline.cmdbuff[skiplen + patlen] = next_char;
508 }
467 509
468 validate_cursor(); 510 validate_cursor();
469 // May redraw the status line to show the cursor position. 511 // May redraw the status line to show the cursor position.
470 if (p_ru && curwin->w_status_height > 0) 512 if (p_ru && curwin->w_status_height > 0)
471 curwin->w_redr_status = TRUE; 513 curwin->w_redr_status = TRUE;
625 return FAIL; 667 return FAIL;
626 } 668 }
627 } 669 }
628 } 670 }
629 return OK; 671 return OK;
630 }
631
632 static void
633 finish_incsearch_highlighting(int gotesc, incsearch_state_T *is_state)
634 {
635 if (is_state->did_incsearch)
636 {
637 if (gotesc)
638 curwin->w_cursor = is_state->save_cursor;
639 else
640 {
641 if (!EQUAL_POS(is_state->save_cursor, is_state->search_start))
642 {
643 // put the '" mark at the original position
644 curwin->w_cursor = is_state->save_cursor;
645 setpcmark();
646 }
647 curwin->w_cursor = is_state->search_start;
648 }
649 restore_viewstate(&is_state->old_viewstate);
650 highlight_match = FALSE;
651 validate_cursor(); /* needed for TAB */
652 redraw_all_later(SOME_VALID);
653 }
654 } 672 }
655 #endif 673 #endif
656 674
657 /* 675 /*
658 * getcmdline() - accept a command line starting with firstc. 676 * getcmdline() - accept a command line starting with firstc.
2299 2317
2300 ExpandCleanup(&xpc); 2318 ExpandCleanup(&xpc);
2301 ccline.xpc = NULL; 2319 ccline.xpc = NULL;
2302 2320
2303 #ifdef FEAT_SEARCH_EXTRA 2321 #ifdef FEAT_SEARCH_EXTRA
2304 finish_incsearch_highlighting(gotesc, &is_state); 2322 finish_incsearch_highlighting(gotesc, &is_state, FALSE);
2305 #endif 2323 #endif
2306 2324
2307 if (ccline.cmdbuff != NULL) 2325 if (ccline.cmdbuff != NULL)
2308 { 2326 {
2309 /* 2327 /*