comparison src/ex_getln.c @ 14503:4825955cb706 v8.1.0265

patch 8.1.0265: the getcmdline() function is way too big commit https://github.com/vim/vim/commit/0ee81cb63876e6ec1b2a6e0125295b43f1c63c7d Author: Bram Moolenaar <Bram@vim.org> Date: Fri Aug 10 22:07:32 2018 +0200 patch 8.1.0265: the getcmdline() function is way too big Problem: The getcmdline() function is way too big. Solution: Factor out the incremental search highlighting.
author Christian Brabandt <cb@256bit.org>
date Fri, 10 Aug 2018 22:15:05 +0200
parents e4c553e9132b
children 3648e74dd523
comparison
equal deleted inserted replaced
14502:f6cb0b08aedb 14503:4825955cb706
139 #ifdef __BORLANDC__ 139 #ifdef __BORLANDC__
140 _RTLENTRYF 140 _RTLENTRYF
141 #endif 141 #endif
142 sort_func_compare(const void *s1, const void *s2); 142 sort_func_compare(const void *s1, const void *s2);
143 #endif 143 #endif
144 #ifdef FEAT_SEARCH_EXTRA
145 static void set_search_match(pos_T *t);
146 #endif
147 144
148 145
149 static void 146 static void
150 trigger_cmd_autocmd(int typechar, int evt) 147 trigger_cmd_autocmd(int typechar, int evt)
151 { 148 {
183 while (n >= 2 && p[n - 2] == '\\' 180 while (n >= 2 && p[n - 2] == '\\'
184 && vim_strchr((char_u *)"mMvVcCZ", p[n - 1]) != NULL) 181 && vim_strchr((char_u *)"mMvVcCZ", p[n - 1]) != NULL)
185 n -= 2; 182 n -= 2;
186 return n == 0 || (n >= 2 && p[n - 2] == '\\' && p[n - 1] == '|'); 183 return n == 0 || (n >= 2 && p[n - 2] == '\\' && p[n - 1] == '|');
187 } 184 }
188 #endif 185
189 186 // Struct to store the viewstate during 'incsearch' highlighting.
190 #ifdef FEAT_SEARCH_EXTRA
191 typedef struct { 187 typedef struct {
192 colnr_T vs_curswant; 188 colnr_T vs_curswant;
193 colnr_T vs_leftcol; 189 colnr_T vs_leftcol;
194 linenr_T vs_topline; 190 linenr_T vs_topline;
195 # ifdef FEAT_DIFF 191 # ifdef FEAT_DIFF
221 # ifdef FEAT_DIFF 217 # ifdef FEAT_DIFF
222 curwin->w_topfill = vs->vs_topfill; 218 curwin->w_topfill = vs->vs_topfill;
223 # endif 219 # endif
224 curwin->w_botline = vs->vs_botline; 220 curwin->w_botline = vs->vs_botline;
225 curwin->w_empty_rows = vs->vs_empty_rows; 221 curwin->w_empty_rows = vs->vs_empty_rows;
222 }
223
224 // Struct to store the state of 'incsearch' highlighting.
225 typedef struct {
226 pos_T search_start; // where 'incsearch' starts searching
227 pos_T save_cursor;
228 viewstate_T init_viewstate;
229 viewstate_T old_viewstate;
230 pos_T match_start;
231 pos_T match_end;
232 int did_incsearch;
233 int incsearch_postponed;
234 } incsearch_state_T;
235
236 static void
237 init_incsearch_state(incsearch_state_T *is_state)
238 {
239 is_state->match_start = curwin->w_cursor;
240 is_state->did_incsearch = FALSE;
241 is_state->incsearch_postponed = FALSE;
242 CLEAR_POS(&is_state->match_end);
243 is_state->save_cursor = curwin->w_cursor; // may be restored later
244 is_state->search_start = curwin->w_cursor;
245 save_viewstate(&is_state->init_viewstate);
246 save_viewstate(&is_state->old_viewstate);
247 }
248
249 /*
250 * First move cursor to end of match, then to the start. This
251 * moves the whole match onto the screen when 'nowrap' is set.
252 */
253 static void
254 set_search_match(pos_T *t)
255 {
256 t->lnum += search_match_lines;
257 t->col = search_match_endcol;
258 if (t->lnum > curbuf->b_ml.ml_line_count)
259 {
260 t->lnum = curbuf->b_ml.ml_line_count;
261 coladvance((colnr_T)MAXCOL);
262 }
263 }
264
265 /*
266 * Return TRUE when 'incsearch' highlighting is to be done.
267 */
268 static int
269 do_incsearch_highlighting(int firstc)
270 {
271 return p_is && !cmd_silent && (firstc == '/' || firstc == '?');
272 }
273
274 /*
275 * Do 'incsearch' highlighting if desired.
276 */
277 static void
278 may_do_incsearch_highlighting(
279 int firstc,
280 long count,
281 incsearch_state_T *is_state)
282 {
283 int i;
284 pos_T end_pos;
285 struct cmdline_info save_ccline;
286 #ifdef FEAT_RELTIME
287 proftime_T tm;
288 #endif
289
290 if (!do_incsearch_highlighting(firstc))
291 return;
292
293 // If there is a character waiting, search and redraw later.
294 if (char_avail())
295 {
296 is_state->incsearch_postponed = TRUE;
297 return;
298 }
299 is_state->incsearch_postponed = FALSE;
300
301 // start at old position
302 curwin->w_cursor = is_state->search_start;
303 save_last_search_pattern();
304
305 // If there is no command line, don't do anything.
306 if (ccline.cmdlen == 0)
307 {
308 i = 0;
309 set_no_hlsearch(TRUE); // turn off previous highlight
310 redraw_all_later(SOME_VALID);
311 }
312 else
313 {
314 int search_flags = SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK;
315
316 cursor_off(); // so the user knows we're busy
317 out_flush();
318 ++emsg_off; // so it doesn't beep if bad expr
319 #ifdef FEAT_RELTIME
320 // Set the time limit to half a second.
321 profile_setlimit(500L, &tm);
322 #endif
323 if (!p_hls)
324 search_flags += SEARCH_KEEP;
325 i = do_search(NULL, firstc, ccline.cmdbuff, count, search_flags,
326 #ifdef FEAT_RELTIME
327 &tm, NULL
328 #else
329 NULL, NULL
330 #endif
331 );
332 --emsg_off;
333
334 // if interrupted while searching, behave like it failed
335 if (got_int)
336 {
337 (void)vpeekc(); // remove <C-C> from input stream
338 got_int = FALSE; // don't abandon the command line
339 i = 0;
340 }
341 else if (char_avail())
342 // cancelled searching because a char was typed
343 is_state->incsearch_postponed = TRUE;
344 }
345 if (i != 0)
346 highlight_match = TRUE; // highlight position
347 else
348 highlight_match = FALSE; // remove highlight
349
350 // First restore the old curwin values, so the screen is positioned in the
351 // same way as the actual search command.
352 restore_viewstate(&is_state->old_viewstate);
353 changed_cline_bef_curs();
354 update_topline();
355
356 if (i != 0)
357 {
358 pos_T save_pos = curwin->w_cursor;
359
360 is_state->match_start = curwin->w_cursor;
361 set_search_match(&curwin->w_cursor);
362 validate_cursor();
363 end_pos = curwin->w_cursor;
364 is_state->match_end = end_pos;
365 curwin->w_cursor = save_pos;
366 }
367 else
368 end_pos = curwin->w_cursor; // shutup gcc 4
369
370 // Disable 'hlsearch' highlighting if the pattern matches everything.
371 // Avoids a flash when typing "foo\|".
372 if (empty_pattern(ccline.cmdbuff))
373 set_no_hlsearch(TRUE);
374
375 validate_cursor();
376 // May redraw the status line to show the cursor position.
377 if (p_ru && curwin->w_status_height > 0)
378 curwin->w_redr_status = TRUE;
379
380 save_cmdline(&save_ccline);
381 update_screen(SOME_VALID);
382 restore_cmdline(&save_ccline);
383 restore_last_search_pattern();
384
385 // Leave it at the end to make CTRL-R CTRL-W work.
386 if (i != 0)
387 curwin->w_cursor = end_pos;
388
389 msg_starthere();
390 redrawcmdline();
391 is_state->did_incsearch = TRUE;
392 }
393
394 /*
395 * May adjust 'incsearch' highlighting for typing CTRL-G and CTRL-T, go to next
396 * or previous match.
397 * Returns FAIL when jumping to cmdline_not_changed;
398 */
399 static int
400 may_adjust_incsearch_highlighting(
401 int firstc,
402 long count,
403 incsearch_state_T *is_state,
404 int c)
405 {
406 pos_T t;
407 char_u *pat;
408 int search_flags = SEARCH_NOOF;
409 int i;
410
411 if (!do_incsearch_highlighting(firstc))
412 return OK;
413 if (ccline.cmdlen == 0)
414 return FAIL;
415
416 if (firstc == ccline.cmdbuff[0])
417 pat = last_search_pattern();
418 else
419 pat = ccline.cmdbuff;
420
421 save_last_search_pattern();
422 cursor_off();
423 out_flush();
424 if (c == Ctrl_G)
425 {
426 t = is_state->match_end;
427 if (LT_POS(is_state->match_start, is_state->match_end))
428 // Start searching at the end of the match not at the beginning of
429 // the next column.
430 (void)decl(&t);
431 search_flags += SEARCH_COL;
432 }
433 else
434 t = is_state->match_start;
435 if (!p_hls)
436 search_flags += SEARCH_KEEP;
437 ++emsg_off;
438 i = searchit(curwin, curbuf, &t,
439 c == Ctrl_G ? FORWARD : BACKWARD,
440 pat, count, search_flags,
441 RE_SEARCH, 0, NULL, NULL);
442 --emsg_off;
443 if (i)
444 {
445 is_state->search_start = is_state->match_start;
446 is_state->match_end = t;
447 is_state->match_start = t;
448 if (c == Ctrl_T && firstc == '/')
449 {
450 // Move just before the current match, so that when nv_search
451 // finishes the cursor will be put back on the match.
452 is_state->search_start = t;
453 (void)decl(&is_state->search_start);
454 }
455 else if (c == Ctrl_G && firstc == '?')
456 {
457 // Move just after the current match, so that when nv_search
458 // finishes the cursor will be put back on the match.
459 is_state->search_start = t;
460 (void)incl(&is_state->search_start);
461 }
462 if (LT_POS(t, is_state->search_start) && c == Ctrl_G)
463 {
464 // wrap around
465 is_state->search_start = t;
466 if (firstc == '?')
467 (void)incl(&is_state->search_start);
468 else
469 (void)decl(&is_state->search_start);
470 }
471
472 set_search_match(&is_state->match_end);
473 curwin->w_cursor = is_state->match_start;
474 changed_cline_bef_curs();
475 update_topline();
476 validate_cursor();
477 highlight_match = TRUE;
478 save_viewstate(&is_state->old_viewstate);
479 update_screen(NOT_VALID);
480 redrawcmdline();
481 }
482 else
483 vim_beep(BO_ERROR);
484 restore_last_search_pattern();
485 return FAIL;
486 }
487
488 /*
489 * When CTRL-L typed: add character from the match to the pattern.
490 * May set "*c" to the added character.
491 * Return OK when jumping to cmdline_not_changed.
492 */
493 static int
494 may_add_char_to_search(int firstc, int *c, incsearch_state_T *is_state)
495 {
496 if (!do_incsearch_highlighting(firstc))
497 return FAIL;
498
499 // Add a character from under the cursor for 'incsearch'.
500 if (is_state->did_incsearch)
501 {
502 curwin->w_cursor = is_state->match_end;
503 if (!EQUAL_POS(curwin->w_cursor, is_state->search_start))
504 {
505 *c = gchar_cursor();
506
507 // If 'ignorecase' and 'smartcase' are set and the
508 // command line has no uppercase characters, convert
509 // the character to lowercase.
510 if (p_ic && p_scs && !pat_has_uppercase(ccline.cmdbuff))
511 *c = MB_TOLOWER(*c);
512 if (*c != NUL)
513 {
514 if (*c == firstc || vim_strchr((char_u *)(
515 p_magic ? "\\~^$.*[" : "\\^$"), *c) != NULL)
516 {
517 // put a backslash before special characters
518 stuffcharReadbuff(*c);
519 *c = '\\';
520 }
521 return FAIL;
522 }
523 }
524 }
525 return OK;
526 }
527
528 static void
529 finish_incsearch_highlighting(int gotesc, incsearch_state_T *is_state)
530 {
531 if (is_state->did_incsearch)
532 {
533 if (gotesc)
534 curwin->w_cursor = is_state->save_cursor;
535 else
536 {
537 if (!EQUAL_POS(is_state->save_cursor, is_state->search_start))
538 {
539 // put the '" mark at the original position
540 curwin->w_cursor = is_state->save_cursor;
541 setpcmark();
542 }
543 curwin->w_cursor = is_state->search_start;
544 }
545 restore_viewstate(&is_state->old_viewstate);
546 highlight_match = FALSE;
547 validate_cursor(); /* needed for TAB */
548 redraw_all_later(SOME_VALID);
549 }
226 } 550 }
227 #endif 551 #endif
228 552
229 /* 553 /*
230 * getcmdline() - accept a command line starting with firstc. 554 * getcmdline() - accept a command line starting with firstc.
260 char_u *lookfor = NULL; /* string to match */ 584 char_u *lookfor = NULL; /* string to match */
261 int hiscnt; /* current history line in use */ 585 int hiscnt; /* current history line in use */
262 int histype; /* history type to be used */ 586 int histype; /* history type to be used */
263 #endif 587 #endif
264 #ifdef FEAT_SEARCH_EXTRA 588 #ifdef FEAT_SEARCH_EXTRA
265 pos_T search_start; /* where 'incsearch' starts searching */ 589 incsearch_state_T is_state;
266 pos_T save_cursor;
267 viewstate_T init_viewstate;
268 viewstate_T old_viewstate;
269 pos_T match_start = curwin->w_cursor;
270 pos_T match_end;
271 int did_incsearch = FALSE;
272 int incsearch_postponed = FALSE;
273 #endif 590 #endif
274 int did_wild_list = FALSE; /* did wild_list() recently */ 591 int did_wild_list = FALSE; /* did wild_list() recently */
275 int wim_index = 0; /* index in wim_flags[] */ 592 int wim_index = 0; /* index in wim_flags[] */
276 int res; 593 int res;
277 int save_msg_scroll = msg_scroll; 594 int save_msg_scroll = msg_scroll;
285 #ifdef FEAT_EVAL 602 #ifdef FEAT_EVAL
286 int break_ctrl_c = FALSE; 603 int break_ctrl_c = FALSE;
287 #endif 604 #endif
288 expand_T xpc; 605 expand_T xpc;
289 long *b_im_ptr = NULL; 606 long *b_im_ptr = NULL;
290 #if defined(FEAT_WILDMENU) || defined(FEAT_EVAL) || defined(FEAT_SEARCH_EXTRA) 607 #if defined(FEAT_WILDMENU) || defined(FEAT_EVAL)
291 /* Everything that may work recursively should save and restore the 608 /* Everything that may work recursively should save and restore the
292 * current command line in save_ccline. That includes update_screen(), a 609 * current command line in save_ccline. That includes update_screen(), a
293 * custom status line may invoke ":normal". */ 610 * custom status line may invoke ":normal". */
294 struct cmdline_info save_ccline; 611 struct cmdline_info save_ccline;
295 #endif 612 #endif
307 if (firstc == ':' || firstc == '=' || firstc == '>') 624 if (firstc == ':' || firstc == '=' || firstc == '>')
308 cmd_hkmap = 0; 625 cmd_hkmap = 0;
309 #endif 626 #endif
310 627
311 ccline.overstrike = FALSE; /* always start in insert mode */ 628 ccline.overstrike = FALSE; /* always start in insert mode */
629
312 #ifdef FEAT_SEARCH_EXTRA 630 #ifdef FEAT_SEARCH_EXTRA
313 CLEAR_POS(&match_end); 631 init_incsearch_state(&is_state);
314 save_cursor = curwin->w_cursor; /* may be restored later */
315 search_start = curwin->w_cursor;
316 save_viewstate(&init_viewstate);
317 save_viewstate(&old_viewstate);
318 #endif 632 #endif
319 633
320 /* 634 /*
321 * set some variables for redrawcmd() 635 * set some variables for redrawcmd()
322 */ 636 */
1087 /* Truncate at the end, required for multi-byte chars. */ 1401 /* Truncate at the end, required for multi-byte chars. */
1088 ccline.cmdbuff[ccline.cmdlen] = NUL; 1402 ccline.cmdbuff[ccline.cmdlen] = NUL;
1089 #ifdef FEAT_SEARCH_EXTRA 1403 #ifdef FEAT_SEARCH_EXTRA
1090 if (ccline.cmdlen == 0) 1404 if (ccline.cmdlen == 0)
1091 { 1405 {
1092 search_start = save_cursor; 1406 is_state.search_start = is_state.save_cursor;
1093 /* save view settings, so that the screen 1407 /* save view settings, so that the screen
1094 * won't be restored at the wrong position */ 1408 * won't be restored at the wrong position */
1095 old_viewstate = init_viewstate; 1409 is_state.old_viewstate = is_state.init_viewstate;
1096 } 1410 }
1097 #endif 1411 #endif
1098 redrawcmd(); 1412 redrawcmd();
1099 } 1413 }
1100 else if (ccline.cmdlen == 0 && c != Ctrl_W 1414 else if (ccline.cmdlen == 0 && c != Ctrl_W
1119 msg_col = 0; 1433 msg_col = 0;
1120 msg_putchar(' '); /* delete ':' */ 1434 msg_putchar(' '); /* delete ':' */
1121 } 1435 }
1122 #ifdef FEAT_SEARCH_EXTRA 1436 #ifdef FEAT_SEARCH_EXTRA
1123 if (ccline.cmdlen == 0) 1437 if (ccline.cmdlen == 0)
1124 search_start = save_cursor; 1438 is_state.search_start = is_state.save_cursor;
1125 #endif 1439 #endif
1126 redraw_cmdline = TRUE; 1440 redraw_cmdline = TRUE;
1127 goto returncmd; /* back to cmd mode */ 1441 goto returncmd; /* back to cmd mode */
1128 } 1442 }
1129 goto cmdline_changed; 1443 goto cmdline_changed;
1206 ccline.cmdbuff[i++] = ccline.cmdbuff[j++]; 1520 ccline.cmdbuff[i++] = ccline.cmdbuff[j++];
1207 /* Truncate at the end, required for multi-byte chars. */ 1521 /* Truncate at the end, required for multi-byte chars. */
1208 ccline.cmdbuff[ccline.cmdlen] = NUL; 1522 ccline.cmdbuff[ccline.cmdlen] = NUL;
1209 #ifdef FEAT_SEARCH_EXTRA 1523 #ifdef FEAT_SEARCH_EXTRA
1210 if (ccline.cmdlen == 0) 1524 if (ccline.cmdlen == 0)
1211 search_start = save_cursor; 1525 is_state.search_start = is_state.save_cursor;
1212 #endif 1526 #endif
1213 redrawcmd(); 1527 redrawcmd();
1214 goto cmdline_changed; 1528 goto cmdline_changed;
1215 1529
1216 #ifdef FEAT_CLIPBOARD 1530 #ifdef FEAT_CLIPBOARD
1543 break; 1857 break;
1544 goto cmdline_changed; 1858 goto cmdline_changed;
1545 1859
1546 case Ctrl_L: 1860 case Ctrl_L:
1547 #ifdef FEAT_SEARCH_EXTRA 1861 #ifdef FEAT_SEARCH_EXTRA
1548 if (p_is && !cmd_silent && (firstc == '/' || firstc == '?')) 1862 if (may_add_char_to_search(firstc, &c, &is_state) == OK)
1549 {
1550 /* Add a character from under the cursor for 'incsearch' */
1551 if (did_incsearch)
1552 {
1553 curwin->w_cursor = match_end;
1554 if (!EQUAL_POS(curwin->w_cursor, search_start))
1555 {
1556 c = gchar_cursor();
1557 /* If 'ignorecase' and 'smartcase' are set and the
1558 * command line has no uppercase characters, convert
1559 * the character to lowercase */
1560 if (p_ic && p_scs
1561 && !pat_has_uppercase(ccline.cmdbuff))
1562 c = MB_TOLOWER(c);
1563 if (c != NUL)
1564 {
1565 if (c == firstc || vim_strchr((char_u *)(
1566 p_magic ? "\\~^$.*[" : "\\^$"), c)
1567 != NULL)
1568 {
1569 /* put a backslash before special
1570 * characters */
1571 stuffcharReadbuff(c);
1572 c = '\\';
1573 }
1574 break;
1575 }
1576 }
1577 }
1578 goto cmdline_not_changed; 1863 goto cmdline_not_changed;
1579 }
1580 #endif 1864 #endif
1581 1865
1582 /* completion: longest common part */ 1866 /* completion: longest common part */
1583 if (nextwild(&xpc, WILD_LONGEST, 0, firstc != '@') == FAIL) 1867 if (nextwild(&xpc, WILD_LONGEST, 0, firstc != '@') == FAIL)
1584 break; 1868 break;
1740 goto cmdline_not_changed; 2024 goto cmdline_not_changed;
1741 2025
1742 #ifdef FEAT_SEARCH_EXTRA 2026 #ifdef FEAT_SEARCH_EXTRA
1743 case Ctrl_G: /* next match */ 2027 case Ctrl_G: /* next match */
1744 case Ctrl_T: /* previous match */ 2028 case Ctrl_T: /* previous match */
1745 if (p_is && !cmd_silent && (firstc == '/' || firstc == '?')) 2029 if (may_adjust_incsearch_highlighting(
1746 { 2030 firstc, count, &is_state, c) == FAIL)
1747 pos_T t;
1748 char_u *pat;
1749 int search_flags = SEARCH_NOOF;
1750
1751 if (ccline.cmdlen == 0)
1752 goto cmdline_not_changed;
1753
1754 if (firstc == ccline.cmdbuff[0])
1755 pat = last_search_pattern();
1756 else
1757 pat = ccline.cmdbuff;
1758
1759 save_last_search_pattern();
1760 cursor_off();
1761 out_flush();
1762 if (c == Ctrl_G)
1763 {
1764 t = match_end;
1765 if (LT_POS(match_start, match_end))
1766 /* start searching at the end of the match
1767 * not at the beginning of the next column */
1768 (void)decl(&t);
1769 search_flags += SEARCH_COL;
1770 }
1771 else
1772 t = match_start;
1773 if (!p_hls)
1774 search_flags += SEARCH_KEEP;
1775 ++emsg_off;
1776 i = searchit(curwin, curbuf, &t,
1777 c == Ctrl_G ? FORWARD : BACKWARD,
1778 pat, count, search_flags,
1779 RE_SEARCH, 0, NULL, NULL);
1780 --emsg_off;
1781 if (i)
1782 {
1783 search_start = match_start;
1784 match_end = t;
1785 match_start = t;
1786 if (c == Ctrl_T && firstc == '/')
1787 {
1788 /* move just before the current match, so that
1789 * when nv_search finishes the cursor will be
1790 * put back on the match */
1791 search_start = t;
1792 (void)decl(&search_start);
1793 }
1794 else if (c == Ctrl_G && firstc == '?')
1795 {
1796 /* move just after the current match, so that
1797 * when nv_search finishes the cursor will be
1798 * put back on the match */
1799 search_start = t;
1800 (void)incl(&search_start);
1801 }
1802 if (LT_POS(t, search_start) && c == Ctrl_G)
1803 {
1804 /* wrap around */
1805 search_start = t;
1806 if (firstc == '?')
1807 (void)incl(&search_start);
1808 else
1809 (void)decl(&search_start);
1810 }
1811
1812 set_search_match(&match_end);
1813 curwin->w_cursor = match_start;
1814 changed_cline_bef_curs();
1815 update_topline();
1816 validate_cursor();
1817 highlight_match = TRUE;
1818 save_viewstate(&old_viewstate);
1819 update_screen(NOT_VALID);
1820 redrawcmdline();
1821 }
1822 else
1823 vim_beep(BO_ERROR);
1824 restore_last_search_pattern();
1825 goto cmdline_not_changed; 2031 goto cmdline_not_changed;
1826 }
1827 break; 2032 break;
1828 #endif 2033 #endif
1829 2034
1830 case Ctrl_V: 2035 case Ctrl_V:
1831 case Ctrl_Q: 2036 case Ctrl_Q:
1949 * Jump to cmdline_changed when the command line did change. 2154 * Jump to cmdline_changed when the command line did change.
1950 * (Sorry for the goto's, I know it is ugly). 2155 * (Sorry for the goto's, I know it is ugly).
1951 */ 2156 */
1952 cmdline_not_changed: 2157 cmdline_not_changed:
1953 #ifdef FEAT_SEARCH_EXTRA 2158 #ifdef FEAT_SEARCH_EXTRA
1954 if (!incsearch_postponed) 2159 if (!is_state.incsearch_postponed)
1955 continue; 2160 continue;
1956 #endif 2161 #endif
1957 2162
1958 cmdline_changed: 2163 cmdline_changed:
1959 /* Trigger CmdlineChanged autocommands. */ 2164 /* Trigger CmdlineChanged autocommands. */
1960 trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINECHANGED); 2165 trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINECHANGED);
1961 2166
1962 #ifdef FEAT_SEARCH_EXTRA 2167 #ifdef FEAT_SEARCH_EXTRA
1963 /* 2168 may_do_incsearch_highlighting(firstc, count, &is_state);
1964 * 'incsearch' highlighting.
1965 */
1966 if (p_is && !cmd_silent && (firstc == '/' || firstc == '?'))
1967 {
1968 pos_T end_pos;
1969 #ifdef FEAT_RELTIME
1970 proftime_T tm;
1971 #endif
1972
1973 /* if there is a character waiting, search and redraw later */
1974 if (char_avail())
1975 {
1976 incsearch_postponed = TRUE;
1977 continue;
1978 }
1979 incsearch_postponed = FALSE;
1980 curwin->w_cursor = search_start; /* start at old position */
1981 save_last_search_pattern();
1982
1983 /* If there is no command line, don't do anything */
1984 if (ccline.cmdlen == 0)
1985 {
1986 i = 0;
1987 set_no_hlsearch(TRUE); /* turn off previous highlight */
1988 redraw_all_later(SOME_VALID);
1989 }
1990 else
1991 {
1992 int search_flags = SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK;
1993 cursor_off(); /* so the user knows we're busy */
1994 out_flush();
1995 ++emsg_off; /* So it doesn't beep if bad expr */
1996 #ifdef FEAT_RELTIME
1997 /* Set the time limit to half a second. */
1998 profile_setlimit(500L, &tm);
1999 #endif
2000 if (!p_hls)
2001 search_flags += SEARCH_KEEP;
2002 i = do_search(NULL, firstc, ccline.cmdbuff, count,
2003 search_flags,
2004 #ifdef FEAT_RELTIME
2005 &tm, NULL
2006 #else
2007 NULL, NULL
2008 #endif
2009 );
2010 --emsg_off;
2011 /* if interrupted while searching, behave like it failed */
2012 if (got_int)
2013 {
2014 (void)vpeekc(); /* remove <C-C> from input stream */
2015 got_int = FALSE; /* don't abandon the command line */
2016 i = 0;
2017 }
2018 else if (char_avail())
2019 /* cancelled searching because a char was typed */
2020 incsearch_postponed = TRUE;
2021 }
2022 if (i != 0)
2023 highlight_match = TRUE; /* highlight position */
2024 else
2025 highlight_match = FALSE; /* remove highlight */
2026
2027 /* first restore the old curwin values, so the screen is
2028 * positioned in the same way as the actual search command */
2029 restore_viewstate(&old_viewstate);
2030 changed_cline_bef_curs();
2031 update_topline();
2032
2033 if (i != 0)
2034 {
2035 pos_T save_pos = curwin->w_cursor;
2036
2037 match_start = curwin->w_cursor;
2038 set_search_match(&curwin->w_cursor);
2039 validate_cursor();
2040 end_pos = curwin->w_cursor;
2041 match_end = end_pos;
2042 curwin->w_cursor = save_pos;
2043 }
2044 else
2045 end_pos = curwin->w_cursor; /* shutup gcc 4 */
2046
2047 /* Disable 'hlsearch' highlighting if the pattern matches
2048 * everything. Avoids a flash when typing "foo\|". */
2049 if (empty_pattern(ccline.cmdbuff))
2050 set_no_hlsearch(TRUE);
2051
2052 validate_cursor();
2053 /* May redraw the status line to show the cursor position. */
2054 if (p_ru && curwin->w_status_height > 0)
2055 curwin->w_redr_status = TRUE;
2056
2057 save_cmdline(&save_ccline);
2058 update_screen(SOME_VALID);
2059 restore_cmdline(&save_ccline);
2060 restore_last_search_pattern();
2061
2062 /* Leave it at the end to make CTRL-R CTRL-W work. */
2063 if (i != 0)
2064 curwin->w_cursor = end_pos;
2065
2066 msg_starthere();
2067 redrawcmdline();
2068 did_incsearch = TRUE;
2069 }
2070 #else /* FEAT_SEARCH_EXTRA */
2071 ;
2072 #endif 2169 #endif
2073 2170
2074 #ifdef FEAT_RIGHTLEFT 2171 #ifdef FEAT_RIGHTLEFT
2075 if (cmdmsg_rl 2172 if (cmdmsg_rl
2076 # ifdef FEAT_ARABIC 2173 # ifdef FEAT_ARABIC
2098 2195
2099 ExpandCleanup(&xpc); 2196 ExpandCleanup(&xpc);
2100 ccline.xpc = NULL; 2197 ccline.xpc = NULL;
2101 2198
2102 #ifdef FEAT_SEARCH_EXTRA 2199 #ifdef FEAT_SEARCH_EXTRA
2103 if (did_incsearch) 2200 finish_incsearch_highlighting(gotesc, &is_state);
2104 {
2105 if (gotesc)
2106 curwin->w_cursor = save_cursor;
2107 else
2108 {
2109 if (!EQUAL_POS(save_cursor, search_start))
2110 {
2111 /* put the '" mark at the original position */
2112 curwin->w_cursor = save_cursor;
2113 setpcmark();
2114 }
2115 curwin->w_cursor = search_start;
2116 }
2117 restore_viewstate(&old_viewstate);
2118 highlight_match = FALSE;
2119 validate_cursor(); /* needed for TAB */
2120 redraw_all_later(SOME_VALID);
2121 }
2122 #endif 2201 #endif
2123 2202
2124 if (ccline.cmdbuff != NULL) 2203 if (ccline.cmdbuff != NULL)
2125 { 2204 {
2126 /* 2205 /*
7237 } 7316 }
7238 ga_append(&ga, NUL); 7317 ga_append(&ga, NUL);
7239 7318
7240 return (char_u *)ga.ga_data; 7319 return (char_u *)ga.ga_data;
7241 } 7320 }
7242
7243 #ifdef FEAT_SEARCH_EXTRA
7244 static void
7245 set_search_match(pos_T *t)
7246 {
7247 /*
7248 * First move cursor to end of match, then to the start. This
7249 * moves the whole match onto the screen when 'nowrap' is set.
7250 */
7251 t->lnum += search_match_lines;
7252 t->col = search_match_endcol;
7253 if (t->lnum > curbuf->b_ml.ml_line_count)
7254 {
7255 t->lnum = curbuf->b_ml.ml_line_count;
7256 coladvance((colnr_T)MAXCOL);
7257 }
7258 }
7259 #endif