diff options
author | Bram Moolenaar <Bram@vim.org> | 2016-08-26 19:13:46 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2016-08-26 19:13:46 +0200 |
commit | 4d6f32cbfbaf324ac4a25c0206a5db0e9f7a48f7 (patch) | |
tree | 1f99127dcddcda19da0a408a32612bc33f968fa5 /src/ex_getln.c | |
parent | f1f0792e55e72cdc7c833b30f565a9b02f18bb1e (diff) | |
download | vim-4d6f32cbfbaf324ac4a25c0206a5db0e9f7a48f7.zip |
patch 7.4.2259
Problem: With 'incsearch' can only see the next match.
Solution: Make CTRL-N/CTRL-P move to the previous/next match. (Christian
Brabandt)
Diffstat (limited to 'src/ex_getln.c')
-rw-r--r-- | src/ex_getln.c | 166 |
1 files changed, 138 insertions, 28 deletions
diff --git a/src/ex_getln.c b/src/ex_getln.c index 642e09010..925e2f490 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -137,6 +137,9 @@ _RTLENTRYF #endif sort_func_compare(const void *s1, const void *s2); #endif +#ifdef FEAT_SEARCH_EXTRA +static void set_search_match(pos_T *t); +#endif /* * getcmdline() - accept a command line starting with firstc. @@ -178,6 +181,9 @@ getcmdline( colnr_T old_curswant; colnr_T old_leftcol; linenr_T old_topline; + pos_T cursor_start; + pos_T match_start = curwin->w_cursor; + pos_T match_end; # ifdef FEAT_DIFF int old_topfill; # endif @@ -223,7 +229,9 @@ getcmdline( ccline.overstrike = FALSE; /* always start in insert mode */ #ifdef FEAT_SEARCH_EXTRA + clearpos(&match_end); 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 +1004,15 @@ 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; + else + { + old_cursor = match_start; + decl(&old_cursor); + } +#endif redrawcmd(); } else if (ccline.cmdlen == 0 && c != Ctrl_W @@ -1021,6 +1038,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 +1125,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; @@ -1440,26 +1465,31 @@ getcmdline( if (p_is && !cmd_silent && (firstc == '/' || firstc == '?')) { /* Add a character from under the cursor for 'incsearch' */ - if (did_incsearch - && !equalpos(curwin->w_cursor, old_cursor)) + if (did_incsearch) { - c = gchar_cursor(); - /* If 'ignorecase' and 'smartcase' are set and the - * command line has no uppercase characters, convert - * the character to lowercase */ - if (p_ic && p_scs && !pat_has_uppercase(ccline.cmdbuff)) - c = MB_TOLOWER(c); - if (c != NUL) + curwin->w_cursor = match_end; + if (!equalpos(curwin->w_cursor, old_cursor)) { - if (c == firstc || vim_strchr((char_u *)( - p_magic ? "\\^$.*[" : "\\^$"), c) - != NULL) + c = gchar_cursor(); + /* If 'ignorecase' and 'smartcase' are set and the + * command line has no uppercase characters, convert + * the character to lowercase */ + if (p_ic && p_scs + && !pat_has_uppercase(ccline.cmdbuff)) + c = MB_TOLOWER(c); + if (c != NUL) { - /* put a backslash before special characters */ - stuffcharReadbuff(c); - c = '\\'; + if (c == firstc || vim_strchr((char_u *)( + p_magic ? "\\^$.*[" : "\\^$"), c) + != NULL) + { + /* put a backslash before special + * characters */ + stuffcharReadbuff(c); + c = '\\'; + } + break; } - break; } } goto cmdline_not_changed; @@ -1473,7 +1503,75 @@ 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; + int search_flags = SEARCH_KEEP + SEARCH_NOOF + + SEARCH_PEEK; + + if (char_avail()) + continue; + cursor_off(); + out_flush(); + if (c == Ctrl_N) + { + t = match_end; + search_flags += SEARCH_COL; + } + else + t = match_start; + ++emsg_off; + i = searchit(curwin, curbuf, &t, + c == Ctrl_N ? FORWARD : BACKWARD, + ccline.cmdbuff, count, search_flags, + RE_SEARCH, 0, NULL); + --emsg_off; + if (i) + { + old_cursor = match_start; + match_end = t; + match_start = t; + 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); + } + if (lt(t, old_cursor) && c == Ctrl_N) + { + /* wrap around */ + old_cursor = t; + if (firstc == '?') + (void)incl(&old_cursor); + else + (void)decl(&old_cursor); + } + + set_search_match(&match_end); + curwin->w_cursor = match_start; + 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) @@ -1821,19 +1919,11 @@ cmdline_changed: { pos_T save_pos = curwin->w_cursor; - /* - * 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); - } + match_start = curwin->w_cursor; + set_search_match(&curwin->w_cursor); validate_cursor(); end_pos = curwin->w_cursor; + match_end = end_pos; curwin->w_cursor = save_pos; } else @@ -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; @@ -6983,3 +7075,21 @@ script_get(exarg_T *eap, char_u *cmd) return (char_u *)ga.ga_data; } + +#ifdef FEAT_SEARCH_EXTRA + static void +set_search_match(pos_T *t) +{ + /* + * First move cursor to end of match, then to the start. This + * moves the whole match onto the screen when 'nowrap' is set. + */ + t->lnum += search_match_lines; + t->col = search_match_endcol; + if (t->lnum > curbuf->b_ml.ml_line_count) + { + t->lnum = curbuf->b_ml.ml_line_count; + coladvance((colnr_T)MAXCOL); + } +} +#endif |