Mercurial > vim
comparison src/ex_getln.c @ 9971:98b39d2eb895 v7.4.2259
commit https://github.com/vim/vim/commit/4d6f32cbfbaf324ac4a25c0206a5db0e9f7a48f7
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Aug 26 19:13:46 2016 +0200
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)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Fri, 26 Aug 2016 19:15:07 +0200 |
parents | 69ed2c9d34a6 |
children | e448370630b2 |
comparison
equal
deleted
inserted
replaced
9970:c57383365947 | 9971:98b39d2eb895 |
---|---|
135 #ifdef __BORLANDC__ | 135 #ifdef __BORLANDC__ |
136 _RTLENTRYF | 136 _RTLENTRYF |
137 #endif | 137 #endif |
138 sort_func_compare(const void *s1, const void *s2); | 138 sort_func_compare(const void *s1, const void *s2); |
139 #endif | 139 #endif |
140 #ifdef FEAT_SEARCH_EXTRA | |
141 static void set_search_match(pos_T *t); | |
142 #endif | |
140 | 143 |
141 /* | 144 /* |
142 * getcmdline() - accept a command line starting with firstc. | 145 * getcmdline() - accept a command line starting with firstc. |
143 * | 146 * |
144 * firstc == ':' get ":" command line. | 147 * firstc == ':' get ":" command line. |
176 #ifdef FEAT_SEARCH_EXTRA | 179 #ifdef FEAT_SEARCH_EXTRA |
177 pos_T old_cursor; | 180 pos_T old_cursor; |
178 colnr_T old_curswant; | 181 colnr_T old_curswant; |
179 colnr_T old_leftcol; | 182 colnr_T old_leftcol; |
180 linenr_T old_topline; | 183 linenr_T old_topline; |
184 pos_T cursor_start; | |
185 pos_T match_start = curwin->w_cursor; | |
186 pos_T match_end; | |
181 # ifdef FEAT_DIFF | 187 # ifdef FEAT_DIFF |
182 int old_topfill; | 188 int old_topfill; |
183 # endif | 189 # endif |
184 linenr_T old_botline; | 190 linenr_T old_botline; |
185 int did_incsearch = FALSE; | 191 int did_incsearch = FALSE; |
221 cmd_hkmap = 0; | 227 cmd_hkmap = 0; |
222 #endif | 228 #endif |
223 | 229 |
224 ccline.overstrike = FALSE; /* always start in insert mode */ | 230 ccline.overstrike = FALSE; /* always start in insert mode */ |
225 #ifdef FEAT_SEARCH_EXTRA | 231 #ifdef FEAT_SEARCH_EXTRA |
232 clearpos(&match_end); | |
226 old_cursor = curwin->w_cursor; /* needs to be restored later */ | 233 old_cursor = curwin->w_cursor; /* needs to be restored later */ |
234 cursor_start = old_cursor; | |
227 old_curswant = curwin->w_curswant; | 235 old_curswant = curwin->w_curswant; |
228 old_leftcol = curwin->w_leftcol; | 236 old_leftcol = curwin->w_leftcol; |
229 old_topline = curwin->w_topline; | 237 old_topline = curwin->w_topline; |
230 # ifdef FEAT_DIFF | 238 # ifdef FEAT_DIFF |
231 old_topfill = curwin->w_topfill; | 239 old_topfill = curwin->w_topfill; |
994 while (i < ccline.cmdlen) | 1002 while (i < ccline.cmdlen) |
995 ccline.cmdbuff[i++] = ccline.cmdbuff[j++]; | 1003 ccline.cmdbuff[i++] = ccline.cmdbuff[j++]; |
996 | 1004 |
997 /* Truncate at the end, required for multi-byte chars. */ | 1005 /* Truncate at the end, required for multi-byte chars. */ |
998 ccline.cmdbuff[ccline.cmdlen] = NUL; | 1006 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 | |
999 redrawcmd(); | 1016 redrawcmd(); |
1000 } | 1017 } |
1001 else if (ccline.cmdlen == 0 && c != Ctrl_W | 1018 else if (ccline.cmdlen == 0 && c != Ctrl_W |
1002 && ccline.cmdprompt == NULL && indent == 0) | 1019 && ccline.cmdprompt == NULL && indent == 0) |
1003 { | 1020 { |
1019 else | 1036 else |
1020 #endif | 1037 #endif |
1021 msg_col = 0; | 1038 msg_col = 0; |
1022 msg_putchar(' '); /* delete ':' */ | 1039 msg_putchar(' '); /* delete ':' */ |
1023 } | 1040 } |
1041 #ifdef FEAT_SEARCH_EXTRA | |
1042 if (ccline.cmdlen == 0) | |
1043 old_cursor = cursor_start; | |
1044 #endif | |
1024 redraw_cmdline = TRUE; | 1045 redraw_cmdline = TRUE; |
1025 goto returncmd; /* back to cmd mode */ | 1046 goto returncmd; /* back to cmd mode */ |
1026 } | 1047 } |
1027 goto cmdline_changed; | 1048 goto cmdline_changed; |
1028 | 1049 |
1102 i = ccline.cmdpos = 0; | 1123 i = ccline.cmdpos = 0; |
1103 while (i < ccline.cmdlen) | 1124 while (i < ccline.cmdlen) |
1104 ccline.cmdbuff[i++] = ccline.cmdbuff[j++]; | 1125 ccline.cmdbuff[i++] = ccline.cmdbuff[j++]; |
1105 /* Truncate at the end, required for multi-byte chars. */ | 1126 /* Truncate at the end, required for multi-byte chars. */ |
1106 ccline.cmdbuff[ccline.cmdlen] = NUL; | 1127 ccline.cmdbuff[ccline.cmdlen] = NUL; |
1128 #ifdef FEAT_SEARCH_EXTRA | |
1129 if (ccline.cmdlen == 0) | |
1130 old_cursor = cursor_start; | |
1131 #endif | |
1107 redrawcmd(); | 1132 redrawcmd(); |
1108 goto cmdline_changed; | 1133 goto cmdline_changed; |
1109 | 1134 |
1110 #ifdef FEAT_CLIPBOARD | 1135 #ifdef FEAT_CLIPBOARD |
1111 case Ctrl_Y: | 1136 case Ctrl_Y: |
1438 case Ctrl_L: | 1463 case Ctrl_L: |
1439 #ifdef FEAT_SEARCH_EXTRA | 1464 #ifdef FEAT_SEARCH_EXTRA |
1440 if (p_is && !cmd_silent && (firstc == '/' || firstc == '?')) | 1465 if (p_is && !cmd_silent && (firstc == '/' || firstc == '?')) |
1441 { | 1466 { |
1442 /* Add a character from under the cursor for 'incsearch' */ | 1467 /* Add a character from under the cursor for 'incsearch' */ |
1443 if (did_incsearch | 1468 if (did_incsearch) |
1444 && !equalpos(curwin->w_cursor, old_cursor)) | |
1445 { | 1469 { |
1446 c = gchar_cursor(); | 1470 curwin->w_cursor = match_end; |
1447 /* If 'ignorecase' and 'smartcase' are set and the | 1471 if (!equalpos(curwin->w_cursor, old_cursor)) |
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) | |
1453 { | 1472 { |
1454 if (c == firstc || vim_strchr((char_u *)( | 1473 c = gchar_cursor(); |
1455 p_magic ? "\\^$.*[" : "\\^$"), c) | 1474 /* If 'ignorecase' and 'smartcase' are set and the |
1456 != NULL) | 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) | |
1457 { | 1481 { |
1458 /* put a backslash before special characters */ | 1482 if (c == firstc || vim_strchr((char_u *)( |
1459 stuffcharReadbuff(c); | 1483 p_magic ? "\\^$.*[" : "\\^$"), c) |
1460 c = '\\'; | 1484 != NULL) |
1485 { | |
1486 /* put a backslash before special | |
1487 * characters */ | |
1488 stuffcharReadbuff(c); | |
1489 c = '\\'; | |
1490 } | |
1491 break; | |
1461 } | 1492 } |
1462 break; | |
1463 } | 1493 } |
1464 } | 1494 } |
1465 goto cmdline_not_changed; | 1495 goto cmdline_not_changed; |
1466 } | 1496 } |
1467 #endif | 1497 #endif |
1471 break; | 1501 break; |
1472 goto cmdline_changed; | 1502 goto cmdline_changed; |
1473 | 1503 |
1474 case Ctrl_N: /* next match */ | 1504 case Ctrl_N: /* next match */ |
1475 case Ctrl_P: /* previous match */ | 1505 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) | |
1477 { | 1575 { |
1478 if (nextwild(&xpc, (c == Ctrl_P) ? WILD_PREV : WILD_NEXT, | 1576 if (nextwild(&xpc, (c == Ctrl_P) ? WILD_PREV : WILD_NEXT, |
1479 0, firstc != '@') == FAIL) | 1577 0, firstc != '@') == FAIL) |
1480 break; | 1578 break; |
1481 goto cmdline_changed; | 1579 goto cmdline_changed; |
1819 | 1917 |
1820 if (i != 0) | 1918 if (i != 0) |
1821 { | 1919 { |
1822 pos_T save_pos = curwin->w_cursor; | 1920 pos_T save_pos = curwin->w_cursor; |
1823 | 1921 |
1824 /* | 1922 match_start = curwin->w_cursor; |
1825 * First move cursor to end of match, then to the start. This | 1923 set_search_match(&curwin->w_cursor); |
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 } | |
1835 validate_cursor(); | 1924 validate_cursor(); |
1836 end_pos = curwin->w_cursor; | 1925 end_pos = curwin->w_cursor; |
1926 match_end = end_pos; | |
1837 curwin->w_cursor = save_pos; | 1927 curwin->w_cursor = save_pos; |
1838 } | 1928 } |
1839 else | 1929 else |
1840 end_pos = curwin->w_cursor; /* shutup gcc 4 */ | 1930 end_pos = curwin->w_cursor; /* shutup gcc 4 */ |
1841 | 1931 |
1892 | 1982 |
1893 #ifdef FEAT_SEARCH_EXTRA | 1983 #ifdef FEAT_SEARCH_EXTRA |
1894 if (did_incsearch) | 1984 if (did_incsearch) |
1895 { | 1985 { |
1896 curwin->w_cursor = old_cursor; | 1986 curwin->w_cursor = old_cursor; |
1987 if (gotesc) | |
1988 curwin->w_cursor = cursor_start; | |
1897 curwin->w_curswant = old_curswant; | 1989 curwin->w_curswant = old_curswant; |
1898 curwin->w_leftcol = old_leftcol; | 1990 curwin->w_leftcol = old_leftcol; |
1899 curwin->w_topline = old_topline; | 1991 curwin->w_topline = old_topline; |
1900 # ifdef FEAT_DIFF | 1992 # ifdef FEAT_DIFF |
1901 curwin->w_topfill = old_topfill; | 1993 curwin->w_topfill = old_topfill; |
6981 } | 7073 } |
6982 ga_append(&ga, NUL); | 7074 ga_append(&ga, NUL); |
6983 | 7075 |
6984 return (char_u *)ga.ga_data; | 7076 return (char_u *)ga.ga_data; |
6985 } | 7077 } |
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 |