if (p_is && !cmd_silent && (firstc == '/' || firstc == '?'))
{
pos_T t;
- int search_flags = SEARCH_KEEP + SEARCH_NOOF;
+ int search_flags = SEARCH_NOOF;
+ save_last_search_pattern();
cursor_off();
out_flush();
if (c == Ctrl_G)
}
else
t = match_start;
+ if (!p_hls)
+ search_flags += SEARCH_KEEP;
++emsg_off;
i = searchit(curwin, curbuf, &t,
c == Ctrl_G ? FORWARD : BACKWARD,
# endif
old_botline = curwin->w_botline;
update_screen(NOT_VALID);
+ restore_last_search_pattern();
redrawcmdline();
}
else
}
incsearch_postponed = FALSE;
curwin->w_cursor = search_start; /* start at old position */
+ save_last_search_pattern();
/* If there is no command line, don't do anything */
if (ccline.cmdlen == 0)
+ {
i = 0;
+ SET_NO_HLSEARCH(TRUE); /* turn off previous highlight */
+ }
else
{
+ int search_flags = SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK;
cursor_off(); /* so the user knows we're busy */
out_flush();
++emsg_off; /* So it doesn't beep if bad expr */
/* Set the time limit to half a second. */
profile_setlimit(500L, &tm);
#endif
+ if (!p_hls)
+ search_flags += SEARCH_KEEP;
i = do_search(NULL, firstc, ccline.cmdbuff, count,
- SEARCH_KEEP + SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK,
+ search_flags,
#ifdef FEAT_RELTIME
&tm, NULL
#else
save_cmdline(&save_ccline);
update_screen(SOME_VALID);
restore_cmdline(&save_ccline);
+ restore_last_search_pattern();
/* Leave it at the end to make CTRL-R CTRL-W work. */
if (i != 0)
#if defined(FEAT_AUTOCMD) || defined(FEAT_EVAL) || defined(PROTO)
/* copy of spats[], for keeping the search patterns while executing autocmds */
static struct spat saved_spats[2];
-static int saved_last_idx = 0;
+#endif
# ifdef FEAT_SEARCH_EXTRA
+/* copy of spats[RE_SEARCH], for keeping the search patterns while incremental
+ * searching */
+static struct spat saved_last_search_spat;
+static int saved_last_idx = 0;
static int saved_no_hlsearch = 0;
# endif
-#endif
static char_u *mr_pattern = NULL; /* pattern used by search_regcomp() */
#ifdef FEAT_RIGHTLEFT
{
vim_free(spats[0].pat);
spats[0] = saved_spats[0];
-#if defined(FEAT_EVAL)
+# if defined(FEAT_EVAL)
set_vv_searchforward();
-#endif
+# endif
vim_free(spats[1].pat);
spats[1] = saved_spats[1];
last_idx = saved_last_idx;
}
#endif
+#ifdef FEAT_SEARCH_EXTRA
+/*
+ * Save and restore the search pattern for incremental highlight search
+ * feature.
+ *
+ * It's similar but differnt from save_search_patterns() and
+ * restore_search_patterns(), because the search pattern must be restored when
+ * cannceling incremental searching even if it's called inside user functions.
+ */
+ void
+save_last_search_pattern(void)
+{
+ saved_last_search_spat = spats[RE_SEARCH];
+ if (spats[RE_SEARCH].pat != NULL)
+ saved_last_search_spat.pat = vim_strsave(spats[RE_SEARCH].pat);
+ saved_last_idx = last_idx;
+ saved_no_hlsearch = no_hlsearch;
+}
+
+ void
+restore_last_search_pattern(void)
+{
+ vim_free(spats[RE_SEARCH].pat);
+ spats[RE_SEARCH] = saved_last_search_spat;
+# if defined(FEAT_EVAL)
+ set_vv_searchforward();
+# endif
+ last_idx = saved_last_idx;
+ SET_NO_HLSEARCH(saved_no_hlsearch);
+}
+#endif
+
/*
* Return TRUE when case should be ignored for search pattern "pat".
* Uses the 'ignorecase' and 'smartcase' options.
" Test for the search command
+source shared.vim
+
func Test_search_cmdline()
if !exists('+incsearch')
return
set undolevels&
enew!
endfunc
+
+func Test_search_cmdline_incsearch_highlight()
+ if !exists('+incsearch')
+ return
+ endif
+ set incsearch hlsearch
+ " need to disable char_avail,
+ " so that expansion of commandline works
+ call test_override("char_avail", 1)
+ new
+ call setline(1, ['aaa 1 the first', ' 2 the second', ' 3 the third'])
+
+ 1
+ call feedkeys("/second\<cr>", 'tx')
+ call assert_equal('second', @/)
+ call assert_equal(' 2 the second', getline('.'))
+
+ " Canceling search won't change @/
+ 1
+ let @/ = 'last pattern'
+ call feedkeys("/third\<C-c>", 'tx')
+ call assert_equal('last pattern', @/)
+ call feedkeys("/third\<Esc>", 'tx')
+ call assert_equal('last pattern', @/)
+ call feedkeys("/3\<bs>\<bs>", 'tx')
+ call assert_equal('last pattern', @/)
+ call feedkeys("/third\<c-g>\<c-t>\<Esc>", 'tx')
+ call assert_equal('last pattern', @/)
+
+ " clean up
+ set noincsearch nohlsearch
+ bw!
+endfunc
+
+func Test_search_cmdline_incsearch_highlight_attr()
+ if !exists('+incsearch') || !has('terminal') || has('gui_running')
+ return
+ endif
+ let h = winheight(0)
+ if h < 3
+ return
+ endif
+ let g:buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': 3})
+
+ " Prepare buffer text
+ let lines = ['abb vim vim vi', 'vimvivim']
+ call term_sendkeys(g:buf, 'i' . join(lines, "\n") . "\<esc>gg0")
+ call term_wait(g:buf, 200)
+ call assert_equal(lines[0], term_getline(g:buf, 1))
+
+ " Get attr of normal(a0), incsearch(a1), hlsearch(a2) highlight
+ call term_sendkeys(g:buf, ":set incsearch hlsearch\<cr>")
+ call term_sendkeys(g:buf, '/b')
+ call term_wait(g:buf, 200)
+ let screen_line1 = term_scrape(g:buf, 1)
+ call assert_true(len(screen_line1) > 2)
+ " a0: attr_normal
+ let a0 = screen_line1[0].attr
+ " a1: attr_incsearch
+ let a1 = screen_line1[1].attr
+ " a2: attr_hlsearch
+ let a2 = screen_line1[2].attr
+ call assert_notequal(a0, a1)
+ call assert_notequal(a0, a2)
+ call assert_notequal(a1, a2)
+ call term_sendkeys(g:buf, "\<cr>gg0")
+
+ " Test incremental highlight search
+ call term_sendkeys(g:buf, "/vim")
+ call term_wait(g:buf, 200)
+ " Buffer:
+ " abb vim vim vi
+ " vimvivim
+ " Search: /vim
+ let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a2,a2,a2,a0,a0,a0]
+ let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
+ call assert_equal(attr_line1, map(term_scrape(g:buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
+ call assert_equal(attr_line2, map(term_scrape(g:buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
+
+ " Test <C-g>
+ call term_sendkeys(g:buf, "\<C-g>\<C-g>")
+ call term_wait(g:buf, 200)
+ let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0]
+ let attr_line2 = [a1,a1,a1,a0,a0,a2,a2,a2]
+ call assert_equal(attr_line1, map(term_scrape(g:buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
+ call assert_equal(attr_line2, map(term_scrape(g:buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
+
+ " Test <C-t>
+ call term_sendkeys(g:buf, "\<C-t>")
+ call term_wait(g:buf, 200)
+ let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a1,a1,a1,a0,a0,a0]
+ let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
+ call assert_equal(attr_line1, map(term_scrape(g:buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
+ call assert_equal(attr_line2, map(term_scrape(g:buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
+
+ " Type Enter and a1(incsearch highlight) should become a2(hlsearch highlight)
+ call term_sendkeys(g:buf, "\<cr>")
+ call term_wait(g:buf, 200)
+ let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0]
+ let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
+ call assert_equal(attr_line1, map(term_scrape(g:buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
+ call assert_equal(attr_line2, map(term_scrape(g:buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
+
+ " Test nohlsearch. a2(hlsearch highlight) should become a0(normal highlight)
+ call term_sendkeys(g:buf, ":1\<cr>")
+ call term_sendkeys(g:buf, ":set nohlsearch\<cr>")
+ call term_sendkeys(g:buf, "/vim")
+ call term_wait(g:buf, 200)
+ let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a0,a0,a0,a0,a0,a0]
+ let attr_line2 = [a0,a0,a0,a0,a0,a0,a0,a0]
+ call assert_equal(attr_line1, map(term_scrape(g:buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
+ call assert_equal(attr_line2, map(term_scrape(g:buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
+
+ bwipe!
+endfunc