Hi Yegappan! On Do, 14 Jul 2016, Yegappan Lakshmanan wrote:
> Hi all, > > My wish list for extending the Vim search feature: > > 1. When searching for a pattern, pressing a key at the search prompt > should jump to the next or previous match. > 2. After jumping multiple times from the search prompt, pressing the > escape key should restore the cursor to the original cursor position > before the search. > 3. Pressing backspace at the search prompt to erase a few characters and > then typing additional characters should start the search from the > previously matched position and not from the original position. > 4. As characters are typed at the search prompt, all the matching text > should be highlighted (multiple matches). This can be turned on/off by > an option. > > I know there are some Vim plugins that support some of these features. > But it will be useful to extend the built-in Vim feature to support these > features. Here is an experimental patch, that does this using Ctrl-N Ctrl-P in search mode, when 'incsearch' is set. I am not super happy, about depending on 'incsearch', but on the other hand, Ctrl-L already only works when 'incsearch' is set. Also I am open to suggestions for alternative keys, although I must admit, Ctrl-N/Ctrl-P seem like logical choices. It doesn't do everything you want, but it seems to work well for me. I made it so, that pressing enter will remain at the current selected match, which seems obvious and so I did not need to introduce a new key function. Pressing ESC however will return the cursor to the position where you started with the search. This was just written very fast, I am pretty sure, there are some bugs lying around and also tests are missing. But if this turns out to be useful, I'll work more on it (and add a test of course). Comments welcome, Best, Christian -- Ja, mach nur einen Plan, sei nur ein großes Licht, und mach noch einen zweiten Plan, gehn tun sie beide nicht. -- Berthold Brecht (Dreigroschenoper) -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
From ae49fd135effecee212640a5b1e71c56834d49d5 Mon Sep 17 00:00:00 2001 From: Christian Brabandt <c...@256bit.org> Date: Tue, 26 Jul 2016 11:18:51 +0200 Subject: [PATCH] Make Ctrl-N/P jump to next/previous search match Currently, you cannot move from one match to the next match when doing a search '/' or '?'. This patch adds the functionality to use 'Ctrl-N' to move the cursor to the next match, if 'insearch' is set. Similarily 'Ctrl-P' will move to the previous match. Also c_CTRL-N and c_CTRL-P are already used to move within in history of search patterns, I have for now made them something different in search mode, when incsearch is set. This is because c_CTRL-L already does something useful in search mode and second, because Ctrl-N and Ctrl-P are already used to select next/previous match in completion mode so it seems logically to also extend their use in search mode. --- runtime/doc/cmdline.txt | 8 +++++ src/ex_getln.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt index 8186678..9fbdbd0 100644 --- a/runtime/doc/cmdline.txt +++ b/runtime/doc/cmdline.txt @@ -409,11 +409,19 @@ CTRL-D List names that match the pattern in front of the cursor. *c_CTRL-N* CTRL-N After using 'wildchar' which got multiple matches, go to next match. Otherwise recall more recent command-line from history. + */_CTRL-N* + When 'incsearch' is set, entering a search pattern for "/" or + "?" and the current match is displayed then CTRL-N will move + to the next match. <S-Tab> *c_CTRL-P* *c_<S-Tab>* CTRL-P After using 'wildchar' which got multiple matches, go to previous match. Otherwise recall older command-line from history. <S-Tab> only works with the GUI, on the Amiga and with MS-DOS. + */_CTRL-P* + When 'incsearch' is set, entering a search pattern for "/" or + "?" and the current match is displayed then CTRL-N will move + to the previous match. *c_CTRL-A* CTRL-A All names that match the pattern in front of the cursor are inserted. diff --git a/src/ex_getln.c b/src/ex_getln.c index 642e090..66fd313 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -178,6 +178,8 @@ getcmdline( colnr_T old_curswant; colnr_T old_leftcol; linenr_T old_topline; + int did_incs_move = FALSE; + pos_T cursor_start; # ifdef FEAT_DIFF int old_topfill; # endif @@ -224,6 +226,7 @@ getcmdline( ccline.overstrike = FALSE; /* always start in insert mode */ #ifdef FEAT_SEARCH_EXTRA old_cursor = curwin->w_cursor; /* needs to be restored later */ + cursor_start = old_cursor; old_curswant = curwin->w_curswant; old_leftcol = curwin->w_leftcol; old_topline = curwin->w_topline; @@ -1441,8 +1444,23 @@ getcmdline( { /* Add a character from under the cursor for 'incsearch' */ if (did_incsearch - && !equalpos(curwin->w_cursor, old_cursor)) + && (!equalpos(curwin->w_cursor, old_cursor) || did_incs_move)) { + if (did_incs_move) + { + /* First move cursor to end of match, then to the start. This + * moves the whole match onto the screen when 'nowrap' is set. + */ + curwin->w_cursor.lnum += search_match_lines; + curwin->w_cursor.col = search_match_endcol; + if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) + { + curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; + coladvance((colnr_T)MAXCOL); + } + did_incs_move = FALSE; + } + c = gchar_cursor(); /* If 'ignorecase' and 'smartcase' are set and the * command line has no uppercase characters, convert @@ -1473,7 +1491,60 @@ getcmdline( case Ctrl_N: /* next match */ case Ctrl_P: /* previous match */ - if (xpc.xp_numfiles > 0) +#ifdef FEAT_SEARCH_EXTRA + if (p_is && !cmd_silent && (firstc == '/' || firstc == '?')) + { + int old_ws = p_ws; + pos_T t; + + if (char_avail()) + continue; + cursor_off(); + out_flush(); + ++emsg_off; + p_ws = TRUE; + t = curwin->w_cursor; + if (!did_incs_move && c == Ctrl_P) + curwin->w_cursor = old_cursor; + + i = do_search(NULL, c == Ctrl_N ? '/' : '?', ccline.cmdbuff, count, + SEARCH_KEEP + SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK, NULL + ); + p_ws = old_ws; + --emsg_off; + if (i) + { + did_incs_move = TRUE; + if (c == Ctrl_P) + { + /* move just before the previous match, so that when nv_search finishes + * the cursor will be put back on the match */ + (void)searchit(curwin, curbuf, &t, BACKWARD, ccline.cmdbuff, count, + SEARCH_KEEP + SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK + SEARCH_COL, + RE_SEARCH, 0, NULL); + (void)decl(&t); + } + old_cursor = t; + changed_cline_bef_curs(); + update_topline(); + validate_cursor(); + highlight_match = TRUE; + old_curswant = curwin->w_curswant; + old_leftcol = curwin->w_leftcol; + old_topline = curwin->w_topline; +# ifdef FEAT_DIFF + old_topfill = curwin->w_topfill; +# endif + old_botline = curwin->w_botline; + update_screen(NOT_VALID); + redrawcmdline(); + } + goto cmdline_not_changed; + + + } +#endif + else if (xpc.xp_numfiles > 0) { if (nextwild(&xpc, (c == Ctrl_P) ? WILD_PREV : WILD_NEXT, 0, firstc != '@') == FAIL) @@ -1894,6 +1965,8 @@ returncmd: if (did_incsearch) { curwin->w_cursor = old_cursor; + if (gotesc) + curwin->w_cursor = cursor_start; curwin->w_curswant = old_curswant; curwin->w_leftcol = old_leftcol; curwin->w_topline = old_topline; -- 2.1.4