@@ -137,6 +137,9 @@ _RTLENTRYF
137137#endif
138138sort_func_compare (const void * s1 , const void * s2 );
139139#endif
140+ #ifdef FEAT_SEARCH_EXTRA
141+ static void set_search_match (pos_T * t );
142+ #endif
140143
141144/*
142145 * getcmdline() - accept a command line starting with firstc.
@@ -178,6 +181,9 @@ getcmdline(
178181 colnr_T old_curswant ;
179182 colnr_T old_leftcol ;
180183 linenr_T old_topline ;
184+ pos_T cursor_start ;
185+ pos_T match_start = curwin -> w_cursor ;
186+ pos_T match_end ;
181187# ifdef FEAT_DIFF
182188 int old_topfill ;
183189# endif
@@ -223,7 +229,9 @@ getcmdline(
223229
224230 ccline .overstrike = FALSE; /* always start in insert mode */
225231#ifdef FEAT_SEARCH_EXTRA
232+ clearpos (& match_end );
226233 old_cursor = curwin -> w_cursor ; /* needs to be restored later */
234+ cursor_start = old_cursor ;
227235 old_curswant = curwin -> w_curswant ;
228236 old_leftcol = curwin -> w_leftcol ;
229237 old_topline = curwin -> w_topline ;
@@ -996,6 +1004,15 @@ getcmdline(
9961004
9971005 /* Truncate at the end, required for multi-byte chars. */
9981006 ccline .cmdbuff [ccline .cmdlen ] = NUL ;
1007+ #ifdef FEAT_SEARCH_EXTRA
1008+ if (ccline .cmdlen == 0 )
1009+ old_cursor = cursor_start ;
1010+ else
1011+ {
1012+ old_cursor = match_start ;
1013+ decl (& old_cursor );
1014+ }
1015+ #endif
9991016 redrawcmd ();
10001017 }
10011018 else if (ccline .cmdlen == 0 && c != Ctrl_W
@@ -1021,6 +1038,10 @@ getcmdline(
10211038 msg_col = 0 ;
10221039 msg_putchar (' ' ); /* delete ':' */
10231040 }
1041+ #ifdef FEAT_SEARCH_EXTRA
1042+ if (ccline .cmdlen == 0 )
1043+ old_cursor = cursor_start ;
1044+ #endif
10241045 redraw_cmdline = TRUE;
10251046 goto returncmd ; /* back to cmd mode */
10261047 }
@@ -1104,6 +1125,10 @@ getcmdline(
11041125 ccline .cmdbuff [i ++ ] = ccline .cmdbuff [j ++ ];
11051126 /* Truncate at the end, required for multi-byte chars. */
11061127 ccline .cmdbuff [ccline .cmdlen ] = NUL ;
1128+ #ifdef FEAT_SEARCH_EXTRA
1129+ if (ccline .cmdlen == 0 )
1130+ old_cursor = cursor_start ;
1131+ #endif
11071132 redrawcmd ();
11081133 goto cmdline_changed ;
11091134
@@ -1440,26 +1465,31 @@ getcmdline(
14401465 if (p_is && !cmd_silent && (firstc == '/' || firstc == '?' ))
14411466 {
14421467 /* Add a character from under the cursor for 'incsearch' */
1443- if (did_incsearch
1444- && !equalpos (curwin -> w_cursor , old_cursor ))
1468+ if (did_incsearch )
14451469 {
1446- c = gchar_cursor ();
1447- /* If 'ignorecase' and 'smartcase' are set and the
1448- * command line has no uppercase characters, convert
1449- * the character to lowercase */
1450- if (p_ic && p_scs && !pat_has_uppercase (ccline .cmdbuff ))
1451- c = MB_TOLOWER (c );
1452- if (c != NUL )
1470+ curwin -> w_cursor = match_end ;
1471+ if (!equalpos (curwin -> w_cursor , old_cursor ))
14531472 {
1454- if (c == firstc || vim_strchr ((char_u * )(
1455- p_magic ? "\\^$.*[" : "\\^$" ), c )
1456- != NULL )
1473+ c = gchar_cursor ();
1474+ /* If 'ignorecase' and 'smartcase' are set and the
1475+ * command line has no uppercase characters, convert
1476+ * the character to lowercase */
1477+ if (p_ic && p_scs
1478+ && !pat_has_uppercase (ccline .cmdbuff ))
1479+ c = MB_TOLOWER (c );
1480+ if (c != NUL )
14571481 {
1458- /* put a backslash before special characters */
1459- stuffcharReadbuff (c );
1460- c = '\\' ;
1482+ if (c == firstc || vim_strchr ((char_u * )(
1483+ p_magic ? "\\^$.*[" : "\\^$" ), c )
1484+ != NULL )
1485+ {
1486+ /* put a backslash before special
1487+ * characters */
1488+ stuffcharReadbuff (c );
1489+ c = '\\' ;
1490+ }
1491+ break ;
14611492 }
1462- break ;
14631493 }
14641494 }
14651495 goto cmdline_not_changed ;
@@ -1473,7 +1503,75 @@ getcmdline(
14731503
14741504 case Ctrl_N : /* next match */
14751505 case Ctrl_P : /* previous match */
1476- if (xpc .xp_numfiles > 0 )
1506+ #ifdef FEAT_SEARCH_EXTRA
1507+ if (p_is && !cmd_silent && (firstc == '/' || firstc == '?' ))
1508+ {
1509+ pos_T t ;
1510+ int search_flags = SEARCH_KEEP + SEARCH_NOOF
1511+ + SEARCH_PEEK ;
1512+
1513+ if (char_avail ())
1514+ continue ;
1515+ cursor_off ();
1516+ out_flush ();
1517+ if (c == Ctrl_N )
1518+ {
1519+ t = match_end ;
1520+ search_flags += SEARCH_COL ;
1521+ }
1522+ else
1523+ t = match_start ;
1524+ ++ emsg_off ;
1525+ i = searchit (curwin , curbuf , & t ,
1526+ c == Ctrl_N ? FORWARD : BACKWARD ,
1527+ ccline .cmdbuff , count , search_flags ,
1528+ RE_SEARCH , 0 , NULL );
1529+ -- emsg_off ;
1530+ if (i )
1531+ {
1532+ old_cursor = match_start ;
1533+ match_end = t ;
1534+ match_start = t ;
1535+ if (c == Ctrl_P && firstc == '/' )
1536+ {
1537+ /* move just before the current match, so that
1538+ * when nv_search finishes the cursor will be
1539+ * put back on the match */
1540+ old_cursor = t ;
1541+ (void )decl (& old_cursor );
1542+ }
1543+ if (lt (t , old_cursor ) && c == Ctrl_N )
1544+ {
1545+ /* wrap around */
1546+ old_cursor = t ;
1547+ if (firstc == '?' )
1548+ (void )incl (& old_cursor );
1549+ else
1550+ (void )decl (& old_cursor );
1551+ }
1552+
1553+ set_search_match (& match_end );
1554+ curwin -> w_cursor = match_start ;
1555+ changed_cline_bef_curs ();
1556+ update_topline ();
1557+ validate_cursor ();
1558+ highlight_match = TRUE;
1559+ old_curswant = curwin -> w_curswant ;
1560+ old_leftcol = curwin -> w_leftcol ;
1561+ old_topline = curwin -> w_topline ;
1562+ # ifdef FEAT_DIFF
1563+ old_topfill = curwin -> w_topfill ;
1564+ # endif
1565+ old_botline = curwin -> w_botline ;
1566+ update_screen (NOT_VALID );
1567+ redrawcmdline ();
1568+ }
1569+ else
1570+ vim_beep (BO_ERROR );
1571+ goto cmdline_not_changed ;
1572+ }
1573+ #endif
1574+ else if (xpc .xp_numfiles > 0 )
14771575 {
14781576 if (nextwild (& xpc , (c == Ctrl_P ) ? WILD_PREV : WILD_NEXT ,
14791577 0 , firstc != '@' ) == FAIL )
@@ -1821,19 +1919,11 @@ getcmdline(
18211919 {
18221920 pos_T save_pos = curwin -> w_cursor ;
18231921
1824- /*
1825- * First move cursor to end of match, then to the start. This
1826- * moves the whole match onto the screen when 'nowrap' is set.
1827- */
1828- curwin -> w_cursor .lnum += search_match_lines ;
1829- curwin -> w_cursor .col = search_match_endcol ;
1830- if (curwin -> w_cursor .lnum > curbuf -> b_ml .ml_line_count )
1831- {
1832- curwin -> w_cursor .lnum = curbuf -> b_ml .ml_line_count ;
1833- coladvance ((colnr_T )MAXCOL );
1834- }
1922+ match_start = curwin -> w_cursor ;
1923+ set_search_match (& curwin -> w_cursor );
18351924 validate_cursor ();
18361925 end_pos = curwin -> w_cursor ;
1926+ match_end = end_pos ;
18371927 curwin -> w_cursor = save_pos ;
18381928 }
18391929 else
@@ -1894,6 +1984,8 @@ getcmdline(
18941984 if (did_incsearch )
18951985 {
18961986 curwin -> w_cursor = old_cursor ;
1987+ if (gotesc )
1988+ curwin -> w_cursor = cursor_start ;
18971989 curwin -> w_curswant = old_curswant ;
18981990 curwin -> w_leftcol = old_leftcol ;
18991991 curwin -> w_topline = old_topline ;
@@ -6983,3 +7075,21 @@ script_get(exarg_T *eap, char_u *cmd)
69837075
69847076 return (char_u * )ga .ga_data ;
69857077}
7078+
7079+ #ifdef FEAT_SEARCH_EXTRA
7080+ static void
7081+ set_search_match (pos_T * t )
7082+ {
7083+ /*
7084+ * First move cursor to end of match, then to the start. This
7085+ * moves the whole match onto the screen when 'nowrap' is set.
7086+ */
7087+ t -> lnum += search_match_lines ;
7088+ t -> col = search_match_endcol ;
7089+ if (t -> lnum > curbuf -> b_ml .ml_line_count )
7090+ {
7091+ t -> lnum = curbuf -> b_ml .ml_line_count ;
7092+ coladvance ((colnr_T )MAXCOL );
7093+ }
7094+ }
7095+ #endif
0 commit comments