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

Raspunde prin e-mail lui