On Do, 28 Jul 2016, Bram Moolenaar wrote:
> I think it should. Most users will have 'wrapscan' on, since it is the
> default. If someone switches it off he must have a reason for it.
okay, fixed with the latest version
Best,
Christian
--
Das Gedruckte übt einen mächtigen Druck aus, der besondere Glaube
ans Gedruckte ist einer der mächtigsten Aberglauben.
-- Ludwig Marcuse (Argumente und Rezepte)
--
--
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 [email protected].
For more options, visit https://groups.google.com/d/optout.
From 74680771664103cf043a11cf96e47eb9693b9a51 Mon Sep 17 00:00:00 2001
From: Christian Brabandt <[email protected]>
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.
Bugfixes: - works correctly with Ctrl-P after ? search
- after clearing the search command line, starts searching
back at the original position
- works correctly, when using \? in a forward search / and
then jumping backwards using Ctrl-P
- obey to 'wrapscan' setting
- beep, when no further match is found
---
runtime/doc/cmdline.txt | 9 +++++
src/ex_getln.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 103 insertions(+), 2 deletions(-)
diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt
index 8186678..83bec9e 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 (does not take |search-offset| into account)
<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 (does not take |search-offset| into account).
*c_CTRL-A*
CTRL-A All names that match the pattern in front of the cursor are
inserted.
@@ -423,6 +431,7 @@ CTRL-L A match is done on the pattern in front of the cursor. If
If there are multiple matches the longest common part is
inserted in place of the pattern. If the result is shorter
than the pattern, no completion is done.
+ */_CTRL-L*
When 'incsearch' is set, entering a search pattern for "/" or
"?" and the current match is displayed then CTRL-L will add
one character from the end of the current match. If
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 642e090..7862b0e 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;
@@ -996,6 +999,10 @@ getcmdline(
/* Truncate at the end, required for multi-byte chars. */
ccline.cmdbuff[ccline.cmdlen] = NUL;
+#ifdef FEAT_SEARCH_EXTRA
+ if (ccline.cmdlen == 0)
+ old_cursor = cursor_start;
+#endif
redrawcmd();
}
else if (ccline.cmdlen == 0 && c != Ctrl_W
@@ -1021,6 +1028,10 @@ getcmdline(
msg_col = 0;
msg_putchar(' '); /* delete ':' */
}
+#ifdef FEAT_SEARCH_EXTRA
+ if (ccline.cmdlen == 0)
+ old_cursor = cursor_start;
+#endif
redraw_cmdline = TRUE;
goto returncmd; /* back to cmd mode */
}
@@ -1104,6 +1115,10 @@ getcmdline(
ccline.cmdbuff[i++] = ccline.cmdbuff[j++];
/* Truncate at the end, required for multi-byte chars. */
ccline.cmdbuff[ccline.cmdlen] = NUL;
+#ifdef FEAT_SEARCH_EXTRA
+ if (ccline.cmdlen == 0)
+ old_cursor = cursor_start;
+#endif
redrawcmd();
goto cmdline_changed;
@@ -1441,8 +1456,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 +1503,67 @@ 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 == '?'))
+ {
+ pos_T t;
+
+ if (char_avail())
+ continue;
+ cursor_off();
+ out_flush();
+ ++emsg_off;
+ t = curwin->w_cursor;
+ if (!did_incs_move && c == Ctrl_P)
+ {
+ t = old_cursor;
+ if (firstc == '?')
+ {
+ (void)searchit(curwin, curbuf, &t, BACKWARD, ccline.cmdbuff, count,
+ SEARCH_KEEP + SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK + SEARCH_COL,
+ RE_SEARCH, 0, NULL);
+ old_cursor = t;
+ }
+ }
+
+ i = searchit(curwin, curbuf, &t, c == Ctrl_N ? FORWARD : BACKWARD,
+ ccline.cmdbuff, count, SEARCH_KEEP + SEARCH_NOOF + SEARCH_PEEK,
+ RE_SEARCH, 0, NULL);
+ --emsg_off;
+ if (i && !equalpos(t, curwin->w_cursor))
+ {
+ did_incs_move = TRUE;
+ old_cursor = curwin->w_cursor;
+ if (c == Ctrl_P && firstc == '/')
+ {
+ /* move just before the current match, so that when nv_search finishes
+ * the cursor will be put back on the match */
+ old_cursor = t;
+ (void)decl(&old_cursor);
+ }
+ curwin->w_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();
+ }
+ else
+ vim_beep(BO_ERROR);
+ 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 +1984,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