1 /* vi:set ts=8 sts=4 sw=4 noet: 2 * 3 * VIM - Vi IMproved by Bram Moolenaar 4 * 5 * Do ":help uganda" in Vim to read copying and usage conditions. 6 * Do ":help credits" in Vim to see a list of people who contributed. 7 * See README.txt for an overview of the Vim source code. 8 */ 9 10 /* 11 * ex_getln.c: Functions for entering and editing an Ex command line. 12 */ 13 14 #include "vim.h" 15 16 #ifndef MAX 17 # define MAX(x,y) ((x) > (y) ? (x) : (y)) 18 #endif 19 20 // The current cmdline_info. It is initialized in getcmdline() and after that 21 // used by other functions. When invoking getcmdline() recursively it needs 22 // to be saved with save_cmdline() and restored with restore_cmdline(). 23 static cmdline_info_T ccline; 24 25 #ifdef FEAT_EVAL 26 static int new_cmdpos; // position set by set_cmdline_pos() 27 #endif 28 29 static int extra_char = NUL; // extra character to display when redrawing 30 // the command line 31 static int extra_char_shift; 32 33 #ifdef FEAT_RIGHTLEFT 34 static int cmd_hkmap = 0; // Hebrew mapping during command line 35 #endif 36 37 static char_u *getcmdline_int(int firstc, long count, int indent, int init_ccline); 38 static int cmdline_charsize(int idx); 39 static void set_cmdspos(void); 40 static void set_cmdspos_cursor(void); 41 static void correct_cmdspos(int idx, int cells); 42 static void alloc_cmdbuff(int len); 43 static void draw_cmdline(int start, int len); 44 static void save_cmdline(cmdline_info_T *ccp); 45 static void restore_cmdline(cmdline_info_T *ccp); 46 static int cmdline_paste(int regname, int literally, int remcr); 47 #ifdef FEAT_WILDMENU 48 static void cmdline_del(int from); 49 #endif 50 static void redrawcmdprompt(void); 51 static int ccheck_abbr(int); 52 53 #ifdef FEAT_CMDWIN 54 static int open_cmdwin(void); 55 56 static int cedit_key INIT(= -1); // key value of 'cedit' option 57 #endif 58 59 60 static void 61 trigger_cmd_autocmd(int typechar, int evt) 62 { 63 char_u typestr[2]; 64 65 typestr[0] = typechar; 66 typestr[1] = NUL; 67 apply_autocmds(evt, typestr, typestr, FALSE, curbuf); 68 } 69 70 /* 71 * Abandon the command line. 72 */ 73 static void 74 abandon_cmdline(void) 75 { 76 VIM_CLEAR(ccline.cmdbuff); 77 if (msg_scrolled == 0) 78 compute_cmdrow(); 79 msg(""); 80 redraw_cmdline = TRUE; 81 } 82 83 #ifdef FEAT_SEARCH_EXTRA 84 /* 85 * Guess that the pattern matches everything. Only finds specific cases, such 86 * as a trailing \|, which can happen while typing a pattern. 87 */ 88 static int 89 empty_pattern(char_u *p) 90 { 91 size_t n = STRLEN(p); 92 93 // remove trailing \v and the like 94 while (n >= 2 && p[n - 2] == '\\' 95 && vim_strchr((char_u *)"mMvVcCZ", p[n - 1]) != NULL) 96 n -= 2; 97 return n == 0 || (n >= 2 && p[n - 2] == '\\' && p[n - 1] == '|'); 98 } 99 100 // Struct to store the viewstate during 'incsearch' highlighting. 101 typedef struct { 102 colnr_T vs_curswant; 103 colnr_T vs_leftcol; 104 linenr_T vs_topline; 105 # ifdef FEAT_DIFF 106 int vs_topfill; 107 # endif 108 linenr_T vs_botline; 109 linenr_T vs_empty_rows; 110 } viewstate_T; 111 112 static void 113 save_viewstate(viewstate_T *vs) 114 { 115 vs->vs_curswant = curwin->w_curswant; 116 vs->vs_leftcol = curwin->w_leftcol; 117 vs->vs_topline = curwin->w_topline; 118 # ifdef FEAT_DIFF 119 vs->vs_topfill = curwin->w_topfill; 120 # endif 121 vs->vs_botline = curwin->w_botline; 122 vs->vs_empty_rows = curwin->w_empty_rows; 123 } 124 125 static void 126 restore_viewstate(viewstate_T *vs) 127 { 128 curwin->w_curswant = vs->vs_curswant; 129 curwin->w_leftcol = vs->vs_leftcol; 130 curwin->w_topline = vs->vs_topline; 131 # ifdef FEAT_DIFF 132 curwin->w_topfill = vs->vs_topfill; 133 # endif 134 curwin->w_botline = vs->vs_botline; 135 curwin->w_empty_rows = vs->vs_empty_rows; 136 } 137 138 // Struct to store the state of 'incsearch' highlighting. 139 typedef struct { 140 pos_T search_start; // where 'incsearch' starts searching 141 pos_T save_cursor; 142 viewstate_T init_viewstate; 143 viewstate_T old_viewstate; 144 pos_T match_start; 145 pos_T match_end; 146 int did_incsearch; 147 int incsearch_postponed; 148 int magic_save; 149 } incsearch_state_T; 150 151 static void 152 init_incsearch_state(incsearch_state_T *is_state) 153 { 154 is_state->match_start = curwin->w_cursor; 155 is_state->did_incsearch = FALSE; 156 is_state->incsearch_postponed = FALSE; 157 is_state->magic_save = p_magic; 158 CLEAR_POS(&is_state->match_end); 159 is_state->save_cursor = curwin->w_cursor; // may be restored later 160 is_state->search_start = curwin->w_cursor; 161 save_viewstate(&is_state->init_viewstate); 162 save_viewstate(&is_state->old_viewstate); 163 } 164 165 /* 166 * First move cursor to end of match, then to the start. This 167 * moves the whole match onto the screen when 'nowrap' is set. 168 */ 169 static void 170 set_search_match(pos_T *t) 171 { 172 t->lnum += search_match_lines; 173 t->col = search_match_endcol; 174 if (t->lnum > curbuf->b_ml.ml_line_count) 175 { 176 t->lnum = curbuf->b_ml.ml_line_count; 177 coladvance((colnr_T)MAXCOL); 178 } 179 } 180 181 /* 182 * Return TRUE when 'incsearch' highlighting is to be done. 183 * Sets search_first_line and search_last_line to the address range. 184 * May change the last search pattern. 185 */ 186 static int 187 do_incsearch_highlighting(int firstc, int *search_delim, incsearch_state_T *is_state, 188 int *skiplen, int *patlen) 189 { 190 char_u *cmd; 191 cmdmod_T save_cmdmod = cmdmod; 192 char_u *p; 193 int delim_optional = FALSE; 194 int delim; 195 char_u *end; 196 char *dummy; 197 exarg_T ea; 198 pos_T save_cursor; 199 int use_last_pat; 200 int retval = FALSE; 201 202 *skiplen = 0; 203 *patlen = ccline.cmdlen; 204 205 if (!p_is || cmd_silent) 206 return FALSE; 207 208 // by default search all lines 209 search_first_line = 0; 210 search_last_line = MAXLNUM; 211 212 if (firstc == '/' || firstc == '?') 213 { 214 *search_delim = firstc; 215 return TRUE; 216 } 217 if (firstc != ':') 218 return FALSE; 219 220 ++emsg_off; 221 CLEAR_FIELD(ea); 222 ea.line1 = 1; 223 ea.line2 = 1; 224 ea.cmd = ccline.cmdbuff; 225 ea.addr_type = ADDR_LINES; 226 227 parse_command_modifiers(&ea, &dummy, TRUE); 228 cmdmod = save_cmdmod; 229 230 cmd = skip_range(ea.cmd, NULL); 231 if (vim_strchr((char_u *)"sgvl", *cmd) == NULL) 232 goto theend; 233 234 // Skip over "substitute" to find the pattern separator. 235 for (p = cmd; ASCII_ISALPHA(*p); ++p) 236 ; 237 if (*skipwhite(p) == NUL) 238 goto theend; 239 240 if (STRNCMP(cmd, "substitute", p - cmd) == 0 241 || STRNCMP(cmd, "smagic", p - cmd) == 0 242 || STRNCMP(cmd, "snomagic", MAX(p - cmd, 3)) == 0 243 || STRNCMP(cmd, "vglobal", p - cmd) == 0) 244 { 245 if (*cmd == 's' && cmd[1] == 'm') 246 p_magic = TRUE; 247 else if (*cmd == 's' && cmd[1] == 'n') 248 p_magic = FALSE; 249 } 250 else if (STRNCMP(cmd, "sort", MAX(p - cmd, 3)) == 0) 251 { 252 // skip over ! and flags 253 if (*p == '!') 254 p = skipwhite(p + 1); 255 while (ASCII_ISALPHA(*(p = skipwhite(p)))) 256 ++p; 257 if (*p == NUL) 258 goto theend; 259 } 260 else if (STRNCMP(cmd, "vimgrep", MAX(p - cmd, 3)) == 0 261 || STRNCMP(cmd, "vimgrepadd", MAX(p - cmd, 8)) == 0 262 || STRNCMP(cmd, "lvimgrep", MAX(p - cmd, 2)) == 0 263 || STRNCMP(cmd, "lvimgrepadd", MAX(p - cmd, 9)) == 0 264 || STRNCMP(cmd, "global", p - cmd) == 0) 265 { 266 // skip over "!" 267 if (*p == '!') 268 { 269 p++; 270 if (*skipwhite(p) == NUL) 271 goto theend; 272 } 273 if (*cmd != 'g') 274 delim_optional = TRUE; 275 } 276 else 277 goto theend; 278 279 p = skipwhite(p); 280 delim = (delim_optional && vim_isIDc(*p)) ? ' ' : *p++; 281 *search_delim = delim; 282 end = skip_regexp(p, delim, p_magic); 283 284 use_last_pat = end == p && *end == delim; 285 286 if (end == p && !use_last_pat) 287 goto theend; 288 289 // Don't do 'hlsearch' highlighting if the pattern matches everything. 290 if (!use_last_pat) 291 { 292 char c = *end; 293 int empty; 294 295 *end = NUL; 296 empty = empty_pattern(p); 297 *end = c; 298 if (empty) 299 goto theend; 300 } 301 302 // found a non-empty pattern or // 303 *skiplen = (int)(p - ccline.cmdbuff); 304 *patlen = (int)(end - p); 305 306 // parse the address range 307 save_cursor = curwin->w_cursor; 308 curwin->w_cursor = is_state->search_start; 309 parse_cmd_address(&ea, &dummy, TRUE); 310 if (ea.addr_count > 0) 311 { 312 // Allow for reverse match. 313 if (ea.line2 < ea.line1) 314 { 315 search_first_line = ea.line2; 316 search_last_line = ea.line1; 317 } 318 else 319 { 320 search_first_line = ea.line1; 321 search_last_line = ea.line2; 322 } 323 } 324 else if (cmd[0] == 's' && cmd[1] != 'o') 325 { 326 // :s defaults to the current line 327 search_first_line = curwin->w_cursor.lnum; 328 search_last_line = curwin->w_cursor.lnum; 329 } 330 331 curwin->w_cursor = save_cursor; 332 retval = TRUE; 333 theend: 334 --emsg_off; 335 return retval; 336 } 337 338 static void 339 finish_incsearch_highlighting( 340 int gotesc, 341 incsearch_state_T *is_state, 342 int call_update_screen) 343 { 344 if (is_state->did_incsearch) 345 { 346 is_state->did_incsearch = FALSE; 347 if (gotesc) 348 curwin->w_cursor = is_state->save_cursor; 349 else 350 { 351 if (!EQUAL_POS(is_state->save_cursor, is_state->search_start)) 352 { 353 // put the '" mark at the original position 354 curwin->w_cursor = is_state->save_cursor; 355 setpcmark(); 356 } 357 curwin->w_cursor = is_state->search_start; 358 } 359 restore_viewstate(&is_state->old_viewstate); 360 highlight_match = FALSE; 361 362 // by default search all lines 363 search_first_line = 0; 364 search_last_line = MAXLNUM; 365 366 p_magic = is_state->magic_save; 367 368 validate_cursor(); // needed for TAB 369 redraw_all_later(SOME_VALID); 370 if (call_update_screen) 371 update_screen(SOME_VALID); 372 } 373 } 374 375 /* 376 * Do 'incsearch' highlighting if desired. 377 */ 378 static void 379 may_do_incsearch_highlighting( 380 int firstc, 381 long count, 382 incsearch_state_T *is_state) 383 { 384 int skiplen, patlen; 385 int found; // do_search() result 386 pos_T end_pos; 387 #ifdef FEAT_RELTIME 388 proftime_T tm; 389 searchit_arg_T sia; 390 #endif 391 int next_char; 392 int use_last_pat; 393 int did_do_incsearch = is_state->did_incsearch; 394 int search_delim; 395 396 // Parsing range may already set the last search pattern. 397 // NOTE: must call restore_last_search_pattern() before returning! 398 save_last_search_pattern(); 399 400 if (!do_incsearch_highlighting(firstc, &search_delim, is_state, &skiplen, &patlen)) 401 { 402 restore_last_search_pattern(); 403 finish_incsearch_highlighting(FALSE, is_state, TRUE); 404 if (did_do_incsearch && vpeekc() == NUL) 405 // may have skipped a redraw, do it now 406 redrawcmd(); 407 return; 408 } 409 410 // If there is a character waiting, search and redraw later. 411 if (char_avail()) 412 { 413 restore_last_search_pattern(); 414 is_state->incsearch_postponed = TRUE; 415 return; 416 } 417 is_state->incsearch_postponed = FALSE; 418 419 if (search_first_line == 0) 420 // start at the original cursor position 421 curwin->w_cursor = is_state->search_start; 422 else if (search_first_line > curbuf->b_ml.ml_line_count) 423 { 424 // start after the last line 425 curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; 426 curwin->w_cursor.col = MAXCOL; 427 } 428 else 429 { 430 // start at the first line in the range 431 curwin->w_cursor.lnum = search_first_line; 432 curwin->w_cursor.col = 0; 433 } 434 435 // Use the previous pattern for ":s//". 436 next_char = ccline.cmdbuff[skiplen + patlen]; 437 use_last_pat = patlen == 0 && skiplen > 0 438 && ccline.cmdbuff[skiplen - 1] == next_char; 439 440 // If there is no pattern, don't do anything. 441 if (patlen == 0 && !use_last_pat) 442 { 443 found = 0; 444 set_no_hlsearch(TRUE); // turn off previous highlight 445 redraw_all_later(SOME_VALID); 446 } 447 else 448 { 449 int search_flags = SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK; 450 451 cursor_off(); // so the user knows we're busy 452 out_flush(); 453 ++emsg_off; // so it doesn't beep if bad expr 454 #ifdef FEAT_RELTIME 455 // Set the time limit to half a second. 456 profile_setlimit(500L, &tm); 457 #endif 458 if (!p_hls) 459 search_flags += SEARCH_KEEP; 460 if (search_first_line != 0) 461 search_flags += SEARCH_START; 462 ccline.cmdbuff[skiplen + patlen] = NUL; 463 #ifdef FEAT_RELTIME 464 CLEAR_FIELD(sia); 465 sia.sa_tm = &tm; 466 #endif 467 found = do_search(NULL, firstc == ':' ? '/' : firstc, search_delim, 468 ccline.cmdbuff + skiplen, count, search_flags, 469 #ifdef FEAT_RELTIME 470 &sia 471 #else 472 NULL 473 #endif 474 ); 475 ccline.cmdbuff[skiplen + patlen] = next_char; 476 --emsg_off; 477 478 if (curwin->w_cursor.lnum < search_first_line 479 || curwin->w_cursor.lnum > search_last_line) 480 { 481 // match outside of address range 482 found = 0; 483 curwin->w_cursor = is_state->search_start; 484 } 485 486 // if interrupted while searching, behave like it failed 487 if (got_int) 488 { 489 (void)vpeekc(); // remove <C-C> from input stream 490 got_int = FALSE; // don't abandon the command line 491 found = 0; 492 } 493 else if (char_avail()) 494 // cancelled searching because a char was typed 495 is_state->incsearch_postponed = TRUE; 496 } 497 if (found != 0) 498 highlight_match = TRUE; // highlight position 499 else 500 highlight_match = FALSE; // remove highlight 501 502 // First restore the old curwin values, so the screen is positioned in the 503 // same way as the actual search command. 504 restore_viewstate(&is_state->old_viewstate); 505 changed_cline_bef_curs(); 506 update_topline(); 507 508 if (found != 0) 509 { 510 pos_T save_pos = curwin->w_cursor; 511 512 is_state->match_start = curwin->w_cursor; 513 set_search_match(&curwin->w_cursor); 514 validate_cursor(); 515 end_pos = curwin->w_cursor; 516 is_state->match_end = end_pos; 517 curwin->w_cursor = save_pos; 518 } 519 else 520 end_pos = curwin->w_cursor; // shutup gcc 4 521 522 // Disable 'hlsearch' highlighting if the pattern matches everything. 523 // Avoids a flash when typing "foo\|". 524 if (!use_last_pat) 525 { 526 next_char = ccline.cmdbuff[skiplen + patlen]; 527 ccline.cmdbuff[skiplen + patlen] = NUL; 528 if (empty_pattern(ccline.cmdbuff) && !no_hlsearch) 529 { 530 redraw_all_later(SOME_VALID); 531 set_no_hlsearch(TRUE); 532 } 533 ccline.cmdbuff[skiplen + patlen] = next_char; 534 } 535 536 validate_cursor(); 537 // May redraw the status line to show the cursor position. 538 if (p_ru && curwin->w_status_height > 0) 539 curwin->w_redr_status = TRUE; 540 541 update_screen(SOME_VALID); 542 highlight_match = FALSE; 543 restore_last_search_pattern(); 544 545 // Leave it at the end to make CTRL-R CTRL-W work. But not when beyond the 546 // end of the pattern, e.g. for ":s/pat/". 547 if (ccline.cmdbuff[skiplen + patlen] != NUL) 548 curwin->w_cursor = is_state->search_start; 549 else if (found != 0) 550 curwin->w_cursor = end_pos; 551 552 msg_starthere(); 553 redrawcmdline(); 554 is_state->did_incsearch = TRUE; 555 } 556 557 /* 558 * May adjust 'incsearch' highlighting for typing CTRL-G and CTRL-T, go to next 559 * or previous match. 560 * Returns FAIL when jumping to cmdline_not_changed; 561 */ 562 static int 563 may_adjust_incsearch_highlighting( 564 int firstc, 565 long count, 566 incsearch_state_T *is_state, 567 int c) 568 { 569 int skiplen, patlen; 570 pos_T t; 571 char_u *pat; 572 int search_flags = SEARCH_NOOF; 573 int i; 574 int save; 575 int search_delim; 576 577 // Parsing range may already set the last search pattern. 578 // NOTE: must call restore_last_search_pattern() before returning! 579 save_last_search_pattern(); 580 581 if (!do_incsearch_highlighting(firstc, &search_delim, is_state, &skiplen, &patlen)) 582 { 583 restore_last_search_pattern(); 584 return OK; 585 } 586 if (patlen == 0 && ccline.cmdbuff[skiplen] == NUL) 587 { 588 restore_last_search_pattern(); 589 return FAIL; 590 } 591 592 if (search_delim == ccline.cmdbuff[skiplen]) 593 { 594 pat = last_search_pattern(); 595 skiplen = 0; 596 patlen = (int)STRLEN(pat); 597 } 598 else 599 pat = ccline.cmdbuff + skiplen; 600 601 cursor_off(); 602 out_flush(); 603 if (c == Ctrl_G) 604 { 605 t = is_state->match_end; 606 if (LT_POS(is_state->match_start, is_state->match_end)) 607 // Start searching at the end of the match not at the beginning of 608 // the next column. 609 (void)decl(&t); 610 search_flags += SEARCH_COL; 611 } 612 else 613 t = is_state->match_start; 614 if (!p_hls) 615 search_flags += SEARCH_KEEP; 616 ++emsg_off; 617 save = pat[patlen]; 618 pat[patlen] = NUL; 619 i = searchit(curwin, curbuf, &t, NULL, 620 c == Ctrl_G ? FORWARD : BACKWARD, 621 pat, count, search_flags, RE_SEARCH, NULL); 622 --emsg_off; 623 pat[patlen] = save; 624 if (i) 625 { 626 is_state->search_start = is_state->match_start; 627 is_state->match_end = t; 628 is_state->match_start = t; 629 if (c == Ctrl_T && firstc != '?') 630 { 631 // Move just before the current match, so that when nv_search 632 // finishes the cursor will be put back on the match. 633 is_state->search_start = t; 634 (void)decl(&is_state->search_start); 635 } 636 else if (c == Ctrl_G && firstc == '?') 637 { 638 // Move just after the current match, so that when nv_search 639 // finishes the cursor will be put back on the match. 640 is_state->search_start = t; 641 (void)incl(&is_state->search_start); 642 } 643 if (LT_POS(t, is_state->search_start) && c == Ctrl_G) 644 { 645 // wrap around 646 is_state->search_start = t; 647 if (firstc == '?') 648 (void)incl(&is_state->search_start); 649 else 650 (void)decl(&is_state->search_start); 651 } 652 653 set_search_match(&is_state->match_end); 654 curwin->w_cursor = is_state->match_start; 655 changed_cline_bef_curs(); 656 update_topline(); 657 validate_cursor(); 658 highlight_match = TRUE; 659 save_viewstate(&is_state->old_viewstate); 660 update_screen(NOT_VALID); 661 highlight_match = FALSE; 662 redrawcmdline(); 663 curwin->w_cursor = is_state->match_end; 664 } 665 else 666 vim_beep(BO_ERROR); 667 restore_last_search_pattern(); 668 return FAIL; 669 } 670 671 /* 672 * When CTRL-L typed: add character from the match to the pattern. 673 * May set "*c" to the added character. 674 * Return OK when jumping to cmdline_not_changed. 675 */ 676 static int 677 may_add_char_to_search(int firstc, int *c, incsearch_state_T *is_state) 678 { 679 int skiplen, patlen, search_delim; 680 681 // Parsing range may already set the last search pattern. 682 // NOTE: must call restore_last_search_pattern() before returning! 683 save_last_search_pattern(); 684 685 if (!do_incsearch_highlighting(firstc, &search_delim, is_state, &skiplen, &patlen)) 686 { 687 restore_last_search_pattern(); 688 return FAIL; 689 } 690 restore_last_search_pattern(); 691 692 // Add a character from under the cursor for 'incsearch'. 693 if (is_state->did_incsearch) 694 { 695 curwin->w_cursor = is_state->match_end; 696 *c = gchar_cursor(); 697 if (*c != NUL) 698 { 699 // If 'ignorecase' and 'smartcase' are set and the 700 // command line has no uppercase characters, convert 701 // the character to lowercase. 702 if (p_ic && p_scs && !pat_has_uppercase(ccline.cmdbuff + skiplen)) 703 *c = MB_TOLOWER(*c); 704 if (*c == search_delim || vim_strchr((char_u *)( 705 p_magic ? "\\~^$.*[" : "\\^$"), *c) != NULL) 706 { 707 // put a backslash before special characters 708 stuffcharReadbuff(*c); 709 *c = '\\'; 710 } 711 // add any composing characters 712 if (mb_char2len(*c) != mb_ptr2len(ml_get_cursor())) 713 { 714 int save_c = *c; 715 716 while (mb_char2len(*c) != mb_ptr2len(ml_get_cursor())) 717 { 718 curwin->w_cursor.col += mb_char2len(*c); 719 *c = gchar_cursor(); 720 stuffcharReadbuff(*c); 721 } 722 *c = save_c; 723 } 724 return FAIL; 725 } 726 } 727 return OK; 728 } 729 #endif 730 731 #ifdef FEAT_ARABIC 732 /* 733 * Return TRUE if the command line has an Arabic character at or after "start" 734 * for "len" bytes. 735 */ 736 static int 737 cmdline_has_arabic(int start, int len) 738 { 739 int j; 740 int mb_l; 741 int u8c; 742 char_u *p; 743 int u8cc[MAX_MCO]; 744 745 if (!enc_utf8) 746 return FALSE; 747 748 for (j = start; j < start + len; j += mb_l) 749 { 750 p = ccline.cmdbuff + j; 751 u8c = utfc_ptr2char_len(p, u8cc, start + len - j); 752 mb_l = utfc_ptr2len_len(p, start + len - j); 753 if (ARABIC_CHAR(u8c)) 754 return TRUE; 755 } 756 return FALSE; 757 } 758 #endif 759 760 void 761 cmdline_init(void) 762 { 763 CLEAR_FIELD(ccline); 764 } 765 766 /* 767 * getcmdline() - accept a command line starting with firstc. 768 * 769 * firstc == ':' get ":" command line. 770 * firstc == '/' or '?' get search pattern 771 * firstc == '=' get expression 772 * firstc == '@' get text for input() function 773 * firstc == '>' get text for debug mode 774 * firstc == NUL get text for :insert command 775 * firstc == -1 like NUL, and break on CTRL-C 776 * 777 * The line is collected in ccline.cmdbuff, which is reallocated to fit the 778 * command line. 779 * 780 * Careful: getcmdline() can be called recursively! 781 * 782 * Return pointer to allocated string if there is a commandline, NULL 783 * otherwise. 784 */ 785 char_u * 786 getcmdline( 787 int firstc, 788 long count, // only used for incremental search 789 int indent, // indent for inside conditionals 790 int do_concat UNUSED) 791 { 792 return getcmdline_int(firstc, count, indent, TRUE); 793 } 794 795 static char_u * 796 getcmdline_int( 797 int firstc, 798 long count UNUSED, // only used for incremental search 799 int indent, // indent for inside conditionals 800 int init_ccline) // clear ccline first 801 { 802 int c; 803 int i; 804 int j; 805 int gotesc = FALSE; // TRUE when <ESC> just typed 806 int do_abbr; // when TRUE check for abbr. 807 char_u *lookfor = NULL; // string to match 808 int hiscnt; // current history line in use 809 int histype; // history type to be used 810 #ifdef FEAT_SEARCH_EXTRA 811 incsearch_state_T is_state; 812 #endif 813 int did_wild_list = FALSE; // did wild_list() recently 814 int wim_index = 0; // index in wim_flags[] 815 int res; 816 int save_msg_scroll = msg_scroll; 817 int save_State = State; // remember State when called 818 int some_key_typed = FALSE; // one of the keys was typed 819 // mouse drag and release events are ignored, unless they are 820 // preceded with a mouse down event 821 int ignore_drag_release = TRUE; 822 #ifdef FEAT_EVAL 823 int break_ctrl_c = FALSE; 824 #endif 825 expand_T xpc; 826 long *b_im_ptr = NULL; 827 cmdline_info_T save_ccline; 828 int did_save_ccline = FALSE; 829 int cmdline_type; 830 831 if (ccline.cmdbuff != NULL) 832 { 833 // Being called recursively. Since ccline is global, we need to save 834 // the current buffer and restore it when returning. 835 save_cmdline(&save_ccline); 836 did_save_ccline = TRUE; 837 } 838 if (init_ccline) 839 CLEAR_FIELD(ccline); 840 841 #ifdef FEAT_EVAL 842 if (firstc == -1) 843 { 844 firstc = NUL; 845 break_ctrl_c = TRUE; 846 } 847 #endif 848 #ifdef FEAT_RIGHTLEFT 849 // start without Hebrew mapping for a command line 850 if (firstc == ':' || firstc == '=' || firstc == '>') 851 cmd_hkmap = 0; 852 #endif 853 854 ccline.overstrike = FALSE; // always start in insert mode 855 856 #ifdef FEAT_SEARCH_EXTRA 857 init_incsearch_state(&is_state); 858 #endif 859 860 /* 861 * set some variables for redrawcmd() 862 */ 863 ccline.cmdfirstc = (firstc == '@' ? 0 : firstc); 864 ccline.cmdindent = (firstc > 0 ? indent : 0); 865 866 // alloc initial ccline.cmdbuff 867 alloc_cmdbuff(exmode_active ? 250 : indent + 1); 868 if (ccline.cmdbuff == NULL) 869 goto theend; // out of memory 870 ccline.cmdlen = ccline.cmdpos = 0; 871 ccline.cmdbuff[0] = NUL; 872 sb_text_start_cmdline(); 873 874 // autoindent for :insert and :append 875 if (firstc <= 0) 876 { 877 vim_memset(ccline.cmdbuff, ' ', indent); 878 ccline.cmdbuff[indent] = NUL; 879 ccline.cmdpos = indent; 880 ccline.cmdspos = indent; 881 ccline.cmdlen = indent; 882 } 883 884 ExpandInit(&xpc); 885 ccline.xpc = &xpc; 886 887 #ifdef FEAT_RIGHTLEFT 888 if (curwin->w_p_rl && *curwin->w_p_rlc == 's' 889 && (firstc == '/' || firstc == '?')) 890 cmdmsg_rl = TRUE; 891 else 892 cmdmsg_rl = FALSE; 893 #endif 894 895 redir_off = TRUE; // don't redirect the typed command 896 if (!cmd_silent) 897 { 898 i = msg_scrolled; 899 msg_scrolled = 0; // avoid wait_return message 900 gotocmdline(TRUE); 901 msg_scrolled += i; 902 redrawcmdprompt(); // draw prompt or indent 903 set_cmdspos(); 904 } 905 xpc.xp_context = EXPAND_NOTHING; 906 xpc.xp_backslash = XP_BS_NONE; 907 #ifndef BACKSLASH_IN_FILENAME 908 xpc.xp_shell = FALSE; 909 #endif 910 911 #if defined(FEAT_EVAL) 912 if (ccline.input_fn) 913 { 914 xpc.xp_context = ccline.xp_context; 915 xpc.xp_pattern = ccline.cmdbuff; 916 xpc.xp_arg = ccline.xp_arg; 917 } 918 #endif 919 920 /* 921 * Avoid scrolling when called by a recursive do_cmdline(), e.g. when 922 * doing ":@0" when register 0 doesn't contain a CR. 923 */ 924 msg_scroll = FALSE; 925 926 State = CMDLINE; 927 928 if (firstc == '/' || firstc == '?' || firstc == '@') 929 { 930 // Use ":lmap" mappings for search pattern and input(). 931 if (curbuf->b_p_imsearch == B_IMODE_USE_INSERT) 932 b_im_ptr = &curbuf->b_p_iminsert; 933 else 934 b_im_ptr = &curbuf->b_p_imsearch; 935 if (*b_im_ptr == B_IMODE_LMAP) 936 State |= LANGMAP; 937 #ifdef HAVE_INPUT_METHOD 938 im_set_active(*b_im_ptr == B_IMODE_IM); 939 #endif 940 } 941 #ifdef HAVE_INPUT_METHOD 942 else if (p_imcmdline) 943 im_set_active(TRUE); 944 #endif 945 946 setmouse(); 947 #ifdef CURSOR_SHAPE 948 ui_cursor_shape(); // may show different cursor shape 949 #endif 950 951 // When inside an autocommand for writing "exiting" may be set and 952 // terminal mode set to cooked. Need to set raw mode here then. 953 settmode(TMODE_RAW); 954 955 // Trigger CmdlineEnter autocommands. 956 cmdline_type = firstc == NUL ? '-' : firstc; 957 trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINEENTER); 958 959 init_history(); 960 hiscnt = get_hislen(); // set hiscnt to impossible history value 961 histype = hist_char2type(firstc); 962 963 #ifdef FEAT_DIGRAPHS 964 do_digraph(-1); // init digraph typeahead 965 #endif 966 967 // If something above caused an error, reset the flags, we do want to type 968 // and execute commands. Display may be messed up a bit. 969 if (did_emsg) 970 redrawcmd(); 971 did_emsg = FALSE; 972 got_int = FALSE; 973 974 /* 975 * Collect the command string, handling editing keys. 976 */ 977 for (;;) 978 { 979 redir_off = TRUE; // Don't redirect the typed command. 980 // Repeated, because a ":redir" inside 981 // completion may switch it on. 982 #ifdef USE_ON_FLY_SCROLL 983 dont_scroll = FALSE; // allow scrolling here 984 #endif 985 quit_more = FALSE; // reset after CTRL-D which had a more-prompt 986 987 did_emsg = FALSE; // There can't really be a reason why an error 988 // that occurs while typing a command should 989 // cause the command not to be executed. 990 991 // Trigger SafeState if nothing is pending. 992 may_trigger_safestate(xpc.xp_numfiles <= 0); 993 994 cursorcmd(); // set the cursor on the right spot 995 996 // Get a character. Ignore K_IGNORE and K_NOP, they should not do 997 // anything, such as stop completion. 998 do 999 c = safe_vgetc(); 1000 while (c == K_IGNORE || c == K_NOP); 1001 1002 if (KeyTyped) 1003 { 1004 some_key_typed = TRUE; 1005 #ifdef FEAT_RIGHTLEFT 1006 if (cmd_hkmap) 1007 c = hkmap(c); 1008 if (cmdmsg_rl && !KeyStuffed) 1009 { 1010 // Invert horizontal movements and operations. Only when 1011 // typed by the user directly, not when the result of a 1012 // mapping. 1013 switch (c) 1014 { 1015 case K_RIGHT: c = K_LEFT; break; 1016 case K_S_RIGHT: c = K_S_LEFT; break; 1017 case K_C_RIGHT: c = K_C_LEFT; break; 1018 case K_LEFT: c = K_RIGHT; break; 1019 case K_S_LEFT: c = K_S_RIGHT; break; 1020 case K_C_LEFT: c = K_C_RIGHT; break; 1021 } 1022 } 1023 #endif 1024 } 1025 1026 /* 1027 * Ignore got_int when CTRL-C was typed here. 1028 * Don't ignore it in :global, we really need to break then, e.g., for 1029 * ":g/pat/normal /pat" (without the <CR>). 1030 * Don't ignore it for the input() function. 1031 */ 1032 if ((c == Ctrl_C 1033 #ifdef UNIX 1034 || c == intr_char 1035 #endif 1036 ) 1037 #if defined(FEAT_EVAL) || defined(FEAT_CRYPT) 1038 && firstc != '@' 1039 #endif 1040 #ifdef FEAT_EVAL 1041 && !break_ctrl_c 1042 #endif 1043 && !global_busy) 1044 got_int = FALSE; 1045 1046 // free old command line when finished moving around in the history 1047 // list 1048 if (lookfor != NULL 1049 && c != K_S_DOWN && c != K_S_UP 1050 && c != K_DOWN && c != K_UP 1051 && c != K_PAGEDOWN && c != K_PAGEUP 1052 && c != K_KPAGEDOWN && c != K_KPAGEUP 1053 && c != K_LEFT && c != K_RIGHT 1054 && (xpc.xp_numfiles > 0 || (c != Ctrl_P && c != Ctrl_N))) 1055 VIM_CLEAR(lookfor); 1056 1057 /* 1058 * When there are matching completions to select <S-Tab> works like 1059 * CTRL-P (unless 'wc' is <S-Tab>). 1060 */ 1061 if (c != p_wc && c == K_S_TAB && xpc.xp_numfiles > 0) 1062 c = Ctrl_P; 1063 1064 #ifdef FEAT_WILDMENU 1065 // Special translations for 'wildmenu' 1066 if (did_wild_list && p_wmnu) 1067 { 1068 if (c == K_LEFT) 1069 c = Ctrl_P; 1070 else if (c == K_RIGHT) 1071 c = Ctrl_N; 1072 } 1073 // Hitting CR after "emenu Name.": complete submenu 1074 if (xpc.xp_context == EXPAND_MENUNAMES && p_wmnu 1075 && ccline.cmdpos > 1 1076 && ccline.cmdbuff[ccline.cmdpos - 1] == '.' 1077 && ccline.cmdbuff[ccline.cmdpos - 2] != '\\' 1078 && (c == '\n' || c == '\r' || c == K_KENTER)) 1079 c = K_DOWN; 1080 #endif 1081 1082 // free expanded names when finished walking through matches 1083 if (xpc.xp_numfiles != -1 1084 && !(c == p_wc && KeyTyped) && c != p_wcm 1085 && c != Ctrl_N && c != Ctrl_P && c != Ctrl_A 1086 && c != Ctrl_L) 1087 { 1088 (void)ExpandOne(&xpc, NULL, NULL, 0, WILD_FREE); 1089 did_wild_list = FALSE; 1090 #ifdef FEAT_WILDMENU 1091 if (!p_wmnu || (c != K_UP && c != K_DOWN)) 1092 #endif 1093 xpc.xp_context = EXPAND_NOTHING; 1094 wim_index = 0; 1095 #ifdef FEAT_WILDMENU 1096 if (p_wmnu && wild_menu_showing != 0) 1097 { 1098 int skt = KeyTyped; 1099 int old_RedrawingDisabled = RedrawingDisabled; 1100 1101 if (ccline.input_fn) 1102 RedrawingDisabled = 0; 1103 1104 if (wild_menu_showing == WM_SCROLLED) 1105 { 1106 // Entered command line, move it up 1107 cmdline_row--; 1108 redrawcmd(); 1109 } 1110 else if (save_p_ls != -1) 1111 { 1112 // restore 'laststatus' and 'winminheight' 1113 p_ls = save_p_ls; 1114 p_wmh = save_p_wmh; 1115 last_status(FALSE); 1116 update_screen(VALID); // redraw the screen NOW 1117 redrawcmd(); 1118 save_p_ls = -1; 1119 } 1120 else 1121 { 1122 win_redraw_last_status(topframe); 1123 redraw_statuslines(); 1124 } 1125 KeyTyped = skt; 1126 wild_menu_showing = 0; 1127 if (ccline.input_fn) 1128 RedrawingDisabled = old_RedrawingDisabled; 1129 } 1130 #endif 1131 } 1132 1133 #ifdef FEAT_WILDMENU 1134 // Special translations for 'wildmenu' 1135 if (xpc.xp_context == EXPAND_MENUNAMES && p_wmnu) 1136 { 1137 // Hitting <Down> after "emenu Name.": complete submenu 1138 if (c == K_DOWN && ccline.cmdpos > 0 1139 && ccline.cmdbuff[ccline.cmdpos - 1] == '.') 1140 c = p_wc; 1141 else if (c == K_UP) 1142 { 1143 // Hitting <Up>: Remove one submenu name in front of the 1144 // cursor 1145 int found = FALSE; 1146 1147 j = (int)(xpc.xp_pattern - ccline.cmdbuff); 1148 i = 0; 1149 while (--j > 0) 1150 { 1151 // check for start of menu name 1152 if (ccline.cmdbuff[j] == ' ' 1153 && ccline.cmdbuff[j - 1] != '\\') 1154 { 1155 i = j + 1; 1156 break; 1157 } 1158 // check for start of submenu name 1159 if (ccline.cmdbuff[j] == '.' 1160 && ccline.cmdbuff[j - 1] != '\\') 1161 { 1162 if (found) 1163 { 1164 i = j + 1; 1165 break; 1166 } 1167 else 1168 found = TRUE; 1169 } 1170 } 1171 if (i > 0) 1172 cmdline_del(i); 1173 c = p_wc; 1174 xpc.xp_context = EXPAND_NOTHING; 1175 } 1176 } 1177 if ((xpc.xp_context == EXPAND_FILES 1178 || xpc.xp_context == EXPAND_DIRECTORIES 1179 || xpc.xp_context == EXPAND_SHELLCMD) && p_wmnu) 1180 { 1181 char_u upseg[5]; 1182 1183 upseg[0] = PATHSEP; 1184 upseg[1] = '.'; 1185 upseg[2] = '.'; 1186 upseg[3] = PATHSEP; 1187 upseg[4] = NUL; 1188 1189 if (c == K_DOWN 1190 && ccline.cmdpos > 0 1191 && ccline.cmdbuff[ccline.cmdpos - 1] == PATHSEP 1192 && (ccline.cmdpos < 3 1193 || ccline.cmdbuff[ccline.cmdpos - 2] != '.' 1194 || ccline.cmdbuff[ccline.cmdpos - 3] != '.')) 1195 { 1196 // go down a directory 1197 c = p_wc; 1198 } 1199 else if (STRNCMP(xpc.xp_pattern, upseg + 1, 3) == 0 && c == K_DOWN) 1200 { 1201 // If in a direct ancestor, strip off one ../ to go down 1202 int found = FALSE; 1203 1204 j = ccline.cmdpos; 1205 i = (int)(xpc.xp_pattern - ccline.cmdbuff); 1206 while (--j > i) 1207 { 1208 if (has_mbyte) 1209 j -= (*mb_head_off)(ccline.cmdbuff, ccline.cmdbuff + j); 1210 if (vim_ispathsep(ccline.cmdbuff[j])) 1211 { 1212 found = TRUE; 1213 break; 1214 } 1215 } 1216 if (found 1217 && ccline.cmdbuff[j - 1] == '.' 1218 && ccline.cmdbuff[j - 2] == '.' 1219 && (vim_ispathsep(ccline.cmdbuff[j - 3]) || j == i + 2)) 1220 { 1221 cmdline_del(j - 2); 1222 c = p_wc; 1223 } 1224 } 1225 else if (c == K_UP) 1226 { 1227 // go up a directory 1228 int found = FALSE; 1229 1230 j = ccline.cmdpos - 1; 1231 i = (int)(xpc.xp_pattern - ccline.cmdbuff); 1232 while (--j > i) 1233 { 1234 if (has_mbyte) 1235 j -= (*mb_head_off)(ccline.cmdbuff, ccline.cmdbuff + j); 1236 if (vim_ispathsep(ccline.cmdbuff[j]) 1237 #ifdef BACKSLASH_IN_FILENAME 1238 && vim_strchr((char_u *)" *?[{`$%#", 1239 ccline.cmdbuff[j + 1]) == NULL 1240 #endif 1241 ) 1242 { 1243 if (found) 1244 { 1245 i = j + 1; 1246 break; 1247 } 1248 else 1249 found = TRUE; 1250 } 1251 } 1252 1253 if (!found) 1254 j = i; 1255 else if (STRNCMP(ccline.cmdbuff + j, upseg, 4) == 0) 1256 j += 4; 1257 else if (STRNCMP(ccline.cmdbuff + j, upseg + 1, 3) == 0 1258 && j == i) 1259 j += 3; 1260 else 1261 j = 0; 1262 if (j > 0) 1263 { 1264 // TODO this is only for DOS/UNIX systems - need to put in 1265 // machine-specific stuff here and in upseg init 1266 cmdline_del(j); 1267 put_on_cmdline(upseg + 1, 3, FALSE); 1268 } 1269 else if (ccline.cmdpos > i) 1270 cmdline_del(i); 1271 1272 // Now complete in the new directory. Set KeyTyped in case the 1273 // Up key came from a mapping. 1274 c = p_wc; 1275 KeyTyped = TRUE; 1276 } 1277 } 1278 1279 #endif // FEAT_WILDMENU 1280 1281 // CTRL-\ CTRL-N goes to Normal mode, CTRL-\ CTRL-G goes to Insert 1282 // mode when 'insertmode' is set, CTRL-\ e prompts for an expression. 1283 if (c == Ctrl_BSL) 1284 { 1285 ++no_mapping; 1286 ++allow_keys; 1287 c = plain_vgetc(); 1288 --no_mapping; 1289 --allow_keys; 1290 // CTRL-\ e doesn't work when obtaining an expression, unless it 1291 // is in a mapping. 1292 if (c != Ctrl_N && c != Ctrl_G && (c != 'e' 1293 || (ccline.cmdfirstc == '=' && KeyTyped) 1294 #ifdef FEAT_EVAL 1295 || cmdline_star > 0 1296 #endif 1297 )) 1298 { 1299 vungetc(c); 1300 c = Ctrl_BSL; 1301 } 1302 #ifdef FEAT_EVAL 1303 else if (c == 'e') 1304 { 1305 char_u *p = NULL; 1306 int len; 1307 1308 /* 1309 * Replace the command line with the result of an expression. 1310 * Need to save and restore the current command line, to be 1311 * able to enter a new one... 1312 */ 1313 if (ccline.cmdpos == ccline.cmdlen) 1314 new_cmdpos = 99999; // keep it at the end 1315 else 1316 new_cmdpos = ccline.cmdpos; 1317 1318 c = get_expr_register(); 1319 if (c == '=') 1320 { 1321 // Need to save and restore ccline. And set "textwinlock" 1322 // to avoid nasty things like going to another buffer when 1323 // evaluating an expression. 1324 ++textwinlock; 1325 p = get_expr_line(); 1326 --textwinlock; 1327 1328 if (p != NULL) 1329 { 1330 len = (int)STRLEN(p); 1331 if (realloc_cmdbuff(len + 1) == OK) 1332 { 1333 ccline.cmdlen = len; 1334 STRCPY(ccline.cmdbuff, p); 1335 vim_free(p); 1336 1337 // Restore the cursor or use the position set with 1338 // set_cmdline_pos(). 1339 if (new_cmdpos > ccline.cmdlen) 1340 ccline.cmdpos = ccline.cmdlen; 1341 else 1342 ccline.cmdpos = new_cmdpos; 1343 1344 KeyTyped = FALSE; // Don't do p_wc completion. 1345 redrawcmd(); 1346 goto cmdline_changed; 1347 } 1348 vim_free(p); 1349 } 1350 } 1351 beep_flush(); 1352 got_int = FALSE; // don't abandon the command line 1353 did_emsg = FALSE; 1354 emsg_on_display = FALSE; 1355 redrawcmd(); 1356 goto cmdline_not_changed; 1357 } 1358 #endif 1359 else 1360 { 1361 if (c == Ctrl_G && p_im && restart_edit == 0) 1362 restart_edit = 'a'; 1363 gotesc = TRUE; // will free ccline.cmdbuff after putting it 1364 // in history 1365 goto returncmd; // back to Normal mode 1366 } 1367 } 1368 1369 #ifdef FEAT_CMDWIN 1370 if (c == cedit_key || c == K_CMDWIN) 1371 { 1372 // TODO: why is ex_normal_busy checked here? 1373 if ((c == K_CMDWIN || ex_normal_busy == 0) && got_int == FALSE) 1374 { 1375 /* 1376 * Open a window to edit the command line (and history). 1377 */ 1378 c = open_cmdwin(); 1379 some_key_typed = TRUE; 1380 } 1381 } 1382 # ifdef FEAT_DIGRAPHS 1383 else 1384 # endif 1385 #endif 1386 #ifdef FEAT_DIGRAPHS 1387 c = do_digraph(c); 1388 #endif 1389 1390 if (c == '\n' || c == '\r' || c == K_KENTER || (c == ESC 1391 && (!KeyTyped || vim_strchr(p_cpo, CPO_ESC) != NULL))) 1392 { 1393 // In Ex mode a backslash escapes a newline. 1394 if (exmode_active 1395 && c != ESC 1396 && ccline.cmdpos == ccline.cmdlen 1397 && ccline.cmdpos > 0 1398 && ccline.cmdbuff[ccline.cmdpos - 1] == '\\') 1399 { 1400 if (c == K_KENTER) 1401 c = '\n'; 1402 } 1403 else 1404 { 1405 gotesc = FALSE; // Might have typed ESC previously, don't 1406 // truncate the cmdline now. 1407 if (ccheck_abbr(c + ABBR_OFF)) 1408 goto cmdline_changed; 1409 if (!cmd_silent) 1410 { 1411 windgoto(msg_row, 0); 1412 out_flush(); 1413 } 1414 break; 1415 } 1416 } 1417 1418 /* 1419 * Completion for 'wildchar' or 'wildcharm' key. 1420 * - hitting <ESC> twice means: abandon command line. 1421 * - wildcard expansion is only done when the 'wildchar' key is really 1422 * typed, not when it comes from a macro 1423 */ 1424 if ((c == p_wc && !gotesc && KeyTyped) || c == p_wcm) 1425 { 1426 int options = WILD_NO_BEEP; 1427 if (wim_flags[wim_index] & WIM_BUFLASTUSED) 1428 options |= WILD_BUFLASTUSED; 1429 if (xpc.xp_numfiles > 0) // typed p_wc at least twice 1430 { 1431 // if 'wildmode' contains "list" may still need to list 1432 if (xpc.xp_numfiles > 1 1433 && !did_wild_list 1434 && (wim_flags[wim_index] & WIM_LIST)) 1435 { 1436 (void)showmatches(&xpc, FALSE); 1437 redrawcmd(); 1438 did_wild_list = TRUE; 1439 } 1440 if (wim_flags[wim_index] & WIM_LONGEST) 1441 res = nextwild(&xpc, WILD_LONGEST, options, 1442 firstc != '@'); 1443 else if (wim_flags[wim_index] & WIM_FULL) 1444 res = nextwild(&xpc, WILD_NEXT, options, 1445 firstc != '@'); 1446 else 1447 res = OK; // don't insert 'wildchar' now 1448 } 1449 else // typed p_wc first time 1450 { 1451 wim_index = 0; 1452 j = ccline.cmdpos; 1453 // if 'wildmode' first contains "longest", get longest 1454 // common part 1455 if (wim_flags[0] & WIM_LONGEST) 1456 res = nextwild(&xpc, WILD_LONGEST, options, 1457 firstc != '@'); 1458 else 1459 res = nextwild(&xpc, WILD_EXPAND_KEEP, options, 1460 firstc != '@'); 1461 1462 // if interrupted while completing, behave like it failed 1463 if (got_int) 1464 { 1465 (void)vpeekc(); // remove <C-C> from input stream 1466 got_int = FALSE; // don't abandon the command line 1467 (void)ExpandOne(&xpc, NULL, NULL, 0, WILD_FREE); 1468 #ifdef FEAT_WILDMENU 1469 xpc.xp_context = EXPAND_NOTHING; 1470 #endif 1471 goto cmdline_changed; 1472 } 1473 1474 // when more than one match, and 'wildmode' first contains 1475 // "list", or no change and 'wildmode' contains "longest,list", 1476 // list all matches 1477 if (res == OK && xpc.xp_numfiles > 1) 1478 { 1479 // a "longest" that didn't do anything is skipped (but not 1480 // "list:longest") 1481 if (wim_flags[0] == WIM_LONGEST && ccline.cmdpos == j) 1482 wim_index = 1; 1483 if ((wim_flags[wim_index] & WIM_LIST) 1484 #ifdef FEAT_WILDMENU 1485 || (p_wmnu && (wim_flags[wim_index] & WIM_FULL) != 0) 1486 #endif 1487 ) 1488 { 1489 if (!(wim_flags[0] & WIM_LONGEST)) 1490 { 1491 #ifdef FEAT_WILDMENU 1492 int p_wmnu_save = p_wmnu; 1493 p_wmnu = 0; 1494 #endif 1495 // remove match 1496 nextwild(&xpc, WILD_PREV, 0, firstc != '@'); 1497 #ifdef FEAT_WILDMENU 1498 p_wmnu = p_wmnu_save; 1499 #endif 1500 } 1501 #ifdef FEAT_WILDMENU 1502 (void)showmatches(&xpc, p_wmnu 1503 && ((wim_flags[wim_index] & WIM_LIST) == 0)); 1504 #else 1505 (void)showmatches(&xpc, FALSE); 1506 #endif 1507 redrawcmd(); 1508 did_wild_list = TRUE; 1509 if (wim_flags[wim_index] & WIM_LONGEST) 1510 nextwild(&xpc, WILD_LONGEST, options, 1511 firstc != '@'); 1512 else if (wim_flags[wim_index] & WIM_FULL) 1513 nextwild(&xpc, WILD_NEXT, options, 1514 firstc != '@'); 1515 } 1516 else 1517 vim_beep(BO_WILD); 1518 } 1519 #ifdef FEAT_WILDMENU 1520 else if (xpc.xp_numfiles == -1) 1521 xpc.xp_context = EXPAND_NOTHING; 1522 #endif 1523 } 1524 if (wim_index < 3) 1525 ++wim_index; 1526 if (c == ESC) 1527 gotesc = TRUE; 1528 if (res == OK) 1529 goto cmdline_changed; 1530 } 1531 1532 gotesc = FALSE; 1533 1534 // <S-Tab> goes to last match, in a clumsy way 1535 if (c == K_S_TAB && KeyTyped) 1536 { 1537 if (nextwild(&xpc, WILD_EXPAND_KEEP, 0, firstc != '@') == OK 1538 && nextwild(&xpc, WILD_PREV, 0, firstc != '@') == OK 1539 && nextwild(&xpc, WILD_PREV, 0, firstc != '@') == OK) 1540 goto cmdline_changed; 1541 } 1542 1543 if (c == NUL || c == K_ZERO) // NUL is stored as NL 1544 c = NL; 1545 1546 do_abbr = TRUE; // default: check for abbreviation 1547 1548 /* 1549 * Big switch for a typed command line character. 1550 */ 1551 switch (c) 1552 { 1553 case K_BS: 1554 case Ctrl_H: 1555 case K_DEL: 1556 case K_KDEL: 1557 case Ctrl_W: 1558 if (c == K_KDEL) 1559 c = K_DEL; 1560 1561 /* 1562 * delete current character is the same as backspace on next 1563 * character, except at end of line 1564 */ 1565 if (c == K_DEL && ccline.cmdpos != ccline.cmdlen) 1566 ++ccline.cmdpos; 1567 if (has_mbyte && c == K_DEL) 1568 ccline.cmdpos += mb_off_next(ccline.cmdbuff, 1569 ccline.cmdbuff + ccline.cmdpos); 1570 if (ccline.cmdpos > 0) 1571 { 1572 char_u *p; 1573 1574 j = ccline.cmdpos; 1575 p = ccline.cmdbuff + j; 1576 if (has_mbyte) 1577 { 1578 p = mb_prevptr(ccline.cmdbuff, p); 1579 if (c == Ctrl_W) 1580 { 1581 while (p > ccline.cmdbuff && vim_isspace(*p)) 1582 p = mb_prevptr(ccline.cmdbuff, p); 1583 i = mb_get_class(p); 1584 while (p > ccline.cmdbuff && mb_get_class(p) == i) 1585 p = mb_prevptr(ccline.cmdbuff, p); 1586 if (mb_get_class(p) != i) 1587 p += (*mb_ptr2len)(p); 1588 } 1589 } 1590 else if (c == Ctrl_W) 1591 { 1592 while (p > ccline.cmdbuff && vim_isspace(p[-1])) 1593 --p; 1594 i = vim_iswordc(p[-1]); 1595 while (p > ccline.cmdbuff && !vim_isspace(p[-1]) 1596 && vim_iswordc(p[-1]) == i) 1597 --p; 1598 } 1599 else 1600 --p; 1601 ccline.cmdpos = (int)(p - ccline.cmdbuff); 1602 ccline.cmdlen -= j - ccline.cmdpos; 1603 i = ccline.cmdpos; 1604 while (i < ccline.cmdlen) 1605 ccline.cmdbuff[i++] = ccline.cmdbuff[j++]; 1606 1607 // Truncate at the end, required for multi-byte chars. 1608 ccline.cmdbuff[ccline.cmdlen] = NUL; 1609 #ifdef FEAT_SEARCH_EXTRA 1610 if (ccline.cmdlen == 0) 1611 { 1612 is_state.search_start = is_state.save_cursor; 1613 // save view settings, so that the screen 1614 // won't be restored at the wrong position 1615 is_state.old_viewstate = is_state.init_viewstate; 1616 } 1617 #endif 1618 redrawcmd(); 1619 } 1620 else if (ccline.cmdlen == 0 && c != Ctrl_W 1621 && ccline.cmdprompt == NULL && indent == 0) 1622 { 1623 // In ex and debug mode it doesn't make sense to return. 1624 if (exmode_active 1625 #ifdef FEAT_EVAL 1626 || ccline.cmdfirstc == '>' 1627 #endif 1628 ) 1629 goto cmdline_not_changed; 1630 1631 VIM_CLEAR(ccline.cmdbuff); // no commandline to return 1632 if (!cmd_silent) 1633 { 1634 #ifdef FEAT_RIGHTLEFT 1635 if (cmdmsg_rl) 1636 msg_col = Columns; 1637 else 1638 #endif 1639 msg_col = 0; 1640 msg_putchar(' '); // delete ':' 1641 } 1642 #ifdef FEAT_SEARCH_EXTRA 1643 if (ccline.cmdlen == 0) 1644 is_state.search_start = is_state.save_cursor; 1645 #endif 1646 redraw_cmdline = TRUE; 1647 goto returncmd; // back to cmd mode 1648 } 1649 goto cmdline_changed; 1650 1651 case K_INS: 1652 case K_KINS: 1653 ccline.overstrike = !ccline.overstrike; 1654 #ifdef CURSOR_SHAPE 1655 ui_cursor_shape(); // may show different cursor shape 1656 #endif 1657 goto cmdline_not_changed; 1658 1659 case Ctrl_HAT: 1660 if (map_to_exists_mode((char_u *)"", LANGMAP, FALSE)) 1661 { 1662 // ":lmap" mappings exists, toggle use of mappings. 1663 State ^= LANGMAP; 1664 #ifdef HAVE_INPUT_METHOD 1665 im_set_active(FALSE); // Disable input method 1666 #endif 1667 if (b_im_ptr != NULL) 1668 { 1669 if (State & LANGMAP) 1670 *b_im_ptr = B_IMODE_LMAP; 1671 else 1672 *b_im_ptr = B_IMODE_NONE; 1673 } 1674 } 1675 #ifdef HAVE_INPUT_METHOD 1676 else 1677 { 1678 // There are no ":lmap" mappings, toggle IM. When 1679 // 'imdisable' is set don't try getting the status, it's 1680 // always off. 1681 if ((p_imdisable && b_im_ptr != NULL) 1682 ? *b_im_ptr == B_IMODE_IM : im_get_status()) 1683 { 1684 im_set_active(FALSE); // Disable input method 1685 if (b_im_ptr != NULL) 1686 *b_im_ptr = B_IMODE_NONE; 1687 } 1688 else 1689 { 1690 im_set_active(TRUE); // Enable input method 1691 if (b_im_ptr != NULL) 1692 *b_im_ptr = B_IMODE_IM; 1693 } 1694 } 1695 #endif 1696 if (b_im_ptr != NULL) 1697 { 1698 if (b_im_ptr == &curbuf->b_p_iminsert) 1699 set_iminsert_global(); 1700 else 1701 set_imsearch_global(); 1702 } 1703 #ifdef CURSOR_SHAPE 1704 ui_cursor_shape(); // may show different cursor shape 1705 #endif 1706 #if defined(FEAT_KEYMAP) 1707 // Show/unshow value of 'keymap' in status lines later. 1708 status_redraw_curbuf(); 1709 #endif 1710 goto cmdline_not_changed; 1711 1712 // case '@': only in very old vi 1713 case Ctrl_U: 1714 // delete all characters left of the cursor 1715 j = ccline.cmdpos; 1716 ccline.cmdlen -= j; 1717 i = ccline.cmdpos = 0; 1718 while (i < ccline.cmdlen) 1719 ccline.cmdbuff[i++] = ccline.cmdbuff[j++]; 1720 // Truncate at the end, required for multi-byte chars. 1721 ccline.cmdbuff[ccline.cmdlen] = NUL; 1722 #ifdef FEAT_SEARCH_EXTRA 1723 if (ccline.cmdlen == 0) 1724 is_state.search_start = is_state.save_cursor; 1725 #endif 1726 redrawcmd(); 1727 goto cmdline_changed; 1728 1729 #ifdef FEAT_CLIPBOARD 1730 case Ctrl_Y: 1731 // Copy the modeless selection, if there is one. 1732 if (clip_star.state != SELECT_CLEARED) 1733 { 1734 if (clip_star.state == SELECT_DONE) 1735 clip_copy_modeless_selection(TRUE); 1736 goto cmdline_not_changed; 1737 } 1738 break; 1739 #endif 1740 1741 case ESC: // get here if p_wc != ESC or when ESC typed twice 1742 case Ctrl_C: 1743 // In exmode it doesn't make sense to return. Except when 1744 // ":normal" runs out of characters. 1745 if (exmode_active 1746 && (ex_normal_busy == 0 || typebuf.tb_len > 0)) 1747 goto cmdline_not_changed; 1748 1749 gotesc = TRUE; // will free ccline.cmdbuff after 1750 // putting it in history 1751 goto returncmd; // back to cmd mode 1752 1753 case Ctrl_R: // insert register 1754 #ifdef USE_ON_FLY_SCROLL 1755 dont_scroll = TRUE; // disallow scrolling here 1756 #endif 1757 putcmdline('"', TRUE); 1758 ++no_mapping; 1759 ++allow_keys; 1760 i = c = plain_vgetc(); // CTRL-R <char> 1761 if (i == Ctrl_O) 1762 i = Ctrl_R; // CTRL-R CTRL-O == CTRL-R CTRL-R 1763 if (i == Ctrl_R) 1764 c = plain_vgetc(); // CTRL-R CTRL-R <char> 1765 extra_char = NUL; 1766 --no_mapping; 1767 --allow_keys; 1768 #ifdef FEAT_EVAL 1769 /* 1770 * Insert the result of an expression. 1771 * Need to save the current command line, to be able to enter 1772 * a new one... 1773 */ 1774 new_cmdpos = -1; 1775 if (c == '=') 1776 { 1777 if (ccline.cmdfirstc == '=' // can't do this recursively 1778 || cmdline_star > 0) // or when typing a password 1779 { 1780 beep_flush(); 1781 c = ESC; 1782 } 1783 else 1784 c = get_expr_register(); 1785 } 1786 #endif 1787 if (c != ESC) // use ESC to cancel inserting register 1788 { 1789 cmdline_paste(c, i == Ctrl_R, FALSE); 1790 1791 #ifdef FEAT_EVAL 1792 // When there was a serious error abort getting the 1793 // command line. 1794 if (aborting()) 1795 { 1796 gotesc = TRUE; // will free ccline.cmdbuff after 1797 // putting it in history 1798 goto returncmd; // back to cmd mode 1799 } 1800 #endif 1801 KeyTyped = FALSE; // Don't do p_wc completion. 1802 #ifdef FEAT_EVAL 1803 if (new_cmdpos >= 0) 1804 { 1805 // set_cmdline_pos() was used 1806 if (new_cmdpos > ccline.cmdlen) 1807 ccline.cmdpos = ccline.cmdlen; 1808 else 1809 ccline.cmdpos = new_cmdpos; 1810 } 1811 #endif 1812 } 1813 redrawcmd(); 1814 goto cmdline_changed; 1815 1816 case Ctrl_D: 1817 if (showmatches(&xpc, FALSE) == EXPAND_NOTHING) 1818 break; // Use ^D as normal char instead 1819 1820 redrawcmd(); 1821 continue; // don't do incremental search now 1822 1823 case K_RIGHT: 1824 case K_S_RIGHT: 1825 case K_C_RIGHT: 1826 do 1827 { 1828 if (ccline.cmdpos >= ccline.cmdlen) 1829 break; 1830 i = cmdline_charsize(ccline.cmdpos); 1831 if (KeyTyped && ccline.cmdspos + i >= Columns * Rows) 1832 break; 1833 ccline.cmdspos += i; 1834 if (has_mbyte) 1835 ccline.cmdpos += (*mb_ptr2len)(ccline.cmdbuff 1836 + ccline.cmdpos); 1837 else 1838 ++ccline.cmdpos; 1839 } 1840 while ((c == K_S_RIGHT || c == K_C_RIGHT 1841 || (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL))) 1842 && ccline.cmdbuff[ccline.cmdpos] != ' '); 1843 if (has_mbyte) 1844 set_cmdspos_cursor(); 1845 goto cmdline_not_changed; 1846 1847 case K_LEFT: 1848 case K_S_LEFT: 1849 case K_C_LEFT: 1850 if (ccline.cmdpos == 0) 1851 goto cmdline_not_changed; 1852 do 1853 { 1854 --ccline.cmdpos; 1855 if (has_mbyte) // move to first byte of char 1856 ccline.cmdpos -= (*mb_head_off)(ccline.cmdbuff, 1857 ccline.cmdbuff + ccline.cmdpos); 1858 ccline.cmdspos -= cmdline_charsize(ccline.cmdpos); 1859 } 1860 while (ccline.cmdpos > 0 1861 && (c == K_S_LEFT || c == K_C_LEFT 1862 || (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL))) 1863 && ccline.cmdbuff[ccline.cmdpos - 1] != ' '); 1864 if (has_mbyte) 1865 set_cmdspos_cursor(); 1866 goto cmdline_not_changed; 1867 1868 case K_IGNORE: 1869 // Ignore mouse event or open_cmdwin() result. 1870 goto cmdline_not_changed; 1871 1872 #ifdef FEAT_GUI_MSWIN 1873 // On MS-Windows ignore <M-F4>, we get it when closing the window 1874 // was cancelled. 1875 case K_F4: 1876 if (mod_mask == MOD_MASK_ALT) 1877 { 1878 redrawcmd(); // somehow the cmdline is cleared 1879 goto cmdline_not_changed; 1880 } 1881 break; 1882 #endif 1883 1884 case K_MIDDLEDRAG: 1885 case K_MIDDLERELEASE: 1886 goto cmdline_not_changed; // Ignore mouse 1887 1888 case K_MIDDLEMOUSE: 1889 # ifdef FEAT_GUI 1890 // When GUI is active, also paste when 'mouse' is empty 1891 if (!gui.in_use) 1892 # endif 1893 if (!mouse_has(MOUSE_COMMAND)) 1894 goto cmdline_not_changed; // Ignore mouse 1895 # ifdef FEAT_CLIPBOARD 1896 if (clip_star.available) 1897 cmdline_paste('*', TRUE, TRUE); 1898 else 1899 # endif 1900 cmdline_paste(0, TRUE, TRUE); 1901 redrawcmd(); 1902 goto cmdline_changed; 1903 1904 # ifdef FEAT_DND 1905 case K_DROP: 1906 cmdline_paste('~', TRUE, FALSE); 1907 redrawcmd(); 1908 goto cmdline_changed; 1909 # endif 1910 1911 case K_LEFTDRAG: 1912 case K_LEFTRELEASE: 1913 case K_RIGHTDRAG: 1914 case K_RIGHTRELEASE: 1915 // Ignore drag and release events when the button-down wasn't 1916 // seen before. 1917 if (ignore_drag_release) 1918 goto cmdline_not_changed; 1919 // FALLTHROUGH 1920 case K_LEFTMOUSE: 1921 case K_RIGHTMOUSE: 1922 if (c == K_LEFTRELEASE || c == K_RIGHTRELEASE) 1923 ignore_drag_release = TRUE; 1924 else 1925 ignore_drag_release = FALSE; 1926 # ifdef FEAT_GUI 1927 // When GUI is active, also move when 'mouse' is empty 1928 if (!gui.in_use) 1929 # endif 1930 if (!mouse_has(MOUSE_COMMAND)) 1931 goto cmdline_not_changed; // Ignore mouse 1932 # ifdef FEAT_CLIPBOARD 1933 if (mouse_row < cmdline_row && clip_star.available) 1934 { 1935 int button, is_click, is_drag; 1936 1937 /* 1938 * Handle modeless selection. 1939 */ 1940 button = get_mouse_button(KEY2TERMCAP1(c), 1941 &is_click, &is_drag); 1942 if (mouse_model_popup() && button == MOUSE_LEFT 1943 && (mod_mask & MOD_MASK_SHIFT)) 1944 { 1945 // Translate shift-left to right button. 1946 button = MOUSE_RIGHT; 1947 mod_mask &= ~MOD_MASK_SHIFT; 1948 } 1949 clip_modeless(button, is_click, is_drag); 1950 goto cmdline_not_changed; 1951 } 1952 # endif 1953 1954 set_cmdspos(); 1955 for (ccline.cmdpos = 0; ccline.cmdpos < ccline.cmdlen; 1956 ++ccline.cmdpos) 1957 { 1958 i = cmdline_charsize(ccline.cmdpos); 1959 if (mouse_row <= cmdline_row + ccline.cmdspos / Columns 1960 && mouse_col < ccline.cmdspos % Columns + i) 1961 break; 1962 if (has_mbyte) 1963 { 1964 // Count ">" for double-wide char that doesn't fit. 1965 correct_cmdspos(ccline.cmdpos, i); 1966 ccline.cmdpos += (*mb_ptr2len)(ccline.cmdbuff 1967 + ccline.cmdpos) - 1; 1968 } 1969 ccline.cmdspos += i; 1970 } 1971 goto cmdline_not_changed; 1972 1973 // Mouse scroll wheel: ignored here 1974 case K_MOUSEDOWN: 1975 case K_MOUSEUP: 1976 case K_MOUSELEFT: 1977 case K_MOUSERIGHT: 1978 // Alternate buttons ignored here 1979 case K_X1MOUSE: 1980 case K_X1DRAG: 1981 case K_X1RELEASE: 1982 case K_X2MOUSE: 1983 case K_X2DRAG: 1984 case K_X2RELEASE: 1985 case K_MOUSEMOVE: 1986 goto cmdline_not_changed; 1987 1988 #ifdef FEAT_GUI 1989 case K_LEFTMOUSE_NM: // mousefocus click, ignored 1990 case K_LEFTRELEASE_NM: 1991 goto cmdline_not_changed; 1992 1993 case K_VER_SCROLLBAR: 1994 if (msg_scrolled == 0) 1995 { 1996 gui_do_scroll(); 1997 redrawcmd(); 1998 } 1999 goto cmdline_not_changed; 2000 2001 case K_HOR_SCROLLBAR: 2002 if (msg_scrolled == 0) 2003 { 2004 gui_do_horiz_scroll(scrollbar_value, FALSE); 2005 redrawcmd(); 2006 } 2007 goto cmdline_not_changed; 2008 #endif 2009 #ifdef FEAT_GUI_TABLINE 2010 case K_TABLINE: 2011 case K_TABMENU: 2012 // Don't want to change any tabs here. Make sure the same tab 2013 // is still selected. 2014 if (gui_use_tabline()) 2015 gui_mch_set_curtab(tabpage_index(curtab)); 2016 goto cmdline_not_changed; 2017 #endif 2018 2019 case K_SELECT: // end of Select mode mapping - ignore 2020 goto cmdline_not_changed; 2021 2022 case Ctrl_B: // begin of command line 2023 case K_HOME: 2024 case K_KHOME: 2025 case K_S_HOME: 2026 case K_C_HOME: 2027 ccline.cmdpos = 0; 2028 set_cmdspos(); 2029 goto cmdline_not_changed; 2030 2031 case Ctrl_E: // end of command line 2032 case K_END: 2033 case K_KEND: 2034 case K_S_END: 2035 case K_C_END: 2036 ccline.cmdpos = ccline.cmdlen; 2037 set_cmdspos_cursor(); 2038 goto cmdline_not_changed; 2039 2040 case Ctrl_A: // all matches 2041 if (nextwild(&xpc, WILD_ALL, 0, firstc != '@') == FAIL) 2042 break; 2043 goto cmdline_changed; 2044 2045 case Ctrl_L: 2046 #ifdef FEAT_SEARCH_EXTRA 2047 if (may_add_char_to_search(firstc, &c, &is_state) == OK) 2048 goto cmdline_not_changed; 2049 #endif 2050 2051 // completion: longest common part 2052 if (nextwild(&xpc, WILD_LONGEST, 0, firstc != '@') == FAIL) 2053 break; 2054 goto cmdline_changed; 2055 2056 case Ctrl_N: // next match 2057 case Ctrl_P: // previous match 2058 if (xpc.xp_numfiles > 0) 2059 { 2060 if (nextwild(&xpc, (c == Ctrl_P) ? WILD_PREV : WILD_NEXT, 2061 0, firstc != '@') == FAIL) 2062 break; 2063 goto cmdline_not_changed; 2064 } 2065 // FALLTHROUGH 2066 case K_UP: 2067 case K_DOWN: 2068 case K_S_UP: 2069 case K_S_DOWN: 2070 case K_PAGEUP: 2071 case K_KPAGEUP: 2072 case K_PAGEDOWN: 2073 case K_KPAGEDOWN: 2074 if (get_hislen() == 0 || firstc == NUL) // no history 2075 goto cmdline_not_changed; 2076 2077 i = hiscnt; 2078 2079 // save current command string so it can be restored later 2080 if (lookfor == NULL) 2081 { 2082 if ((lookfor = vim_strsave(ccline.cmdbuff)) == NULL) 2083 goto cmdline_not_changed; 2084 lookfor[ccline.cmdpos] = NUL; 2085 } 2086 2087 j = (int)STRLEN(lookfor); 2088 for (;;) 2089 { 2090 // one step backwards 2091 if (c == K_UP|| c == K_S_UP || c == Ctrl_P 2092 || c == K_PAGEUP || c == K_KPAGEUP) 2093 { 2094 if (hiscnt == get_hislen()) // first time 2095 hiscnt = *get_hisidx(histype); 2096 else if (hiscnt == 0 && *get_hisidx(histype) 2097 != get_hislen() - 1) 2098 hiscnt = get_hislen() - 1; 2099 else if (hiscnt != *get_hisidx(histype) + 1) 2100 --hiscnt; 2101 else // at top of list 2102 { 2103 hiscnt = i; 2104 break; 2105 } 2106 } 2107 else // one step forwards 2108 { 2109 // on last entry, clear the line 2110 if (hiscnt == *get_hisidx(histype)) 2111 { 2112 hiscnt = get_hislen(); 2113 break; 2114 } 2115 2116 // not on a history line, nothing to do 2117 if (hiscnt == get_hislen()) 2118 break; 2119 if (hiscnt == get_hislen() - 1) // wrap around 2120 hiscnt = 0; 2121 else 2122 ++hiscnt; 2123 } 2124 if (hiscnt < 0 || get_histentry(histype)[hiscnt].hisstr 2125 == NULL) 2126 { 2127 hiscnt = i; 2128 break; 2129 } 2130 if ((c != K_UP && c != K_DOWN) 2131 || hiscnt == i 2132 || STRNCMP(get_histentry(histype)[hiscnt].hisstr, 2133 lookfor, (size_t)j) == 0) 2134 break; 2135 } 2136 2137 if (hiscnt != i) // jumped to other entry 2138 { 2139 char_u *p; 2140 int len; 2141 int old_firstc; 2142 2143 VIM_CLEAR(ccline.cmdbuff); 2144 xpc.xp_context = EXPAND_NOTHING; 2145 if (hiscnt == get_hislen()) 2146 p = lookfor; // back to the old one 2147 else 2148 p = get_histentry(histype)[hiscnt].hisstr; 2149 2150 if (histype == HIST_SEARCH 2151 && p != lookfor 2152 && (old_firstc = p[STRLEN(p) + 1]) != firstc) 2153 { 2154 // Correct for the separator character used when 2155 // adding the history entry vs the one used now. 2156 // First loop: count length. 2157 // Second loop: copy the characters. 2158 for (i = 0; i <= 1; ++i) 2159 { 2160 len = 0; 2161 for (j = 0; p[j] != NUL; ++j) 2162 { 2163 // Replace old sep with new sep, unless it is 2164 // escaped. 2165 if (p[j] == old_firstc 2166 && (j == 0 || p[j - 1] != '\\')) 2167 { 2168 if (i > 0) 2169 ccline.cmdbuff[len] = firstc; 2170 } 2171 else 2172 { 2173 // Escape new sep, unless it is already 2174 // escaped. 2175 if (p[j] == firstc 2176 && (j == 0 || p[j - 1] != '\\')) 2177 { 2178 if (i > 0) 2179 ccline.cmdbuff[len] = '\\'; 2180 ++len; 2181 } 2182 if (i > 0) 2183 ccline.cmdbuff[len] = p[j]; 2184 } 2185 ++len; 2186 } 2187 if (i == 0) 2188 { 2189 alloc_cmdbuff(len); 2190 if (ccline.cmdbuff == NULL) 2191 goto returncmd; 2192 } 2193 } 2194 ccline.cmdbuff[len] = NUL; 2195 } 2196 else 2197 { 2198 alloc_cmdbuff((int)STRLEN(p)); 2199 if (ccline.cmdbuff == NULL) 2200 goto returncmd; 2201 STRCPY(ccline.cmdbuff, p); 2202 } 2203 2204 ccline.cmdpos = ccline.cmdlen = (int)STRLEN(ccline.cmdbuff); 2205 redrawcmd(); 2206 goto cmdline_changed; 2207 } 2208 beep_flush(); 2209 goto cmdline_not_changed; 2210 2211 #ifdef FEAT_SEARCH_EXTRA 2212 case Ctrl_G: // next match 2213 case Ctrl_T: // previous match 2214 if (may_adjust_incsearch_highlighting( 2215 firstc, count, &is_state, c) == FAIL) 2216 goto cmdline_not_changed; 2217 break; 2218 #endif 2219 2220 case Ctrl_V: 2221 case Ctrl_Q: 2222 { 2223 int prev_mod_mask = mod_mask; 2224 2225 ignore_drag_release = TRUE; 2226 putcmdline('^', TRUE); 2227 c = get_literal(); // get next (two) character(s) 2228 do_abbr = FALSE; // don't do abbreviation now 2229 extra_char = NUL; 2230 // may need to remove ^ when composing char was typed 2231 if (enc_utf8 && utf_iscomposing(c) && !cmd_silent) 2232 { 2233 draw_cmdline(ccline.cmdpos, 2234 ccline.cmdlen - ccline.cmdpos); 2235 msg_putchar(' '); 2236 cursorcmd(); 2237 } 2238 2239 if ((c == ESC || c == CSI) 2240 && !(prev_mod_mask & MOD_MASK_SHIFT)) 2241 // Using CTRL-V: Change any modifyOtherKeys ESC 2242 // sequence to a normal key. Don't do this for 2243 // CTRL-SHIFT-V. 2244 c = decodeModifyOtherKeys(c); 2245 } 2246 2247 break; 2248 2249 #ifdef FEAT_DIGRAPHS 2250 case Ctrl_K: 2251 ignore_drag_release = TRUE; 2252 putcmdline('?', TRUE); 2253 # ifdef USE_ON_FLY_SCROLL 2254 dont_scroll = TRUE; // disallow scrolling here 2255 # endif 2256 c = get_digraph(TRUE); 2257 extra_char = NUL; 2258 if (c != NUL) 2259 break; 2260 2261 redrawcmd(); 2262 goto cmdline_not_changed; 2263 #endif // FEAT_DIGRAPHS 2264 2265 #ifdef FEAT_RIGHTLEFT 2266 case Ctrl__: // CTRL-_: switch language mode 2267 if (!p_ari) 2268 break; 2269 cmd_hkmap = !cmd_hkmap; 2270 goto cmdline_not_changed; 2271 #endif 2272 2273 case K_PS: 2274 bracketed_paste(PASTE_CMDLINE, FALSE, NULL); 2275 goto cmdline_changed; 2276 2277 default: 2278 #ifdef UNIX 2279 if (c == intr_char) 2280 { 2281 gotesc = TRUE; // will free ccline.cmdbuff after 2282 // putting it in history 2283 goto returncmd; // back to Normal mode 2284 } 2285 #endif 2286 /* 2287 * Normal character with no special meaning. Just set mod_mask 2288 * to 0x0 so that typing Shift-Space in the GUI doesn't enter 2289 * the string <S-Space>. This should only happen after ^V. 2290 */ 2291 if (!IS_SPECIAL(c)) 2292 mod_mask = 0x0; 2293 break; 2294 } 2295 /* 2296 * End of switch on command line character. 2297 * We come here if we have a normal character. 2298 */ 2299 2300 if (do_abbr && (IS_SPECIAL(c) || !vim_iswordc(c)) 2301 && (ccheck_abbr( 2302 // Add ABBR_OFF for characters above 0x100, this is 2303 // what check_abbr() expects. 2304 (has_mbyte && c >= 0x100) ? (c + ABBR_OFF) : c) 2305 || c == Ctrl_RSB)) 2306 goto cmdline_changed; 2307 2308 /* 2309 * put the character in the command line 2310 */ 2311 if (IS_SPECIAL(c) || mod_mask != 0) 2312 put_on_cmdline(get_special_key_name(c, mod_mask), -1, TRUE); 2313 else 2314 { 2315 if (has_mbyte) 2316 { 2317 j = (*mb_char2bytes)(c, IObuff); 2318 IObuff[j] = NUL; // exclude composing chars 2319 put_on_cmdline(IObuff, j, TRUE); 2320 } 2321 else 2322 { 2323 IObuff[0] = c; 2324 put_on_cmdline(IObuff, 1, TRUE); 2325 } 2326 } 2327 goto cmdline_changed; 2328 2329 /* 2330 * This part implements incremental searches for "/" and "?" 2331 * Jump to cmdline_not_changed when a character has been read but the command 2332 * line did not change. Then we only search and redraw if something changed in 2333 * the past. 2334 * Jump to cmdline_changed when the command line did change. 2335 * (Sorry for the goto's, I know it is ugly). 2336 */ 2337 cmdline_not_changed: 2338 #ifdef FEAT_SEARCH_EXTRA 2339 if (!is_state.incsearch_postponed) 2340 continue; 2341 #endif 2342 2343 cmdline_changed: 2344 // Trigger CmdlineChanged autocommands. 2345 trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINECHANGED); 2346 2347 #ifdef FEAT_SEARCH_EXTRA 2348 may_do_incsearch_highlighting(firstc, count, &is_state); 2349 #endif 2350 2351 #ifdef FEAT_RIGHTLEFT 2352 if (cmdmsg_rl 2353 # ifdef FEAT_ARABIC 2354 || (p_arshape && !p_tbidi 2355 && cmdline_has_arabic(0, ccline.cmdlen)) 2356 # endif 2357 ) 2358 // Always redraw the whole command line to fix shaping and 2359 // right-left typing. Not efficient, but it works. 2360 // Do it only when there are no characters left to read 2361 // to avoid useless intermediate redraws. 2362 if (vpeekc() == NUL) 2363 redrawcmd(); 2364 #endif 2365 } 2366 2367 returncmd: 2368 2369 #ifdef FEAT_RIGHTLEFT 2370 cmdmsg_rl = FALSE; 2371 #endif 2372 2373 ExpandCleanup(&xpc); 2374 ccline.xpc = NULL; 2375 2376 #ifdef FEAT_SEARCH_EXTRA 2377 finish_incsearch_highlighting(gotesc, &is_state, FALSE); 2378 #endif 2379 2380 if (ccline.cmdbuff != NULL) 2381 { 2382 /* 2383 * Put line in history buffer (":" and "=" only when it was typed). 2384 */ 2385 if (ccline.cmdlen && firstc != NUL 2386 && (some_key_typed || histype == HIST_SEARCH)) 2387 { 2388 add_to_history(histype, ccline.cmdbuff, TRUE, 2389 histype == HIST_SEARCH ? firstc : NUL); 2390 if (firstc == ':') 2391 { 2392 vim_free(new_last_cmdline); 2393 new_last_cmdline = vim_strsave(ccline.cmdbuff); 2394 } 2395 } 2396 2397 if (gotesc) 2398 abandon_cmdline(); 2399 } 2400 2401 /* 2402 * If the screen was shifted up, redraw the whole screen (later). 2403 * If the line is too long, clear it, so ruler and shown command do 2404 * not get printed in the middle of it. 2405 */ 2406 msg_check(); 2407 msg_scroll = save_msg_scroll; 2408 redir_off = FALSE; 2409 2410 // When the command line was typed, no need for a wait-return prompt. 2411 if (some_key_typed) 2412 need_wait_return = FALSE; 2413 2414 // Trigger CmdlineLeave autocommands. 2415 trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINELEAVE); 2416 2417 State = save_State; 2418 #ifdef HAVE_INPUT_METHOD 2419 if (b_im_ptr != NULL && *b_im_ptr != B_IMODE_LMAP) 2420 im_save_status(b_im_ptr); 2421 im_set_active(FALSE); 2422 #endif 2423 setmouse(); 2424 #ifdef CURSOR_SHAPE 2425 ui_cursor_shape(); // may show different cursor shape 2426 #endif 2427 sb_text_end_cmdline(); 2428 2429 theend: 2430 { 2431 char_u *p = ccline.cmdbuff; 2432 2433 if (did_save_ccline) 2434 restore_cmdline(&save_ccline); 2435 else 2436 ccline.cmdbuff = NULL; 2437 return p; 2438 } 2439 } 2440 2441 #if (defined(FEAT_CRYPT) || defined(FEAT_EVAL)) || defined(PROTO) 2442 /* 2443 * Get a command line with a prompt. 2444 * This is prepared to be called recursively from getcmdline() (e.g. by 2445 * f_input() when evaluating an expression from CTRL-R =). 2446 * Returns the command line in allocated memory, or NULL. 2447 */ 2448 char_u * 2449 getcmdline_prompt( 2450 int firstc, 2451 char_u *prompt, // command line prompt 2452 int attr, // attributes for prompt 2453 int xp_context, // type of expansion 2454 char_u *xp_arg) // user-defined expansion argument 2455 { 2456 char_u *s; 2457 cmdline_info_T save_ccline; 2458 int did_save_ccline = FALSE; 2459 int msg_col_save = msg_col; 2460 int msg_silent_save = msg_silent; 2461 2462 if (ccline.cmdbuff != NULL) 2463 { 2464 // Save the values of the current cmdline and restore them below. 2465 save_cmdline(&save_ccline); 2466 did_save_ccline = TRUE; 2467 } 2468 2469 CLEAR_FIELD(ccline); 2470 ccline.cmdprompt = prompt; 2471 ccline.cmdattr = attr; 2472 # ifdef FEAT_EVAL 2473 ccline.xp_context = xp_context; 2474 ccline.xp_arg = xp_arg; 2475 ccline.input_fn = (firstc == '@'); 2476 # endif 2477 msg_silent = 0; 2478 s = getcmdline_int(firstc, 1L, 0, FALSE); 2479 2480 if (did_save_ccline) 2481 restore_cmdline(&save_ccline); 2482 2483 msg_silent = msg_silent_save; 2484 // Restore msg_col, the prompt from input() may have changed it. 2485 // But only if called recursively and the commandline is therefore being 2486 // restored to an old one; if not, the input() prompt stays on the screen, 2487 // so we need its modified msg_col left intact. 2488 if (ccline.cmdbuff != NULL) 2489 msg_col = msg_col_save; 2490 2491 return s; 2492 } 2493 #endif 2494 2495 /* 2496 * Read the 'wildmode' option, fill wim_flags[]. 2497 */ 2498 int 2499 check_opt_wim(void) 2500 { 2501 char_u new_wim_flags[4]; 2502 char_u *p; 2503 int i; 2504 int idx = 0; 2505 2506 for (i = 0; i < 4; ++i) 2507 new_wim_flags[i] = 0; 2508 2509 for (p = p_wim; *p; ++p) 2510 { 2511 for (i = 0; ASCII_ISALPHA(p[i]); ++i) 2512 ; 2513 if (p[i] != NUL && p[i] != ',' && p[i] != ':') 2514 return FAIL; 2515 if (i == 7 && STRNCMP(p, "longest", 7) == 0) 2516 new_wim_flags[idx] |= WIM_LONGEST; 2517 else if (i == 4 && STRNCMP(p, "full", 4) == 0) 2518 new_wim_flags[idx] |= WIM_FULL; 2519 else if (i == 4 && STRNCMP(p, "list", 4) == 0) 2520 new_wim_flags[idx] |= WIM_LIST; 2521 else if (i == 8 && STRNCMP(p, "lastused", 8) == 0) 2522 new_wim_flags[idx] |= WIM_BUFLASTUSED; 2523 else 2524 return FAIL; 2525 p += i; 2526 if (*p == NUL) 2527 break; 2528 if (*p == ',') 2529 { 2530 if (idx == 3) 2531 return FAIL; 2532 ++idx; 2533 } 2534 } 2535 2536 // fill remaining entries with last flag 2537 while (idx < 3) 2538 { 2539 new_wim_flags[idx + 1] = new_wim_flags[idx]; 2540 ++idx; 2541 } 2542 2543 // only when there are no errors, wim_flags[] is changed 2544 for (i = 0; i < 4; ++i) 2545 wim_flags[i] = new_wim_flags[i]; 2546 return OK; 2547 } 2548 2549 /* 2550 * Return TRUE when the text must not be changed and we can't switch to 2551 * another window or buffer. TRUE when editing the command line, evaluating 2552 * 'balloonexpr', etc. 2553 */ 2554 int 2555 text_and_win_locked(void) 2556 { 2557 #ifdef FEAT_CMDWIN 2558 if (cmdwin_type != 0) 2559 return TRUE; 2560 #endif 2561 return textwinlock != 0; 2562 } 2563 2564 /* 2565 * Give an error message for a command that isn't allowed while the cmdline 2566 * window is open or editing the cmdline in another way. 2567 */ 2568 void 2569 text_locked_msg(void) 2570 { 2571 emsg(_(get_text_locked_msg())); 2572 } 2573 2574 char * 2575 get_text_locked_msg(void) 2576 { 2577 #ifdef FEAT_CMDWIN 2578 if (cmdwin_type != 0) 2579 return e_cmdwin; 2580 #endif 2581 if (textwinlock != 0) 2582 return e_textwinlock; 2583 return e_textlock; 2584 } 2585 2586 /* 2587 * Return TRUE when the text must not be changed and/or we cannot switch to 2588 * another window. TRUE while evaluating 'completefunc'. 2589 */ 2590 int 2591 text_locked(void) 2592 { 2593 return text_and_win_locked() || textlock != 0; 2594 } 2595 2596 /* 2597 * Check if "curbuf_lock" or "allbuf_lock" is set and return TRUE when it is 2598 * and give an error message. 2599 */ 2600 int 2601 curbuf_locked(void) 2602 { 2603 if (curbuf_lock > 0) 2604 { 2605 emsg(_("E788: Not allowed to edit another buffer now")); 2606 return TRUE; 2607 } 2608 return allbuf_locked(); 2609 } 2610 2611 /* 2612 * Check if "allbuf_lock" is set and return TRUE when it is and give an error 2613 * message. 2614 */ 2615 int 2616 allbuf_locked(void) 2617 { 2618 if (allbuf_lock > 0) 2619 { 2620 emsg(_("E811: Not allowed to change buffer information now")); 2621 return TRUE; 2622 } 2623 return FALSE; 2624 } 2625 2626 static int 2627 cmdline_charsize(int idx) 2628 { 2629 #if defined(FEAT_CRYPT) || defined(FEAT_EVAL) 2630 if (cmdline_star > 0) // showing '*', always 1 position 2631 return 1; 2632 #endif 2633 return ptr2cells(ccline.cmdbuff + idx); 2634 } 2635 2636 /* 2637 * Compute the offset of the cursor on the command line for the prompt and 2638 * indent. 2639 */ 2640 static void 2641 set_cmdspos(void) 2642 { 2643 if (ccline.cmdfirstc != NUL) 2644 ccline.cmdspos = 1 + ccline.cmdindent; 2645 else 2646 ccline.cmdspos = 0 + ccline.cmdindent; 2647 } 2648 2649 /* 2650 * Compute the screen position for the cursor on the command line. 2651 */ 2652 static void 2653 set_cmdspos_cursor(void) 2654 { 2655 int i, m, c; 2656 2657 set_cmdspos(); 2658 if (KeyTyped) 2659 { 2660 m = Columns * Rows; 2661 if (m < 0) // overflow, Columns or Rows at weird value 2662 m = MAXCOL; 2663 } 2664 else 2665 m = MAXCOL; 2666 for (i = 0; i < ccline.cmdlen && i < ccline.cmdpos; ++i) 2667 { 2668 c = cmdline_charsize(i); 2669 // Count ">" for double-wide multi-byte char that doesn't fit. 2670 if (has_mbyte) 2671 correct_cmdspos(i, c); 2672 // If the cmdline doesn't fit, show cursor on last visible char. 2673 // Don't move the cursor itself, so we can still append. 2674 if ((ccline.cmdspos += c) >= m) 2675 { 2676 ccline.cmdspos -= c; 2677 break; 2678 } 2679 if (has_mbyte) 2680 i += (*mb_ptr2len)(ccline.cmdbuff + i) - 1; 2681 } 2682 } 2683 2684 /* 2685 * Check if the character at "idx", which is "cells" wide, is a multi-byte 2686 * character that doesn't fit, so that a ">" must be displayed. 2687 */ 2688 static void 2689 correct_cmdspos(int idx, int cells) 2690 { 2691 if ((*mb_ptr2len)(ccline.cmdbuff + idx) > 1 2692 && (*mb_ptr2cells)(ccline.cmdbuff + idx) > 1 2693 && ccline.cmdspos % Columns + cells > Columns) 2694 ccline.cmdspos++; 2695 } 2696 2697 /* 2698 * Get an Ex command line for the ":" command. 2699 */ 2700 char_u * 2701 getexline( 2702 int c, // normally ':', NUL for ":append" 2703 void *cookie UNUSED, 2704 int indent, // indent for inside conditionals 2705 int do_concat) 2706 { 2707 // When executing a register, remove ':' that's in front of each line. 2708 if (exec_from_reg && vpeekc() == ':') 2709 (void)vgetc(); 2710 return getcmdline(c, 1L, indent, do_concat); 2711 } 2712 2713 /* 2714 * Get an Ex command line for Ex mode. 2715 * In Ex mode we only use the OS supplied line editing features and no 2716 * mappings or abbreviations. 2717 * Returns a string in allocated memory or NULL. 2718 */ 2719 char_u * 2720 getexmodeline( 2721 int promptc, // normally ':', NUL for ":append" and '?' for 2722 // :s prompt 2723 void *cookie UNUSED, 2724 int indent, // indent for inside conditionals 2725 int do_concat UNUSED) 2726 { 2727 garray_T line_ga; 2728 char_u *pend; 2729 int startcol = 0; 2730 int c1 = 0; 2731 int escaped = FALSE; // CTRL-V typed 2732 int vcol = 0; 2733 char_u *p; 2734 int prev_char; 2735 int len; 2736 2737 // Switch cursor on now. This avoids that it happens after the "\n", which 2738 // confuses the system function that computes tabstops. 2739 cursor_on(); 2740 2741 // always start in column 0; write a newline if necessary 2742 compute_cmdrow(); 2743 if ((msg_col || msg_didout) && promptc != '?') 2744 msg_putchar('\n'); 2745 if (promptc == ':') 2746 { 2747 // indent that is only displayed, not in the line itself 2748 if (p_prompt) 2749 msg_putchar(':'); 2750 while (indent-- > 0) 2751 msg_putchar(' '); 2752 startcol = msg_col; 2753 } 2754 2755 ga_init2(&line_ga, 1, 30); 2756 2757 // autoindent for :insert and :append is in the line itself 2758 if (promptc <= 0) 2759 { 2760 vcol = indent; 2761 while (indent >= 8) 2762 { 2763 ga_append(&line_ga, TAB); 2764 msg_puts(" "); 2765 indent -= 8; 2766 } 2767 while (indent-- > 0) 2768 { 2769 ga_append(&line_ga, ' '); 2770 msg_putchar(' '); 2771 } 2772 } 2773 ++no_mapping; 2774 ++allow_keys; 2775 2776 /* 2777 * Get the line, one character at a time. 2778 */ 2779 got_int = FALSE; 2780 while (!got_int) 2781 { 2782 long sw; 2783 char_u *s; 2784 2785 if (ga_grow(&line_ga, 40) == FAIL) 2786 break; 2787 2788 /* 2789 * Get one character at a time. 2790 */ 2791 prev_char = c1; 2792 2793 // Check for a ":normal" command and no more characters left. 2794 if (ex_normal_busy > 0 && typebuf.tb_len == 0) 2795 c1 = '\n'; 2796 else 2797 c1 = vgetc(); 2798 2799 /* 2800 * Handle line editing. 2801 * Previously this was left to the system, putting the terminal in 2802 * cooked mode, but then CTRL-D and CTRL-T can't be used properly. 2803 */ 2804 if (got_int) 2805 { 2806 msg_putchar('\n'); 2807 break; 2808 } 2809 2810 if (c1 == K_PS) 2811 { 2812 bracketed_paste(PASTE_EX, FALSE, &line_ga); 2813 goto redraw; 2814 } 2815 2816 if (!escaped) 2817 { 2818 // CR typed means "enter", which is NL 2819 if (c1 == '\r') 2820 c1 = '\n'; 2821 2822 if (c1 == BS || c1 == K_BS 2823 || c1 == DEL || c1 == K_DEL || c1 == K_KDEL) 2824 { 2825 if (line_ga.ga_len > 0) 2826 { 2827 if (has_mbyte) 2828 { 2829 p = (char_u *)line_ga.ga_data; 2830 p[line_ga.ga_len] = NUL; 2831 len = (*mb_head_off)(p, p + line_ga.ga_len - 1) + 1; 2832 line_ga.ga_len -= len; 2833 } 2834 else 2835 --line_ga.ga_len; 2836 goto redraw; 2837 } 2838 continue; 2839 } 2840 2841 if (c1 == Ctrl_U) 2842 { 2843 msg_col = startcol; 2844 msg_clr_eos(); 2845 line_ga.ga_len = 0; 2846 goto redraw; 2847 } 2848 2849 if (c1 == Ctrl_T) 2850 { 2851 sw = get_sw_value(curbuf); 2852 p = (char_u *)line_ga.ga_data; 2853 p[line_ga.ga_len] = NUL; 2854 indent = get_indent_str(p, 8, FALSE); 2855 indent += sw - indent % sw; 2856 add_indent: 2857 while (get_indent_str(p, 8, FALSE) < indent) 2858 { 2859 (void)ga_grow(&line_ga, 2); // one more for the NUL 2860 p = (char_u *)line_ga.ga_data; 2861 s = skipwhite(p); 2862 mch_memmove(s + 1, s, line_ga.ga_len - (s - p) + 1); 2863 *s = ' '; 2864 ++line_ga.ga_len; 2865 } 2866 redraw: 2867 // redraw the line 2868 msg_col = startcol; 2869 vcol = 0; 2870 p = (char_u *)line_ga.ga_data; 2871 p[line_ga.ga_len] = NUL; 2872 while (p < (char_u *)line_ga.ga_data + line_ga.ga_len) 2873 { 2874 if (*p == TAB) 2875 { 2876 do 2877 msg_putchar(' '); 2878 while (++vcol % 8); 2879 ++p; 2880 } 2881 else 2882 { 2883 len = mb_ptr2len(p); 2884 msg_outtrans_len(p, len); 2885 vcol += ptr2cells(p); 2886 p += len; 2887 } 2888 } 2889 msg_clr_eos(); 2890 windgoto(msg_row, msg_col); 2891 continue; 2892 } 2893 2894 if (c1 == Ctrl_D) 2895 { 2896 // Delete one shiftwidth. 2897 p = (char_u *)line_ga.ga_data; 2898 if (prev_char == '0' || prev_char == '^') 2899 { 2900 if (prev_char == '^') 2901 ex_keep_indent = TRUE; 2902 indent = 0; 2903 p[--line_ga.ga_len] = NUL; 2904 } 2905 else 2906 { 2907 p[line_ga.ga_len] = NUL; 2908 indent = get_indent_str(p, 8, FALSE); 2909 if (indent > 0) 2910 { 2911 --indent; 2912 indent -= indent % get_sw_value(curbuf); 2913 } 2914 } 2915 while (get_indent_str(p, 8, FALSE) > indent) 2916 { 2917 s = skipwhite(p); 2918 mch_memmove(s - 1, s, line_ga.ga_len - (s - p) + 1); 2919 --line_ga.ga_len; 2920 } 2921 goto add_indent; 2922 } 2923 2924 if (c1 == Ctrl_V || c1 == Ctrl_Q) 2925 { 2926 escaped = TRUE; 2927 continue; 2928 } 2929 2930 // Ignore special key codes: mouse movement, K_IGNORE, etc. 2931 if (IS_SPECIAL(c1)) 2932 continue; 2933 } 2934 2935 if (IS_SPECIAL(c1)) 2936 c1 = '?'; 2937 if (has_mbyte) 2938 len = (*mb_char2bytes)(c1, 2939 (char_u *)line_ga.ga_data + line_ga.ga_len); 2940 else 2941 { 2942 len = 1; 2943 ((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1; 2944 } 2945 if (c1 == '\n') 2946 msg_putchar('\n'); 2947 else if (c1 == TAB) 2948 { 2949 // Don't use chartabsize(), 'ts' can be different 2950 do 2951 msg_putchar(' '); 2952 while (++vcol % 8); 2953 } 2954 else 2955 { 2956 msg_outtrans_len( 2957 ((char_u *)line_ga.ga_data) + line_ga.ga_len, len); 2958 vcol += char2cells(c1); 2959 } 2960 line_ga.ga_len += len; 2961 escaped = FALSE; 2962 2963 windgoto(msg_row, msg_col); 2964 pend = (char_u *)(line_ga.ga_data) + line_ga.ga_len; 2965 2966 // We are done when a NL is entered, but not when it comes after an 2967 // odd number of backslashes, that results in a NUL. 2968 if (line_ga.ga_len > 0 && pend[-1] == '\n') 2969 { 2970 int bcount = 0; 2971 2972 while (line_ga.ga_len - 2 >= bcount && pend[-2 - bcount] == '\\') 2973 ++bcount; 2974 2975 if (bcount > 0) 2976 { 2977 // Halve the number of backslashes: "\NL" -> "NUL", "\\NL" -> 2978 // "\NL", etc. 2979 line_ga.ga_len -= (bcount + 1) / 2; 2980 pend -= (bcount + 1) / 2; 2981 pend[-1] = '\n'; 2982 } 2983 2984 if ((bcount & 1) == 0) 2985 { 2986 --line_ga.ga_len; 2987 --pend; 2988 *pend = NUL; 2989 break; 2990 } 2991 } 2992 } 2993 2994 --no_mapping; 2995 --allow_keys; 2996 2997 // make following messages go to the next line 2998 msg_didout = FALSE; 2999 msg_col = 0; 3000 if (msg_row < Rows - 1) 3001 ++msg_row; 3002 emsg_on_display = FALSE; // don't want ui_delay() 3003 3004 if (got_int) 3005 ga_clear(&line_ga); 3006 3007 return (char_u *)line_ga.ga_data; 3008 } 3009 3010 # if defined(MCH_CURSOR_SHAPE) || defined(FEAT_GUI) \ 3011 || defined(FEAT_MOUSESHAPE) || defined(PROTO) 3012 /* 3013 * Return TRUE if ccline.overstrike is on. 3014 */ 3015 int 3016 cmdline_overstrike(void) 3017 { 3018 return ccline.overstrike; 3019 } 3020 3021 /* 3022 * Return TRUE if the cursor is at the end of the cmdline. 3023 */ 3024 int 3025 cmdline_at_end(void) 3026 { 3027 return (ccline.cmdpos >= ccline.cmdlen); 3028 } 3029 #endif 3030 3031 #if (defined(FEAT_XIM) && (defined(FEAT_GUI_GTK))) || defined(PROTO) 3032 /* 3033 * Return the virtual column number at the current cursor position. 3034 * This is used by the IM code to obtain the start of the preedit string. 3035 */ 3036 colnr_T 3037 cmdline_getvcol_cursor(void) 3038 { 3039 if (ccline.cmdbuff == NULL || ccline.cmdpos > ccline.cmdlen) 3040 return MAXCOL; 3041 3042 if (has_mbyte) 3043 { 3044 colnr_T col; 3045 int i = 0; 3046 3047 for (col = 0; i < ccline.cmdpos; ++col) 3048 i += (*mb_ptr2len)(ccline.cmdbuff + i); 3049 3050 return col; 3051 } 3052 else 3053 return ccline.cmdpos; 3054 } 3055 #endif 3056 3057 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) 3058 /* 3059 * If part of the command line is an IM preedit string, redraw it with 3060 * IM feedback attributes. The cursor position is restored after drawing. 3061 */ 3062 static void 3063 redrawcmd_preedit(void) 3064 { 3065 if ((State & CMDLINE) 3066 && xic != NULL 3067 // && im_get_status() doesn't work when using SCIM 3068 && !p_imdisable 3069 && im_is_preediting()) 3070 { 3071 int cmdpos = 0; 3072 int cmdspos; 3073 int old_row; 3074 int old_col; 3075 colnr_T col; 3076 3077 old_row = msg_row; 3078 old_col = msg_col; 3079 cmdspos = ((ccline.cmdfirstc != NUL) ? 1 : 0) + ccline.cmdindent; 3080 3081 if (has_mbyte) 3082 { 3083 for (col = 0; col < preedit_start_col 3084 && cmdpos < ccline.cmdlen; ++col) 3085 { 3086 cmdspos += (*mb_ptr2cells)(ccline.cmdbuff + cmdpos); 3087 cmdpos += (*mb_ptr2len)(ccline.cmdbuff + cmdpos); 3088 } 3089 } 3090 else 3091 { 3092 cmdspos += preedit_start_col; 3093 cmdpos += preedit_start_col; 3094 } 3095 3096 msg_row = cmdline_row + (cmdspos / (int)Columns); 3097 msg_col = cmdspos % (int)Columns; 3098 if (msg_row >= Rows) 3099 msg_row = Rows - 1; 3100 3101 for (col = 0; cmdpos < ccline.cmdlen; ++col) 3102 { 3103 int char_len; 3104 int char_attr; 3105 3106 char_attr = im_get_feedback_attr(col); 3107 if (char_attr < 0) 3108 break; // end of preedit string 3109 3110 if (has_mbyte) 3111 char_len = (*mb_ptr2len)(ccline.cmdbuff + cmdpos); 3112 else 3113 char_len = 1; 3114 3115 msg_outtrans_len_attr(ccline.cmdbuff + cmdpos, char_len, char_attr); 3116 cmdpos += char_len; 3117 } 3118 3119 msg_row = old_row; 3120 msg_col = old_col; 3121 } 3122 } 3123 #endif // FEAT_XIM && FEAT_GUI_GTK 3124 3125 /* 3126 * Allocate a new command line buffer. 3127 * Assigns the new buffer to ccline.cmdbuff and ccline.cmdbufflen. 3128 */ 3129 static void 3130 alloc_cmdbuff(int len) 3131 { 3132 /* 3133 * give some extra space to avoid having to allocate all the time 3134 */ 3135 if (len < 80) 3136 len = 100; 3137 else 3138 len += 20; 3139 3140 ccline.cmdbuff = alloc(len); // caller should check for out-of-memory 3141 ccline.cmdbufflen = len; 3142 } 3143 3144 /* 3145 * Re-allocate the command line to length len + something extra. 3146 * return FAIL for failure, OK otherwise 3147 */ 3148 int 3149 realloc_cmdbuff(int len) 3150 { 3151 char_u *p; 3152 3153 if (len < ccline.cmdbufflen) 3154 return OK; // no need to resize 3155 3156 p = ccline.cmdbuff; 3157 alloc_cmdbuff(len); // will get some more 3158 if (ccline.cmdbuff == NULL) // out of memory 3159 { 3160 ccline.cmdbuff = p; // keep the old one 3161 return FAIL; 3162 } 3163 // There isn't always a NUL after the command, but it may need to be 3164 // there, thus copy up to the NUL and add a NUL. 3165 mch_memmove(ccline.cmdbuff, p, (size_t)ccline.cmdlen); 3166 ccline.cmdbuff[ccline.cmdlen] = NUL; 3167 vim_free(p); 3168 3169 if (ccline.xpc != NULL 3170 && ccline.xpc->xp_pattern != NULL 3171 && ccline.xpc->xp_context != EXPAND_NOTHING 3172 && ccline.xpc->xp_context != EXPAND_UNSUCCESSFUL) 3173 { 3174 int i = (int)(ccline.xpc->xp_pattern - p); 3175 3176 // If xp_pattern points inside the old cmdbuff it needs to be adjusted 3177 // to point into the newly allocated memory. 3178 if (i >= 0 && i <= ccline.cmdlen) 3179 ccline.xpc->xp_pattern = ccline.cmdbuff + i; 3180 } 3181 3182 return OK; 3183 } 3184 3185 #if defined(FEAT_ARABIC) || defined(PROTO) 3186 static char_u *arshape_buf = NULL; 3187 3188 # if defined(EXITFREE) || defined(PROTO) 3189 void 3190 free_arshape_buf(void) 3191 { 3192 vim_free(arshape_buf); 3193 } 3194 # endif 3195 #endif 3196 3197 /* 3198 * Draw part of the cmdline at the current cursor position. But draw stars 3199 * when cmdline_star is TRUE. 3200 */ 3201 static void 3202 draw_cmdline(int start, int len) 3203 { 3204 #if defined(FEAT_CRYPT) || defined(FEAT_EVAL) 3205 int i; 3206 3207 if (cmdline_star > 0) 3208 for (i = 0; i < len; ++i) 3209 { 3210 msg_putchar('*'); 3211 if (has_mbyte) 3212 i += (*mb_ptr2len)(ccline.cmdbuff + start + i) - 1; 3213 } 3214 else 3215 #endif 3216 #ifdef FEAT_ARABIC 3217 if (p_arshape && !p_tbidi && cmdline_has_arabic(start, len)) 3218 { 3219 static int buflen = 0; 3220 char_u *p; 3221 int j; 3222 int newlen = 0; 3223 int mb_l; 3224 int pc, pc1 = 0; 3225 int prev_c = 0; 3226 int prev_c1 = 0; 3227 int u8c; 3228 int u8cc[MAX_MCO]; 3229 int nc = 0; 3230 3231 /* 3232 * Do arabic shaping into a temporary buffer. This is very 3233 * inefficient! 3234 */ 3235 if (len * 2 + 2 > buflen) 3236 { 3237 // Re-allocate the buffer. We keep it around to avoid a lot of 3238 // alloc()/free() calls. 3239 vim_free(arshape_buf); 3240 buflen = len * 2 + 2; 3241 arshape_buf = alloc(buflen); 3242 if (arshape_buf == NULL) 3243 return; // out of memory 3244 } 3245 3246 if (utf_iscomposing(utf_ptr2char(ccline.cmdbuff + start))) 3247 { 3248 // Prepend a space to draw the leading composing char on. 3249 arshape_buf[0] = ' '; 3250 newlen = 1; 3251 } 3252 3253 for (j = start; j < start + len; j += mb_l) 3254 { 3255 p = ccline.cmdbuff + j; 3256 u8c = utfc_ptr2char_len(p, u8cc, start + len - j); 3257 mb_l = utfc_ptr2len_len(p, start + len - j); 3258 if (ARABIC_CHAR(u8c)) 3259 { 3260 // Do Arabic shaping. 3261 if (cmdmsg_rl) 3262 { 3263 // displaying from right to left 3264 pc = prev_c; 3265 pc1 = prev_c1; 3266 prev_c1 = u8cc[0]; 3267 if (j + mb_l >= start + len) 3268 nc = NUL; 3269 else 3270 nc = utf_ptr2char(p + mb_l); 3271 } 3272 else 3273 { 3274 // displaying from left to right 3275 if (j + mb_l >= start + len) 3276 pc = NUL; 3277 else 3278 { 3279 int pcc[MAX_MCO]; 3280 3281 pc = utfc_ptr2char_len(p + mb_l, pcc, 3282 start + len - j - mb_l); 3283 pc1 = pcc[0]; 3284 } 3285 nc = prev_c; 3286 } 3287 prev_c = u8c; 3288 3289 u8c = arabic_shape(u8c, NULL, &u8cc[0], pc, pc1, nc); 3290 3291 newlen += (*mb_char2bytes)(u8c, arshape_buf + newlen); 3292 if (u8cc[0] != 0) 3293 { 3294 newlen += (*mb_char2bytes)(u8cc[0], arshape_buf + newlen); 3295 if (u8cc[1] != 0) 3296 newlen += (*mb_char2bytes)(u8cc[1], 3297 arshape_buf + newlen); 3298 } 3299 } 3300 else 3301 { 3302 prev_c = u8c; 3303 mch_memmove(arshape_buf + newlen, p, mb_l); 3304 newlen += mb_l; 3305 } 3306 } 3307 3308 msg_outtrans_len(arshape_buf, newlen); 3309 } 3310 else 3311 #endif 3312 msg_outtrans_len(ccline.cmdbuff + start, len); 3313 } 3314 3315 /* 3316 * Put a character on the command line. Shifts the following text to the 3317 * right when "shift" is TRUE. Used for CTRL-V, CTRL-K, etc. 3318 * "c" must be printable (fit in one display cell)! 3319 */ 3320 void 3321 putcmdline(int c, int shift) 3322 { 3323 if (cmd_silent) 3324 return; 3325 msg_no_more = TRUE; 3326 msg_putchar(c); 3327 if (shift) 3328 draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos); 3329 msg_no_more = FALSE; 3330 cursorcmd(); 3331 extra_char = c; 3332 extra_char_shift = shift; 3333 } 3334 3335 /* 3336 * Undo a putcmdline(c, FALSE). 3337 */ 3338 void 3339 unputcmdline(void) 3340 { 3341 if (cmd_silent) 3342 return; 3343 msg_no_more = TRUE; 3344 if (ccline.cmdlen == ccline.cmdpos) 3345 msg_putchar(' '); 3346 else if (has_mbyte) 3347 draw_cmdline(ccline.cmdpos, 3348 (*mb_ptr2len)(ccline.cmdbuff + ccline.cmdpos)); 3349 else 3350 draw_cmdline(ccline.cmdpos, 1); 3351 msg_no_more = FALSE; 3352 cursorcmd(); 3353 extra_char = NUL; 3354 } 3355 3356 /* 3357 * Put the given string, of the given length, onto the command line. 3358 * If len is -1, then STRLEN() is used to calculate the length. 3359 * If 'redraw' is TRUE then the new part of the command line, and the remaining 3360 * part will be redrawn, otherwise it will not. If this function is called 3361 * twice in a row, then 'redraw' should be FALSE and redrawcmd() should be 3362 * called afterwards. 3363 */ 3364 int 3365 put_on_cmdline(char_u *str, int len, int redraw) 3366 { 3367 int retval; 3368 int i; 3369 int m; 3370 int c; 3371 3372 if (len < 0) 3373 len = (int)STRLEN(str); 3374 3375 // Check if ccline.cmdbuff needs to be longer 3376 if (ccline.cmdlen + len + 1 >= ccline.cmdbufflen) 3377 retval = realloc_cmdbuff(ccline.cmdlen + len + 1); 3378 else 3379 retval = OK; 3380 if (retval == OK) 3381 { 3382 if (!ccline.overstrike) 3383 { 3384 mch_memmove(ccline.cmdbuff + ccline.cmdpos + len, 3385 ccline.cmdbuff + ccline.cmdpos, 3386 (size_t)(ccline.cmdlen - ccline.cmdpos)); 3387 ccline.cmdlen += len; 3388 } 3389 else 3390 { 3391 if (has_mbyte) 3392 { 3393 // Count nr of characters in the new string. 3394 m = 0; 3395 for (i = 0; i < len; i += (*mb_ptr2len)(str + i)) 3396 ++m; 3397 // Count nr of bytes in cmdline that are overwritten by these 3398 // characters. 3399 for (i = ccline.cmdpos; i < ccline.cmdlen && m > 0; 3400 i += (*mb_ptr2len)(ccline.cmdbuff + i)) 3401 --m; 3402 if (i < ccline.cmdlen) 3403 { 3404 mch_memmove(ccline.cmdbuff + ccline.cmdpos + len, 3405 ccline.cmdbuff + i, (size_t)(ccline.cmdlen - i)); 3406 ccline.cmdlen += ccline.cmdpos + len - i; 3407 } 3408 else 3409 ccline.cmdlen = ccline.cmdpos + len; 3410 } 3411 else if (ccline.cmdpos + len > ccline.cmdlen) 3412 ccline.cmdlen = ccline.cmdpos + len; 3413 } 3414 mch_memmove(ccline.cmdbuff + ccline.cmdpos, str, (size_t)len); 3415 ccline.cmdbuff[ccline.cmdlen] = NUL; 3416 3417 if (enc_utf8) 3418 { 3419 // When the inserted text starts with a composing character, 3420 // backup to the character before it. There could be two of them. 3421 i = 0; 3422 c = utf_ptr2char(ccline.cmdbuff + ccline.cmdpos); 3423 while (ccline.cmdpos > 0 && utf_iscomposing(c)) 3424 { 3425 i = (*mb_head_off)(ccline.cmdbuff, 3426 ccline.cmdbuff + ccline.cmdpos - 1) + 1; 3427 ccline.cmdpos -= i; 3428 len += i; 3429 c = utf_ptr2char(ccline.cmdbuff + ccline.cmdpos); 3430 } 3431 #ifdef FEAT_ARABIC 3432 if (i == 0 && ccline.cmdpos > 0 && arabic_maycombine(c)) 3433 { 3434 // Check the previous character for Arabic combining pair. 3435 i = (*mb_head_off)(ccline.cmdbuff, 3436 ccline.cmdbuff + ccline.cmdpos - 1) + 1; 3437 if (arabic_combine(utf_ptr2char(ccline.cmdbuff 3438 + ccline.cmdpos - i), c)) 3439 { 3440 ccline.cmdpos -= i; 3441 len += i; 3442 } 3443 else 3444 i = 0; 3445 } 3446 #endif 3447 if (i != 0) 3448 { 3449 // Also backup the cursor position. 3450 i = ptr2cells(ccline.cmdbuff + ccline.cmdpos); 3451 ccline.cmdspos -= i; 3452 msg_col -= i; 3453 if (msg_col < 0) 3454 { 3455 msg_col += Columns; 3456 --msg_row; 3457 } 3458 } 3459 } 3460 3461 if (redraw && !cmd_silent) 3462 { 3463 msg_no_more = TRUE; 3464 i = cmdline_row; 3465 cursorcmd(); 3466 draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos); 3467 // Avoid clearing the rest of the line too often. 3468 if (cmdline_row != i || ccline.overstrike) 3469 msg_clr_eos(); 3470 msg_no_more = FALSE; 3471 } 3472 if (KeyTyped) 3473 { 3474 m = Columns * Rows; 3475 if (m < 0) // overflow, Columns or Rows at weird value 3476 m = MAXCOL; 3477 } 3478 else 3479 m = MAXCOL; 3480 for (i = 0; i < len; ++i) 3481 { 3482 c = cmdline_charsize(ccline.cmdpos); 3483 // count ">" for a double-wide char that doesn't fit. 3484 if (has_mbyte) 3485 correct_cmdspos(ccline.cmdpos, c); 3486 // Stop cursor at the end of the screen, but do increment the 3487 // insert position, so that entering a very long command 3488 // works, even though you can't see it. 3489 if (ccline.cmdspos + c < m) 3490 ccline.cmdspos += c; 3491 3492 if (has_mbyte) 3493 { 3494 c = (*mb_ptr2len)(ccline.cmdbuff + ccline.cmdpos) - 1; 3495 if (c > len - i - 1) 3496 c = len - i - 1; 3497 ccline.cmdpos += c; 3498 i += c; 3499 } 3500 ++ccline.cmdpos; 3501 } 3502 } 3503 if (redraw) 3504 msg_check(); 3505 return retval; 3506 } 3507 3508 static cmdline_info_T prev_ccline; 3509 static int prev_ccline_used = FALSE; 3510 3511 /* 3512 * Save ccline, because obtaining the "=" register may execute "normal :cmd" 3513 * and overwrite it. But get_cmdline_str() may need it, thus make it 3514 * available globally in prev_ccline. 3515 */ 3516 static void 3517 save_cmdline(cmdline_info_T *ccp) 3518 { 3519 if (!prev_ccline_used) 3520 { 3521 CLEAR_FIELD(prev_ccline); 3522 prev_ccline_used = TRUE; 3523 } 3524 *ccp = prev_ccline; 3525 prev_ccline = ccline; 3526 ccline.cmdbuff = NULL; // signal that ccline is not in use 3527 } 3528 3529 /* 3530 * Restore ccline after it has been saved with save_cmdline(). 3531 */ 3532 static void 3533 restore_cmdline(cmdline_info_T *ccp) 3534 { 3535 ccline = prev_ccline; 3536 prev_ccline = *ccp; 3537 } 3538 3539 /* 3540 * Paste a yank register into the command line. 3541 * Used by CTRL-R command in command-line mode. 3542 * insert_reg() can't be used here, because special characters from the 3543 * register contents will be interpreted as commands. 3544 * 3545 * Return FAIL for failure, OK otherwise. 3546 */ 3547 static int 3548 cmdline_paste( 3549 int regname, 3550 int literally, // Insert text literally instead of "as typed" 3551 int remcr) // remove trailing CR 3552 { 3553 long i; 3554 char_u *arg; 3555 char_u *p; 3556 int allocated; 3557 3558 // check for valid regname; also accept special characters for CTRL-R in 3559 // the command line 3560 if (regname != Ctrl_F && regname != Ctrl_P && regname != Ctrl_W 3561 && regname != Ctrl_A && regname != Ctrl_L 3562 && !valid_yank_reg(regname, FALSE)) 3563 return FAIL; 3564 3565 // A register containing CTRL-R can cause an endless loop. Allow using 3566 // CTRL-C to break the loop. 3567 line_breakcheck(); 3568 if (got_int) 3569 return FAIL; 3570 3571 #ifdef FEAT_CLIPBOARD 3572 regname = may_get_selection(regname); 3573 #endif 3574 3575 // Need to set "textwinlock" to avoid nasty things like going to another 3576 // buffer when evaluating an expression. 3577 ++textwinlock; 3578 i = get_spec_reg(regname, &arg, &allocated, TRUE); 3579 --textwinlock; 3580 3581 if (i) 3582 { 3583 // Got the value of a special register in "arg". 3584 if (arg == NULL) 3585 return FAIL; 3586 3587 // When 'incsearch' is set and CTRL-R CTRL-W used: skip the duplicate 3588 // part of the word. 3589 p = arg; 3590 if (p_is && regname == Ctrl_W) 3591 { 3592 char_u *w; 3593 int len; 3594 3595 // Locate start of last word in the cmd buffer. 3596 for (w = ccline.cmdbuff + ccline.cmdpos; w > ccline.cmdbuff; ) 3597 { 3598 if (has_mbyte) 3599 { 3600 len = (*mb_head_off)(ccline.cmdbuff, w - 1) + 1; 3601 if (!vim_iswordc(mb_ptr2char(w - len))) 3602 break; 3603 w -= len; 3604 } 3605 else 3606 { 3607 if (!vim_iswordc(w[-1])) 3608 break; 3609 --w; 3610 } 3611 } 3612 len = (int)((ccline.cmdbuff + ccline.cmdpos) - w); 3613 if (p_ic ? STRNICMP(w, arg, len) == 0 : STRNCMP(w, arg, len) == 0) 3614 p += len; 3615 } 3616 3617 cmdline_paste_str(p, literally); 3618 if (allocated) 3619 vim_free(arg); 3620 return OK; 3621 } 3622 3623 return cmdline_paste_reg(regname, literally, remcr); 3624 } 3625 3626 /* 3627 * Put a string on the command line. 3628 * When "literally" is TRUE, insert literally. 3629 * When "literally" is FALSE, insert as typed, but don't leave the command 3630 * line. 3631 */ 3632 void 3633 cmdline_paste_str(char_u *s, int literally) 3634 { 3635 int c, cv; 3636 3637 if (literally) 3638 put_on_cmdline(s, -1, TRUE); 3639 else 3640 while (*s != NUL) 3641 { 3642 cv = *s; 3643 if (cv == Ctrl_V && s[1]) 3644 ++s; 3645 if (has_mbyte) 3646 c = mb_cptr2char_adv(&s); 3647 else 3648 c = *s++; 3649 if (cv == Ctrl_V || c == ESC || c == Ctrl_C 3650 || c == CAR || c == NL || c == Ctrl_L 3651 #ifdef UNIX 3652 || c == intr_char 3653 #endif 3654 || (c == Ctrl_BSL && *s == Ctrl_N)) 3655 stuffcharReadbuff(Ctrl_V); 3656 stuffcharReadbuff(c); 3657 } 3658 } 3659 3660 #ifdef FEAT_WILDMENU 3661 /* 3662 * Delete characters on the command line, from "from" to the current 3663 * position. 3664 */ 3665 static void 3666 cmdline_del(int from) 3667 { 3668 mch_memmove(ccline.cmdbuff + from, ccline.cmdbuff + ccline.cmdpos, 3669 (size_t)(ccline.cmdlen - ccline.cmdpos + 1)); 3670 ccline.cmdlen -= ccline.cmdpos - from; 3671 ccline.cmdpos = from; 3672 } 3673 #endif 3674 3675 /* 3676 * This function is called when the screen size changes and with incremental 3677 * search and in other situations where the command line may have been 3678 * overwritten. 3679 */ 3680 void 3681 redrawcmdline(void) 3682 { 3683 redrawcmdline_ex(TRUE); 3684 } 3685 3686 void 3687 redrawcmdline_ex(int do_compute_cmdrow) 3688 { 3689 if (cmd_silent) 3690 return; 3691 need_wait_return = FALSE; 3692 if (do_compute_cmdrow) 3693 compute_cmdrow(); 3694 redrawcmd(); 3695 cursorcmd(); 3696 } 3697 3698 static void 3699 redrawcmdprompt(void) 3700 { 3701 int i; 3702 3703 if (cmd_silent) 3704 return; 3705 if (ccline.cmdfirstc != NUL) 3706 msg_putchar(ccline.cmdfirstc); 3707 if (ccline.cmdprompt != NULL) 3708 { 3709 msg_puts_attr((char *)ccline.cmdprompt, ccline.cmdattr); 3710 ccline.cmdindent = msg_col + (msg_row - cmdline_row) * Columns; 3711 // do the reverse of set_cmdspos() 3712 if (ccline.cmdfirstc != NUL) 3713 --ccline.cmdindent; 3714 } 3715 else 3716 for (i = ccline.cmdindent; i > 0; --i) 3717 msg_putchar(' '); 3718 } 3719 3720 /* 3721 * Redraw what is currently on the command line. 3722 */ 3723 void 3724 redrawcmd(void) 3725 { 3726 if (cmd_silent) 3727 return; 3728 3729 // when 'incsearch' is set there may be no command line while redrawing 3730 if (ccline.cmdbuff == NULL) 3731 { 3732 windgoto(cmdline_row, 0); 3733 msg_clr_eos(); 3734 return; 3735 } 3736 3737 msg_start(); 3738 redrawcmdprompt(); 3739 3740 // Don't use more prompt, truncate the cmdline if it doesn't fit. 3741 msg_no_more = TRUE; 3742 draw_cmdline(0, ccline.cmdlen); 3743 msg_clr_eos(); 3744 msg_no_more = FALSE; 3745 3746 set_cmdspos_cursor(); 3747 if (extra_char != NUL) 3748 putcmdline(extra_char, extra_char_shift); 3749 3750 /* 3751 * An emsg() before may have set msg_scroll. This is used in normal mode, 3752 * in cmdline mode we can reset them now. 3753 */ 3754 msg_scroll = FALSE; // next message overwrites cmdline 3755 3756 // Typing ':' at the more prompt may set skip_redraw. We don't want this 3757 // in cmdline mode 3758 skip_redraw = FALSE; 3759 } 3760 3761 void 3762 compute_cmdrow(void) 3763 { 3764 if (exmode_active || msg_scrolled != 0) 3765 cmdline_row = Rows - 1; 3766 else 3767 cmdline_row = W_WINROW(lastwin) + lastwin->w_height 3768 + lastwin->w_status_height; 3769 } 3770 3771 void 3772 cursorcmd(void) 3773 { 3774 if (cmd_silent) 3775 return; 3776 3777 #ifdef FEAT_RIGHTLEFT 3778 if (cmdmsg_rl) 3779 { 3780 msg_row = cmdline_row + (ccline.cmdspos / (int)(Columns - 1)); 3781 msg_col = (int)Columns - (ccline.cmdspos % (int)(Columns - 1)) - 1; 3782 if (msg_row <= 0) 3783 msg_row = Rows - 1; 3784 } 3785 else 3786 #endif 3787 { 3788 msg_row = cmdline_row + (ccline.cmdspos / (int)Columns); 3789 msg_col = ccline.cmdspos % (int)Columns; 3790 if (msg_row >= Rows) 3791 msg_row = Rows - 1; 3792 } 3793 3794 windgoto(msg_row, msg_col); 3795 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) 3796 if (p_imst == IM_ON_THE_SPOT) 3797 redrawcmd_preedit(); 3798 #endif 3799 #ifdef MCH_CURSOR_SHAPE 3800 mch_update_cursor(); 3801 #endif 3802 } 3803 3804 void 3805 gotocmdline(int clr) 3806 { 3807 msg_start(); 3808 #ifdef FEAT_RIGHTLEFT 3809 if (cmdmsg_rl) 3810 msg_col = Columns - 1; 3811 else 3812 #endif 3813 msg_col = 0; // always start in column 0 3814 if (clr) // clear the bottom line(s) 3815 msg_clr_eos(); // will reset clear_cmdline 3816 windgoto(cmdline_row, 0); 3817 } 3818 3819 /* 3820 * Check the word in front of the cursor for an abbreviation. 3821 * Called when the non-id character "c" has been entered. 3822 * When an abbreviation is recognized it is removed from the text with 3823 * backspaces and the replacement string is inserted, followed by "c". 3824 */ 3825 static int 3826 ccheck_abbr(int c) 3827 { 3828 int spos = 0; 3829 3830 if (p_paste || no_abbr) // no abbreviations or in paste mode 3831 return FALSE; 3832 3833 // Do not consider '<,'> be part of the mapping, skip leading whitespace. 3834 // Actually accepts any mark. 3835 while (VIM_ISWHITE(ccline.cmdbuff[spos]) && spos < ccline.cmdlen) 3836 spos++; 3837 if (ccline.cmdlen - spos > 5 3838 && ccline.cmdbuff[spos] == '\'' 3839 && ccline.cmdbuff[spos + 2] == ',' 3840 && ccline.cmdbuff[spos + 3] == '\'') 3841 spos += 5; 3842 else 3843 // check abbreviation from the beginning of the commandline 3844 spos = 0; 3845 3846 return check_abbr(c, ccline.cmdbuff, ccline.cmdpos, spos); 3847 } 3848 3849 /* 3850 * Escape special characters in "fname" for when used as a file name argument 3851 * after a Vim command, or, when "shell" is non-zero, a shell command. 3852 * Returns the result in allocated memory. 3853 */ 3854 char_u * 3855 vim_strsave_fnameescape(char_u *fname, int shell UNUSED) 3856 { 3857 char_u *p; 3858 #ifdef BACKSLASH_IN_FILENAME 3859 char_u buf[20]; 3860 int j = 0; 3861 3862 // Don't escape '[', '{' and '!' if they are in 'isfname'. 3863 for (p = PATH_ESC_CHARS; *p != NUL; ++p) 3864 if ((*p != '[' && *p != '{' && *p != '!') || !vim_isfilec(*p)) 3865 buf[j++] = *p; 3866 buf[j] = NUL; 3867 p = vim_strsave_escaped(fname, buf); 3868 #else 3869 p = vim_strsave_escaped(fname, shell ? SHELL_ESC_CHARS : PATH_ESC_CHARS); 3870 if (shell && csh_like_shell() && p != NULL) 3871 { 3872 char_u *s; 3873 3874 // For csh and similar shells need to put two backslashes before '!'. 3875 // One is taken by Vim, one by the shell. 3876 s = vim_strsave_escaped(p, (char_u *)"!"); 3877 vim_free(p); 3878 p = s; 3879 } 3880 #endif 3881 3882 // '>' and '+' are special at the start of some commands, e.g. ":edit" and 3883 // ":write". "cd -" has a special meaning. 3884 if (p != NULL && (*p == '>' || *p == '+' || (*p == '-' && p[1] == NUL))) 3885 escape_fname(&p); 3886 3887 return p; 3888 } 3889 3890 /* 3891 * Put a backslash before the file name in "pp", which is in allocated memory. 3892 */ 3893 void 3894 escape_fname(char_u **pp) 3895 { 3896 char_u *p; 3897 3898 p = alloc(STRLEN(*pp) + 2); 3899 if (p != NULL) 3900 { 3901 p[0] = '\\'; 3902 STRCPY(p + 1, *pp); 3903 vim_free(*pp); 3904 *pp = p; 3905 } 3906 } 3907 3908 /* 3909 * For each file name in files[num_files]: 3910 * If 'orig_pat' starts with "~/", replace the home directory with "~". 3911 */ 3912 void 3913 tilde_replace( 3914 char_u *orig_pat, 3915 int num_files, 3916 char_u **files) 3917 { 3918 int i; 3919 char_u *p; 3920 3921 if (orig_pat[0] == '~' && vim_ispathsep(orig_pat[1])) 3922 { 3923 for (i = 0; i < num_files; ++i) 3924 { 3925 p = home_replace_save(NULL, files[i]); 3926 if (p != NULL) 3927 { 3928 vim_free(files[i]); 3929 files[i] = p; 3930 } 3931 } 3932 } 3933 } 3934 3935 /* 3936 * Get a pointer to the current command line info. 3937 */ 3938 cmdline_info_T * 3939 get_cmdline_info(void) 3940 { 3941 return &ccline; 3942 } 3943 3944 #if defined(FEAT_EVAL) || defined(FEAT_CMDWIN) || defined(PROTO) 3945 /* 3946 * Get pointer to the command line info to use. save_ccline() may clear 3947 * ccline and put the previous value in prev_ccline. 3948 */ 3949 static cmdline_info_T * 3950 get_ccline_ptr(void) 3951 { 3952 if ((State & CMDLINE) == 0) 3953 return NULL; 3954 if (ccline.cmdbuff != NULL) 3955 return &ccline; 3956 if (prev_ccline_used && prev_ccline.cmdbuff != NULL) 3957 return &prev_ccline; 3958 return NULL; 3959 } 3960 #endif 3961 3962 #if defined(FEAT_EVAL) || defined(PROTO) 3963 /* 3964 * Get the current command line in allocated memory. 3965 * Only works when the command line is being edited. 3966 * Returns NULL when something is wrong. 3967 */ 3968 static char_u * 3969 get_cmdline_str(void) 3970 { 3971 cmdline_info_T *p; 3972 3973 if (cmdline_star > 0) 3974 return NULL; 3975 p = get_ccline_ptr(); 3976 if (p == NULL) 3977 return NULL; 3978 return vim_strnsave(p->cmdbuff, p->cmdlen); 3979 } 3980 3981 /* 3982 * "getcmdline()" function 3983 */ 3984 void 3985 f_getcmdline(typval_T *argvars UNUSED, typval_T *rettv) 3986 { 3987 rettv->v_type = VAR_STRING; 3988 rettv->vval.v_string = get_cmdline_str(); 3989 } 3990 3991 /* 3992 * "getcmdpos()" function 3993 */ 3994 void 3995 f_getcmdpos(typval_T *argvars UNUSED, typval_T *rettv) 3996 { 3997 cmdline_info_T *p = get_ccline_ptr(); 3998 3999 rettv->vval.v_number = 0; 4000 if (p != NULL) 4001 rettv->vval.v_number = p->cmdpos + 1; 4002 } 4003 4004 /* 4005 * Set the command line byte position to "pos". Zero is the first position. 4006 * Only works when the command line is being edited. 4007 * Returns 1 when failed, 0 when OK. 4008 */ 4009 static int 4010 set_cmdline_pos( 4011 int pos) 4012 { 4013 cmdline_info_T *p = get_ccline_ptr(); 4014 4015 if (p == NULL) 4016 return 1; 4017 4018 // The position is not set directly but after CTRL-\ e or CTRL-R = has 4019 // changed the command line. 4020 if (pos < 0) 4021 new_cmdpos = 0; 4022 else 4023 new_cmdpos = pos; 4024 return 0; 4025 } 4026 4027 /* 4028 * "setcmdpos()" function 4029 */ 4030 void 4031 f_setcmdpos(typval_T *argvars, typval_T *rettv) 4032 { 4033 int pos = (int)tv_get_number(&argvars[0]) - 1; 4034 4035 if (pos >= 0) 4036 rettv->vval.v_number = set_cmdline_pos(pos); 4037 } 4038 4039 /* 4040 * "getcmdtype()" function 4041 */ 4042 void 4043 f_getcmdtype(typval_T *argvars UNUSED, typval_T *rettv) 4044 { 4045 rettv->v_type = VAR_STRING; 4046 rettv->vval.v_string = alloc(2); 4047 if (rettv->vval.v_string != NULL) 4048 { 4049 rettv->vval.v_string[0] = get_cmdline_type(); 4050 rettv->vval.v_string[1] = NUL; 4051 } 4052 } 4053 4054 #endif 4055 4056 #if defined(FEAT_EVAL) || defined(FEAT_CMDWIN) || defined(PROTO) 4057 /* 4058 * Get the current command-line type. 4059 * Returns ':' or '/' or '?' or '@' or '>' or '-' 4060 * Only works when the command line is being edited. 4061 * Returns NUL when something is wrong. 4062 */ 4063 int 4064 get_cmdline_type(void) 4065 { 4066 cmdline_info_T *p = get_ccline_ptr(); 4067 4068 if (p == NULL) 4069 return NUL; 4070 if (p->cmdfirstc == NUL) 4071 return 4072 # ifdef FEAT_EVAL 4073 (p->input_fn) ? '@' : 4074 # endif 4075 '-'; 4076 return p->cmdfirstc; 4077 } 4078 #endif 4079 4080 /* 4081 * Return the first character of the current command line. 4082 */ 4083 int 4084 get_cmdline_firstc(void) 4085 { 4086 return ccline.cmdfirstc; 4087 } 4088 4089 /* 4090 * Get indices "num1,num2" that specify a range within a list (not a range of 4091 * text lines in a buffer!) from a string. Used for ":history" and ":clist". 4092 * Returns OK if parsed successfully, otherwise FAIL. 4093 */ 4094 int 4095 get_list_range(char_u **str, int *num1, int *num2) 4096 { 4097 int len; 4098 int first = FALSE; 4099 varnumber_T num; 4100 4101 *str = skipwhite(*str); 4102 if (**str == '-' || vim_isdigit(**str)) // parse "from" part of range 4103 { 4104 vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0, FALSE); 4105 *str += len; 4106 *num1 = (int)num; 4107 first = TRUE; 4108 } 4109 *str = skipwhite(*str); 4110 if (**str == ',') // parse "to" part of range 4111 { 4112 *str = skipwhite(*str + 1); 4113 vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0, FALSE); 4114 if (len > 0) 4115 { 4116 *num2 = (int)num; 4117 *str = skipwhite(*str + len); 4118 } 4119 else if (!first) // no number given at all 4120 return FAIL; 4121 } 4122 else if (first) // only one number given 4123 *num2 = *num1; 4124 return OK; 4125 } 4126 4127 #if defined(FEAT_CMDWIN) || defined(PROTO) 4128 /* 4129 * Check value of 'cedit' and set cedit_key. 4130 * Returns NULL if value is OK, error message otherwise. 4131 */ 4132 char * 4133 check_cedit(void) 4134 { 4135 int n; 4136 4137 if (*p_cedit == NUL) 4138 cedit_key = -1; 4139 else 4140 { 4141 n = string_to_key(p_cedit, FALSE); 4142 if (vim_isprintc(n)) 4143 return e_invarg; 4144 cedit_key = n; 4145 } 4146 return NULL; 4147 } 4148 4149 /* 4150 * Open a window on the current command line and history. Allow editing in 4151 * the window. Returns when the window is closed. 4152 * Returns: 4153 * CR if the command is to be executed 4154 * Ctrl_C if it is to be abandoned 4155 * K_IGNORE if editing continues 4156 */ 4157 static int 4158 open_cmdwin(void) 4159 { 4160 bufref_T old_curbuf; 4161 win_T *old_curwin = curwin; 4162 bufref_T bufref; 4163 win_T *wp; 4164 int i; 4165 linenr_T lnum; 4166 int histtype; 4167 garray_T winsizes; 4168 int save_restart_edit = restart_edit; 4169 int save_State = State; 4170 int save_exmode = exmode_active; 4171 #ifdef FEAT_RIGHTLEFT 4172 int save_cmdmsg_rl = cmdmsg_rl; 4173 #endif 4174 #ifdef FEAT_FOLDING 4175 int save_KeyTyped; 4176 #endif 4177 4178 // Can't do this recursively. Can't do it when typing a password. 4179 if (cmdwin_type != 0 4180 # if defined(FEAT_CRYPT) || defined(FEAT_EVAL) 4181 || cmdline_star > 0 4182 # endif 4183 ) 4184 { 4185 beep_flush(); 4186 return K_IGNORE; 4187 } 4188 set_bufref(&old_curbuf, curbuf); 4189 4190 // Save current window sizes. 4191 win_size_save(&winsizes); 4192 4193 // When using completion in Insert mode with <C-R>=<C-F> one can open the 4194 // command line window, but we don't want the popup menu then. 4195 pum_undisplay(); 4196 4197 // don't use a new tab page 4198 cmdmod.tab = 0; 4199 cmdmod.noswapfile = 1; 4200 4201 // Create a window for the command-line buffer. 4202 if (win_split((int)p_cwh, WSP_BOT) == FAIL) 4203 { 4204 beep_flush(); 4205 ga_clear(&winsizes); 4206 return K_IGNORE; 4207 } 4208 cmdwin_type = get_cmdline_type(); 4209 4210 // Create the command-line buffer empty. 4211 (void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL); 4212 apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, curbuf); 4213 (void)setfname(curbuf, (char_u *)"[Command Line]", NULL, TRUE); 4214 apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, curbuf); 4215 set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL); 4216 curbuf->b_p_ma = TRUE; 4217 #ifdef FEAT_FOLDING 4218 curwin->w_p_fen = FALSE; 4219 #endif 4220 # ifdef FEAT_RIGHTLEFT 4221 curwin->w_p_rl = cmdmsg_rl; 4222 cmdmsg_rl = FALSE; 4223 # endif 4224 RESET_BINDING(curwin); 4225 4226 // Don't allow switching to another buffer. 4227 ++curbuf_lock; 4228 4229 // Showing the prompt may have set need_wait_return, reset it. 4230 need_wait_return = FALSE; 4231 4232 histtype = hist_char2type(cmdwin_type); 4233 if (histtype == HIST_CMD || histtype == HIST_DEBUG) 4234 { 4235 if (p_wc == TAB) 4236 { 4237 add_map((char_u *)"<buffer> <Tab> <C-X><C-V>", INSERT); 4238 add_map((char_u *)"<buffer> <Tab> a<C-X><C-V>", NORMAL); 4239 } 4240 set_option_value((char_u *)"ft", 0L, (char_u *)"vim", OPT_LOCAL); 4241 } 4242 --curbuf_lock; 4243 4244 // Reset 'textwidth' after setting 'filetype' (the Vim filetype plugin 4245 // sets 'textwidth' to 78). 4246 curbuf->b_p_tw = 0; 4247 4248 // Fill the buffer with the history. 4249 init_history(); 4250 if (get_hislen() > 0) 4251 { 4252 i = *get_hisidx(histtype); 4253 if (i >= 0) 4254 { 4255 lnum = 0; 4256 do 4257 { 4258 if (++i == get_hislen()) 4259 i = 0; 4260 if (get_histentry(histtype)[i].hisstr != NULL) 4261 ml_append(lnum++, get_histentry(histtype)[i].hisstr, 4262 (colnr_T)0, FALSE); 4263 } 4264 while (i != *get_hisidx(histtype)); 4265 } 4266 } 4267 4268 // Replace the empty last line with the current command-line and put the 4269 // cursor there. 4270 ml_replace(curbuf->b_ml.ml_line_count, ccline.cmdbuff, TRUE); 4271 curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; 4272 curwin->w_cursor.col = ccline.cmdpos; 4273 changed_line_abv_curs(); 4274 invalidate_botline(); 4275 redraw_later(SOME_VALID); 4276 4277 // No Ex mode here! 4278 exmode_active = 0; 4279 4280 State = NORMAL; 4281 setmouse(); 4282 4283 // Reset here so it can be set by a CmdWinEnter autocommand. 4284 cmdwin_result = 0; 4285 4286 // Trigger CmdwinEnter autocommands. 4287 trigger_cmd_autocmd(cmdwin_type, EVENT_CMDWINENTER); 4288 if (restart_edit != 0) // autocmd with ":startinsert" 4289 stuffcharReadbuff(K_NOP); 4290 4291 i = RedrawingDisabled; 4292 RedrawingDisabled = 0; 4293 4294 /* 4295 * Call the main loop until <CR> or CTRL-C is typed. 4296 */ 4297 main_loop(TRUE, FALSE); 4298 4299 RedrawingDisabled = i; 4300 4301 # ifdef FEAT_FOLDING 4302 save_KeyTyped = KeyTyped; 4303 # endif 4304 4305 // Trigger CmdwinLeave autocommands. 4306 trigger_cmd_autocmd(cmdwin_type, EVENT_CMDWINLEAVE); 4307 4308 # ifdef FEAT_FOLDING 4309 // Restore KeyTyped in case it is modified by autocommands 4310 KeyTyped = save_KeyTyped; 4311 # endif 4312 4313 cmdwin_type = 0; 4314 exmode_active = save_exmode; 4315 4316 // Safety check: The old window or buffer was deleted: It's a bug when 4317 // this happens! 4318 if (!win_valid(old_curwin) || !bufref_valid(&old_curbuf)) 4319 { 4320 cmdwin_result = Ctrl_C; 4321 emsg(_("E199: Active window or buffer deleted")); 4322 } 4323 else 4324 { 4325 # if defined(FEAT_EVAL) 4326 // autocmds may abort script processing 4327 if (aborting() && cmdwin_result != K_IGNORE) 4328 cmdwin_result = Ctrl_C; 4329 # endif 4330 // Set the new command line from the cmdline buffer. 4331 vim_free(ccline.cmdbuff); 4332 if (cmdwin_result == K_XF1 || cmdwin_result == K_XF2) // :qa[!] typed 4333 { 4334 char *p = (cmdwin_result == K_XF2) ? "qa" : "qa!"; 4335 4336 if (histtype == HIST_CMD) 4337 { 4338 // Execute the command directly. 4339 ccline.cmdbuff = vim_strsave((char_u *)p); 4340 cmdwin_result = CAR; 4341 } 4342 else 4343 { 4344 // First need to cancel what we were doing. 4345 ccline.cmdbuff = NULL; 4346 stuffcharReadbuff(':'); 4347 stuffReadbuff((char_u *)p); 4348 stuffcharReadbuff(CAR); 4349 } 4350 } 4351 else if (cmdwin_result == K_XF2) // :qa typed 4352 { 4353 ccline.cmdbuff = vim_strsave((char_u *)"qa"); 4354 cmdwin_result = CAR; 4355 } 4356 else if (cmdwin_result == Ctrl_C) 4357 { 4358 // :q or :close, don't execute any command 4359 // and don't modify the cmd window. 4360 ccline.cmdbuff = NULL; 4361 } 4362 else 4363 ccline.cmdbuff = vim_strsave(ml_get_curline()); 4364 if (ccline.cmdbuff == NULL) 4365 { 4366 ccline.cmdbuff = vim_strsave((char_u *)""); 4367 ccline.cmdlen = 0; 4368 ccline.cmdbufflen = 1; 4369 ccline.cmdpos = 0; 4370 cmdwin_result = Ctrl_C; 4371 } 4372 else 4373 { 4374 ccline.cmdlen = (int)STRLEN(ccline.cmdbuff); 4375 ccline.cmdbufflen = ccline.cmdlen + 1; 4376 ccline.cmdpos = curwin->w_cursor.col; 4377 if (ccline.cmdpos > ccline.cmdlen) 4378 ccline.cmdpos = ccline.cmdlen; 4379 if (cmdwin_result == K_IGNORE) 4380 { 4381 set_cmdspos_cursor(); 4382 redrawcmd(); 4383 } 4384 } 4385 4386 # ifdef FEAT_CONCEAL 4387 // Avoid command-line window first character being concealed. 4388 curwin->w_p_cole = 0; 4389 # endif 4390 wp = curwin; 4391 set_bufref(&bufref, curbuf); 4392 win_goto(old_curwin); 4393 win_close(wp, TRUE); 4394 4395 // win_close() may have already wiped the buffer when 'bh' is 4396 // set to 'wipe' 4397 if (bufref_valid(&bufref)) 4398 close_buffer(NULL, bufref.br_buf, DOBUF_WIPE, FALSE, FALSE); 4399 4400 // Restore window sizes. 4401 win_size_restore(&winsizes); 4402 } 4403 4404 ga_clear(&winsizes); 4405 restart_edit = save_restart_edit; 4406 # ifdef FEAT_RIGHTLEFT 4407 cmdmsg_rl = save_cmdmsg_rl; 4408 # endif 4409 4410 State = save_State; 4411 setmouse(); 4412 4413 return cmdwin_result; 4414 } 4415 #endif // FEAT_CMDWIN 4416 4417 /* 4418 * Used for commands that either take a simple command string argument, or: 4419 * cmd << endmarker 4420 * {script} 4421 * endmarker 4422 * Returns a pointer to allocated memory with {script} or NULL. 4423 */ 4424 char_u * 4425 script_get(exarg_T *eap UNUSED, char_u *cmd UNUSED) 4426 { 4427 #ifdef FEAT_EVAL 4428 list_T *l; 4429 listitem_T *li; 4430 char_u *s; 4431 garray_T ga; 4432 4433 if (cmd[0] != '<' || cmd[1] != '<' || eap->getline == NULL) 4434 return NULL; 4435 cmd += 2; 4436 4437 l = heredoc_get(eap, cmd, TRUE); 4438 if (l == NULL) 4439 return NULL; 4440 4441 ga_init2(&ga, 1, 0x400); 4442 4443 FOR_ALL_LIST_ITEMS(l, li) 4444 { 4445 s = tv_get_string(&li->li_tv); 4446 ga_concat(&ga, s); 4447 ga_append(&ga, '\n'); 4448 } 4449 ga_append(&ga, NUL); 4450 4451 list_free(l); 4452 return (char_u *)ga.ga_data; 4453 #else 4454 return NULL; 4455 #endif 4456 } 4457 4458 #if defined(FEAT_EVAL) || defined(PROTO) 4459 /* 4460 * This function is used by f_input() and f_inputdialog() functions. The third 4461 * argument to f_input() specifies the type of completion to use at the 4462 * prompt. The third argument to f_inputdialog() specifies the value to return 4463 * when the user cancels the prompt. 4464 */ 4465 void 4466 get_user_input( 4467 typval_T *argvars, 4468 typval_T *rettv, 4469 int inputdialog, 4470 int secret) 4471 { 4472 char_u *prompt = tv_get_string_chk(&argvars[0]); 4473 char_u *p = NULL; 4474 int c; 4475 char_u buf[NUMBUFLEN]; 4476 int cmd_silent_save = cmd_silent; 4477 char_u *defstr = (char_u *)""; 4478 int xp_type = EXPAND_NOTHING; 4479 char_u *xp_arg = NULL; 4480 4481 rettv->v_type = VAR_STRING; 4482 rettv->vval.v_string = NULL; 4483 if (input_busy) 4484 return; // this doesn't work recursively. 4485 4486 #ifdef NO_CONSOLE_INPUT 4487 // While starting up, there is no place to enter text. When running tests 4488 // with --not-a-term we assume feedkeys() will be used. 4489 if (no_console_input() && !is_not_a_term()) 4490 return; 4491 #endif 4492 4493 cmd_silent = FALSE; // Want to see the prompt. 4494 if (prompt != NULL) 4495 { 4496 // Only the part of the message after the last NL is considered as 4497 // prompt for the command line 4498 p = vim_strrchr(prompt, '\n'); 4499 if (p == NULL) 4500 p = prompt; 4501 else 4502 { 4503 ++p; 4504 c = *p; 4505 *p = NUL; 4506 msg_start(); 4507 msg_clr_eos(); 4508 msg_puts_attr((char *)prompt, get_echo_attr()); 4509 msg_didout = FALSE; 4510 msg_starthere(); 4511 *p = c; 4512 } 4513 cmdline_row = msg_row; 4514 4515 if (argvars[1].v_type != VAR_UNKNOWN) 4516 { 4517 defstr = tv_get_string_buf_chk(&argvars[1], buf); 4518 if (defstr != NULL) 4519 stuffReadbuffSpec(defstr); 4520 4521 if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN) 4522 { 4523 char_u *xp_name; 4524 int xp_namelen; 4525 long argt; 4526 4527 // input() with a third argument: completion 4528 rettv->vval.v_string = NULL; 4529 4530 xp_name = tv_get_string_buf_chk(&argvars[2], buf); 4531 if (xp_name == NULL) 4532 return; 4533 4534 xp_namelen = (int)STRLEN(xp_name); 4535 4536 if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt, 4537 &xp_arg) == FAIL) 4538 return; 4539 } 4540 } 4541 4542 if (defstr != NULL) 4543 { 4544 int save_ex_normal_busy = ex_normal_busy; 4545 int save_vgetc_busy = vgetc_busy; 4546 int save_input_busy = input_busy; 4547 4548 input_busy |= vgetc_busy; 4549 ex_normal_busy = 0; 4550 vgetc_busy = 0; 4551 rettv->vval.v_string = 4552 getcmdline_prompt(secret ? NUL : '@', p, get_echo_attr(), 4553 xp_type, xp_arg); 4554 ex_normal_busy = save_ex_normal_busy; 4555 vgetc_busy = save_vgetc_busy; 4556 input_busy = save_input_busy; 4557 } 4558 if (inputdialog && rettv->vval.v_string == NULL 4559 && argvars[1].v_type != VAR_UNKNOWN 4560 && argvars[2].v_type != VAR_UNKNOWN) 4561 rettv->vval.v_string = vim_strsave(tv_get_string_buf( 4562 &argvars[2], buf)); 4563 4564 vim_free(xp_arg); 4565 4566 // since the user typed this, no need to wait for return 4567 need_wait_return = FALSE; 4568 msg_didout = FALSE; 4569 } 4570 cmd_silent = cmd_silent_save; 4571 } 4572 #endif 4573