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 * edit.c: functions for Insert mode 12 */ 13 14 #include "vim.h" 15 16 #ifdef FEAT_INS_EXPAND 17 /* 18 * definitions used for CTRL-X submode 19 */ 20 # define CTRL_X_WANT_IDENT 0x100 21 22 # define CTRL_X_NORMAL 0 /* CTRL-N CTRL-P completion, default */ 23 # define CTRL_X_NOT_DEFINED_YET 1 24 # define CTRL_X_SCROLL 2 25 # define CTRL_X_WHOLE_LINE 3 26 # define CTRL_X_FILES 4 27 # define CTRL_X_TAGS (5 + CTRL_X_WANT_IDENT) 28 # define CTRL_X_PATH_PATTERNS (6 + CTRL_X_WANT_IDENT) 29 # define CTRL_X_PATH_DEFINES (7 + CTRL_X_WANT_IDENT) 30 # define CTRL_X_FINISHED 8 31 # define CTRL_X_DICTIONARY (9 + CTRL_X_WANT_IDENT) 32 # define CTRL_X_THESAURUS (10 + CTRL_X_WANT_IDENT) 33 # define CTRL_X_CMDLINE 11 34 # define CTRL_X_FUNCTION 12 35 # define CTRL_X_OMNI 13 36 # define CTRL_X_SPELL 14 37 # define CTRL_X_LOCAL_MSG 15 /* only used in "ctrl_x_msgs" */ 38 # define CTRL_X_EVAL 16 /* for builtin function complete() */ 39 40 # define CTRL_X_MSG(i) ctrl_x_msgs[(i) & ~CTRL_X_WANT_IDENT] 41 # define CTRL_X_MODE_LINE_OR_EVAL(m) ((m) == CTRL_X_WHOLE_LINE || (m) == CTRL_X_EVAL) 42 43 /* Message for CTRL-X mode, index is ctrl_x_mode. */ 44 static char *ctrl_x_msgs[] = 45 { 46 N_(" Keyword completion (^N^P)"), /* CTRL_X_NORMAL, ^P/^N compl. */ 47 N_(" ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"), 48 NULL, /* CTRL_X_SCROLL: depends on state */ 49 N_(" Whole line completion (^L^N^P)"), 50 N_(" File name completion (^F^N^P)"), 51 N_(" Tag completion (^]^N^P)"), 52 N_(" Path pattern completion (^N^P)"), 53 N_(" Definition completion (^D^N^P)"), 54 NULL, /* CTRL_X_FINISHED */ 55 N_(" Dictionary completion (^K^N^P)"), 56 N_(" Thesaurus completion (^T^N^P)"), 57 N_(" Command-line completion (^V^N^P)"), 58 N_(" User defined completion (^U^N^P)"), 59 N_(" Omni completion (^O^N^P)"), 60 N_(" Spelling suggestion (s^N^P)"), 61 N_(" Keyword Local completion (^N^P)"), 62 NULL, /* CTRL_X_EVAL doesn't use msg. */ 63 }; 64 65 static char e_hitend[] = N_("Hit end of paragraph"); 66 # ifdef FEAT_COMPL_FUNC 67 static char e_complwin[] = N_("E839: Completion function changed window"); 68 static char e_compldel[] = N_("E840: Completion function deleted text"); 69 # endif 70 71 /* 72 * Structure used to store one match for insert completion. 73 */ 74 typedef struct compl_S compl_T; 75 struct compl_S 76 { 77 compl_T *cp_next; 78 compl_T *cp_prev; 79 char_u *cp_str; /* matched text */ 80 char cp_icase; /* TRUE or FALSE: ignore case */ 81 char_u *(cp_text[CPT_COUNT]); /* text for the menu */ 82 char_u *cp_fname; /* file containing the match, allocated when 83 * cp_flags has FREE_FNAME */ 84 int cp_flags; /* ORIGINAL_TEXT, CONT_S_IPOS or FREE_FNAME */ 85 int cp_number; /* sequence number */ 86 }; 87 88 # define ORIGINAL_TEXT (1) /* the original text when the expansion begun */ 89 # define FREE_FNAME (2) 90 91 /* 92 * All the current matches are stored in a list. 93 * "compl_first_match" points to the start of the list. 94 * "compl_curr_match" points to the currently selected entry. 95 * "compl_shown_match" is different from compl_curr_match during 96 * ins_compl_get_exp(). 97 */ 98 static compl_T *compl_first_match = NULL; 99 static compl_T *compl_curr_match = NULL; 100 static compl_T *compl_shown_match = NULL; 101 static compl_T *compl_old_match = NULL; 102 103 /* After using a cursor key <Enter> selects a match in the popup menu, 104 * otherwise it inserts a line break. */ 105 static int compl_enter_selects = FALSE; 106 107 /* When "compl_leader" is not NULL only matches that start with this string 108 * are used. */ 109 static char_u *compl_leader = NULL; 110 111 static int compl_get_longest = FALSE; /* put longest common string 112 in compl_leader */ 113 114 static int compl_no_insert = FALSE; /* FALSE: select & insert 115 TRUE: noinsert */ 116 static int compl_no_select = FALSE; /* FALSE: select & insert 117 TRUE: noselect */ 118 119 static int compl_used_match; /* Selected one of the matches. When 120 FALSE the match was edited or using 121 the longest common string. */ 122 123 static int compl_was_interrupted = FALSE; /* didn't finish finding 124 completions. */ 125 126 static int compl_restarting = FALSE; /* don't insert match */ 127 128 /* When the first completion is done "compl_started" is set. When it's 129 * FALSE the word to be completed must be located. */ 130 static int compl_started = FALSE; 131 132 /* Which Ctrl-X mode are we in? */ 133 static int ctrl_x_mode = CTRL_X_NORMAL; 134 135 /* Set when doing something for completion that may call edit() recursively, 136 * which is not allowed. */ 137 static int compl_busy = FALSE; 138 139 static int compl_matches = 0; 140 static char_u *compl_pattern = NULL; 141 static int compl_direction = FORWARD; 142 static int compl_shows_dir = FORWARD; 143 static int compl_pending = 0; /* > 1 for postponed CTRL-N */ 144 static pos_T compl_startpos; 145 static colnr_T compl_col = 0; /* column where the text starts 146 * that is being completed */ 147 static char_u *compl_orig_text = NULL; /* text as it was before 148 * completion started */ 149 static int compl_cont_mode = 0; 150 static expand_T compl_xp; 151 152 static int compl_opt_refresh_always = FALSE; 153 static int compl_opt_suppress_empty = FALSE; 154 155 static void ins_ctrl_x(void); 156 static int has_compl_option(int dict_opt); 157 static int ins_compl_accept_char(int c); 158 static int ins_compl_add(char_u *str, int len, int icase, char_u *fname, char_u **cptext, int cdir, int flags, int adup); 159 static void ins_compl_longest_match(compl_T *match); 160 static void ins_compl_del_pum(void); 161 static int pum_wanted(void); 162 static void ins_compl_files(int count, char_u **files, int thesaurus, int flags, regmatch_T *regmatch, char_u *buf, int *dir); 163 static char_u *find_line_end(char_u *ptr); 164 static void ins_compl_free(void); 165 static void ins_compl_clear(void); 166 static int ins_compl_bs(void); 167 static int ins_compl_need_restart(void); 168 static void ins_compl_new_leader(void); 169 static void ins_compl_addleader(int c); 170 static int ins_compl_len(void); 171 static void ins_compl_restart(void); 172 static void ins_compl_set_original_text(char_u *str); 173 static void ins_compl_addfrommatch(void); 174 static int ins_compl_prep(int c); 175 static void ins_compl_fixRedoBufForLeader(char_u *ptr_arg); 176 # if defined(FEAT_COMPL_FUNC) || defined(FEAT_EVAL) 177 static void ins_compl_add_list(list_T *list); 178 static void ins_compl_add_dict(dict_T *dict); 179 # endif 180 static void ins_compl_delete(void); 181 static void ins_compl_insert(int in_compl_func); 182 static int ins_compl_key2dir(int c); 183 static int ins_compl_pum_key(int c); 184 static int ins_compl_key2count(int c); 185 static int ins_complete(int c, int enable_pum); 186 static void show_pum(int prev_w_wrow, int prev_w_leftcol); 187 static unsigned quote_meta(char_u *dest, char_u *str, int len); 188 #endif /* FEAT_INS_EXPAND */ 189 190 #define BACKSPACE_CHAR 1 191 #define BACKSPACE_WORD 2 192 #define BACKSPACE_WORD_NOT_SPACE 3 193 #define BACKSPACE_LINE 4 194 195 static void ins_redraw(int ready); 196 static void ins_ctrl_v(void); 197 #ifdef FEAT_JOB_CHANNEL 198 static void init_prompt(int cmdchar_todo); 199 #endif 200 static void undisplay_dollar(void); 201 static void insert_special(int, int, int); 202 static void internal_format(int textwidth, int second_indent, int flags, int format_only, int c); 203 static void check_auto_format(int); 204 static void redo_literal(int c); 205 static void start_arrow(pos_T *end_insert_pos); 206 static void start_arrow_common(pos_T *end_insert_pos, int change); 207 #ifdef FEAT_SPELL 208 static void check_spell_redraw(void); 209 static void spell_back_to_badword(void); 210 static int spell_bad_len = 0; /* length of located bad word */ 211 #endif 212 static void stop_insert(pos_T *end_insert_pos, int esc, int nomove); 213 static int echeck_abbr(int); 214 static void replace_join(int off); 215 static void mb_replace_pop_ins(int cc); 216 static void replace_flush(void); 217 static void replace_do_bs(int limit_col); 218 static int del_char_after_col(int limit_col); 219 static void ins_reg(void); 220 static void ins_ctrl_g(void); 221 static void ins_ctrl_hat(void); 222 static int ins_esc(long *count, int cmdchar, int nomove); 223 #ifdef FEAT_RIGHTLEFT 224 static void ins_ctrl_(void); 225 #endif 226 static int ins_start_select(int c); 227 static void ins_insert(int replaceState); 228 static void ins_ctrl_o(void); 229 static void ins_shift(int c, int lastc); 230 static void ins_del(void); 231 static int ins_bs(int c, int mode, int *inserted_space_p); 232 #ifdef FEAT_MOUSE 233 static void ins_mouse(int c); 234 static void ins_mousescroll(int dir); 235 #endif 236 #if defined(FEAT_GUI_TABLINE) || defined(PROTO) 237 static void ins_tabline(int c); 238 #endif 239 static void ins_left(int end_change); 240 static void ins_home(int c); 241 static void ins_end(int c); 242 static void ins_s_left(void); 243 static void ins_right(int end_change); 244 static void ins_s_right(void); 245 static void ins_up(int startcol); 246 static void ins_pageup(void); 247 static void ins_down(int startcol); 248 static void ins_pagedown(void); 249 #ifdef FEAT_DND 250 static void ins_drop(void); 251 #endif 252 static int ins_tab(void); 253 static int ins_eol(int c); 254 #ifdef FEAT_DIGRAPHS 255 static int ins_digraph(void); 256 #endif 257 static int ins_ctrl_ey(int tc); 258 #ifdef FEAT_SMARTINDENT 259 static void ins_try_si(int c); 260 #endif 261 #if defined(FEAT_EVAL) 262 static char_u *do_insert_char_pre(int c); 263 #endif 264 static int ins_apply_autocmds(event_T event); 265 266 static colnr_T Insstart_textlen; /* length of line when insert started */ 267 static colnr_T Insstart_blank_vcol; /* vcol for first inserted blank */ 268 static int update_Insstart_orig = TRUE; /* set Insstart_orig to Insstart */ 269 270 static char_u *last_insert = NULL; /* the text of the previous insert, 271 K_SPECIAL and CSI are escaped */ 272 static int last_insert_skip; /* nr of chars in front of previous insert */ 273 static int new_insert_skip; /* nr of chars in front of current insert */ 274 static int did_restart_edit; /* "restart_edit" when calling edit() */ 275 276 #ifdef FEAT_CINDENT 277 static int can_cindent; /* may do cindenting on this line */ 278 #endif 279 280 static int old_indent = 0; /* for ^^D command in insert mode */ 281 282 #ifdef FEAT_RIGHTLEFT 283 static int revins_on; /* reverse insert mode on */ 284 static int revins_chars; /* how much to skip after edit */ 285 static int revins_legal; /* was the last char 'legal'? */ 286 static int revins_scol; /* start column of revins session */ 287 #endif 288 289 static int ins_need_undo; /* call u_save() before inserting a 290 char. Set when edit() is called. 291 after that arrow_used is used. */ 292 293 static int did_add_space = FALSE; /* auto_format() added an extra space 294 under the cursor */ 295 static int dont_sync_undo = FALSE; /* CTRL-G U prevents syncing undo for 296 the next left/right cursor */ 297 298 /* 299 * edit(): Start inserting text. 300 * 301 * "cmdchar" can be: 302 * 'i' normal insert command 303 * 'a' normal append command 304 * K_PS bracketed paste 305 * 'R' replace command 306 * 'r' "r<CR>" command: insert one <CR>. Note: count can be > 1, for redo, 307 * but still only one <CR> is inserted. The <Esc> is not used for redo. 308 * 'g' "gI" command. 309 * 'V' "gR" command for Virtual Replace mode. 310 * 'v' "gr" command for single character Virtual Replace mode. 311 * 312 * This function is not called recursively. For CTRL-O commands, it returns 313 * and lets the caller handle the Normal-mode command. 314 * 315 * Return TRUE if a CTRL-O command caused the return (insert mode pending). 316 */ 317 int 318 edit( 319 int cmdchar, 320 int startln, /* if set, insert at start of line */ 321 long count) 322 { 323 int c = 0; 324 char_u *ptr; 325 int lastc = 0; 326 int mincol; 327 static linenr_T o_lnum = 0; 328 int i; 329 int did_backspace = TRUE; /* previous char was backspace */ 330 #ifdef FEAT_CINDENT 331 int line_is_white = FALSE; /* line is empty before insert */ 332 #endif 333 linenr_T old_topline = 0; /* topline before insertion */ 334 #ifdef FEAT_DIFF 335 int old_topfill = -1; 336 #endif 337 int inserted_space = FALSE; /* just inserted a space */ 338 int replaceState = REPLACE; 339 int nomove = FALSE; /* don't move cursor on return */ 340 #ifdef FEAT_JOB_CHANNEL 341 int cmdchar_todo = cmdchar; 342 #endif 343 344 /* Remember whether editing was restarted after CTRL-O. */ 345 did_restart_edit = restart_edit; 346 347 /* sleep before redrawing, needed for "CTRL-O :" that results in an 348 * error message */ 349 check_for_delay(TRUE); 350 351 /* set Insstart_orig to Insstart */ 352 update_Insstart_orig = TRUE; 353 354 #ifdef HAVE_SANDBOX 355 /* Don't allow inserting in the sandbox. */ 356 if (sandbox != 0) 357 { 358 emsg(_(e_sandbox)); 359 return FALSE; 360 } 361 #endif 362 /* Don't allow changes in the buffer while editing the cmdline. The 363 * caller of getcmdline() may get confused. */ 364 if (textlock != 0) 365 { 366 emsg(_(e_secure)); 367 return FALSE; 368 } 369 370 #ifdef FEAT_INS_EXPAND 371 /* Don't allow recursive insert mode when busy with completion. */ 372 if (compl_started || compl_busy || pum_visible()) 373 { 374 emsg(_(e_secure)); 375 return FALSE; 376 } 377 ins_compl_clear(); /* clear stuff for CTRL-X mode */ 378 #endif 379 380 /* 381 * Trigger InsertEnter autocommands. Do not do this for "r<CR>" or "grx". 382 */ 383 if (cmdchar != 'r' && cmdchar != 'v') 384 { 385 pos_T save_cursor = curwin->w_cursor; 386 387 #ifdef FEAT_EVAL 388 if (cmdchar == 'R') 389 ptr = (char_u *)"r"; 390 else if (cmdchar == 'V') 391 ptr = (char_u *)"v"; 392 else 393 ptr = (char_u *)"i"; 394 set_vim_var_string(VV_INSERTMODE, ptr, 1); 395 set_vim_var_string(VV_CHAR, NULL, -1); /* clear v:char */ 396 #endif 397 ins_apply_autocmds(EVENT_INSERTENTER); 398 399 /* Make sure the cursor didn't move. Do call check_cursor_col() in 400 * case the text was modified. Since Insert mode was not started yet 401 * a call to check_cursor_col() may move the cursor, especially with 402 * the "A" command, thus set State to avoid that. Also check that the 403 * line number is still valid (lines may have been deleted). 404 * Do not restore if v:char was set to a non-empty string. */ 405 if (!EQUAL_POS(curwin->w_cursor, save_cursor) 406 #ifdef FEAT_EVAL 407 && *get_vim_var_str(VV_CHAR) == NUL 408 #endif 409 && save_cursor.lnum <= curbuf->b_ml.ml_line_count) 410 { 411 int save_state = State; 412 413 curwin->w_cursor = save_cursor; 414 State = INSERT; 415 check_cursor_col(); 416 State = save_state; 417 } 418 } 419 420 #ifdef FEAT_CONCEAL 421 /* Check if the cursor line needs redrawing before changing State. If 422 * 'concealcursor' is "n" it needs to be redrawn without concealing. */ 423 conceal_check_cursor_line(); 424 #endif 425 426 #ifdef FEAT_MOUSE 427 /* 428 * When doing a paste with the middle mouse button, Insstart is set to 429 * where the paste started. 430 */ 431 if (where_paste_started.lnum != 0) 432 Insstart = where_paste_started; 433 else 434 #endif 435 { 436 Insstart = curwin->w_cursor; 437 if (startln) 438 Insstart.col = 0; 439 } 440 Insstart_textlen = (colnr_T)linetabsize(ml_get_curline()); 441 Insstart_blank_vcol = MAXCOL; 442 if (!did_ai) 443 ai_col = 0; 444 445 if (cmdchar != NUL && restart_edit == 0) 446 { 447 ResetRedobuff(); 448 AppendNumberToRedobuff(count); 449 if (cmdchar == 'V' || cmdchar == 'v') 450 { 451 /* "gR" or "gr" command */ 452 AppendCharToRedobuff('g'); 453 AppendCharToRedobuff((cmdchar == 'v') ? 'r' : 'R'); 454 } 455 else 456 { 457 if (cmdchar == K_PS) 458 AppendCharToRedobuff('a'); 459 else 460 AppendCharToRedobuff(cmdchar); 461 if (cmdchar == 'g') /* "gI" command */ 462 AppendCharToRedobuff('I'); 463 else if (cmdchar == 'r') /* "r<CR>" command */ 464 count = 1; /* insert only one <CR> */ 465 } 466 } 467 468 if (cmdchar == 'R') 469 { 470 State = REPLACE; 471 } 472 else if (cmdchar == 'V' || cmdchar == 'v') 473 { 474 State = VREPLACE; 475 replaceState = VREPLACE; 476 orig_line_count = curbuf->b_ml.ml_line_count; 477 vr_lines_changed = 1; 478 } 479 else 480 State = INSERT; 481 482 stop_insert_mode = FALSE; 483 484 /* 485 * Need to recompute the cursor position, it might move when the cursor is 486 * on a TAB or special character. 487 */ 488 curs_columns(TRUE); 489 490 /* 491 * Enable langmap or IME, indicated by 'iminsert'. 492 * Note that IME may enabled/disabled without us noticing here, thus the 493 * 'iminsert' value may not reflect what is actually used. It is updated 494 * when hitting <Esc>. 495 */ 496 if (curbuf->b_p_iminsert == B_IMODE_LMAP) 497 State |= LANGMAP; 498 #ifdef HAVE_INPUT_METHOD 499 im_set_active(curbuf->b_p_iminsert == B_IMODE_IM); 500 #endif 501 502 #ifdef FEAT_MOUSE 503 setmouse(); 504 #endif 505 #ifdef FEAT_CMDL_INFO 506 clear_showcmd(); 507 #endif 508 #ifdef FEAT_RIGHTLEFT 509 /* there is no reverse replace mode */ 510 revins_on = (State == INSERT && p_ri); 511 if (revins_on) 512 undisplay_dollar(); 513 revins_chars = 0; 514 revins_legal = 0; 515 revins_scol = -1; 516 #endif 517 if (!p_ek) 518 /* Disable bracketed paste mode, we won't recognize the escape 519 * sequences. */ 520 out_str(T_BD); 521 522 /* 523 * Handle restarting Insert mode. 524 * Don't do this for "CTRL-O ." (repeat an insert): In that case we get 525 * here with something in the stuff buffer. 526 */ 527 if (restart_edit != 0 && stuff_empty()) 528 { 529 #ifdef FEAT_MOUSE 530 /* 531 * After a paste we consider text typed to be part of the insert for 532 * the pasted text. You can backspace over the pasted text too. 533 */ 534 if (where_paste_started.lnum) 535 arrow_used = FALSE; 536 else 537 #endif 538 arrow_used = TRUE; 539 restart_edit = 0; 540 541 /* 542 * If the cursor was after the end-of-line before the CTRL-O and it is 543 * now at the end-of-line, put it after the end-of-line (this is not 544 * correct in very rare cases). 545 * Also do this if curswant is greater than the current virtual 546 * column. Eg after "^O$" or "^O80|". 547 */ 548 validate_virtcol(); 549 update_curswant(); 550 if (((ins_at_eol && curwin->w_cursor.lnum == o_lnum) 551 || curwin->w_curswant > curwin->w_virtcol) 552 && *(ptr = ml_get_curline() + curwin->w_cursor.col) != NUL) 553 { 554 if (ptr[1] == NUL) 555 ++curwin->w_cursor.col; 556 else if (has_mbyte) 557 { 558 i = (*mb_ptr2len)(ptr); 559 if (ptr[i] == NUL) 560 curwin->w_cursor.col += i; 561 } 562 } 563 ins_at_eol = FALSE; 564 } 565 else 566 arrow_used = FALSE; 567 568 /* we are in insert mode now, don't need to start it anymore */ 569 need_start_insertmode = FALSE; 570 571 /* Need to save the line for undo before inserting the first char. */ 572 ins_need_undo = TRUE; 573 574 #ifdef FEAT_MOUSE 575 where_paste_started.lnum = 0; 576 #endif 577 #ifdef FEAT_CINDENT 578 can_cindent = TRUE; 579 #endif 580 #ifdef FEAT_FOLDING 581 /* The cursor line is not in a closed fold, unless 'insertmode' is set or 582 * restarting. */ 583 if (!p_im && did_restart_edit == 0) 584 foldOpenCursor(); 585 #endif 586 587 /* 588 * If 'showmode' is set, show the current (insert/replace/..) mode. 589 * A warning message for changing a readonly file is given here, before 590 * actually changing anything. It's put after the mode, if any. 591 */ 592 i = 0; 593 if (p_smd && msg_silent == 0) 594 i = showmode(); 595 596 if (!p_im && did_restart_edit == 0) 597 change_warning(i == 0 ? 0 : i + 1); 598 599 #ifdef CURSOR_SHAPE 600 ui_cursor_shape(); /* may show different cursor shape */ 601 #endif 602 #ifdef FEAT_DIGRAPHS 603 do_digraph(-1); /* clear digraphs */ 604 #endif 605 606 /* 607 * Get the current length of the redo buffer, those characters have to be 608 * skipped if we want to get to the inserted characters. 609 */ 610 ptr = get_inserted(); 611 if (ptr == NULL) 612 new_insert_skip = 0; 613 else 614 { 615 new_insert_skip = (int)STRLEN(ptr); 616 vim_free(ptr); 617 } 618 619 old_indent = 0; 620 621 /* 622 * Main loop in Insert mode: repeat until Insert mode is left. 623 */ 624 for (;;) 625 { 626 #ifdef FEAT_RIGHTLEFT 627 if (!revins_legal) 628 revins_scol = -1; /* reset on illegal motions */ 629 else 630 revins_legal = 0; 631 #endif 632 if (arrow_used) /* don't repeat insert when arrow key used */ 633 count = 0; 634 635 if (update_Insstart_orig) 636 Insstart_orig = Insstart; 637 638 if (stop_insert_mode 639 #ifdef FEAT_INS_EXPAND 640 && !pum_visible() 641 #endif 642 ) 643 { 644 /* ":stopinsert" used or 'insertmode' reset */ 645 count = 0; 646 goto doESCkey; 647 } 648 649 /* set curwin->w_curswant for next K_DOWN or K_UP */ 650 if (!arrow_used) 651 curwin->w_set_curswant = TRUE; 652 653 /* If there is no typeahead may check for timestamps (e.g., for when a 654 * menu invoked a shell command). */ 655 if (stuff_empty()) 656 { 657 did_check_timestamps = FALSE; 658 if (need_check_timestamps) 659 check_timestamps(FALSE); 660 } 661 662 /* 663 * When emsg() was called msg_scroll will have been set. 664 */ 665 msg_scroll = FALSE; 666 667 #ifdef FEAT_GUI 668 /* When 'mousefocus' is set a mouse movement may have taken us to 669 * another window. "need_mouse_correct" may then be set because of an 670 * autocommand. */ 671 if (need_mouse_correct) 672 gui_mouse_correct(); 673 #endif 674 675 #ifdef FEAT_FOLDING 676 /* Open fold at the cursor line, according to 'foldopen'. */ 677 if (fdo_flags & FDO_INSERT) 678 foldOpenCursor(); 679 /* Close folds where the cursor isn't, according to 'foldclose' */ 680 if (!char_avail()) 681 foldCheckClose(); 682 #endif 683 684 #ifdef FEAT_JOB_CHANNEL 685 if (bt_prompt(curbuf)) 686 { 687 init_prompt(cmdchar_todo); 688 cmdchar_todo = NUL; 689 } 690 #endif 691 692 /* 693 * If we inserted a character at the last position of the last line in 694 * the window, scroll the window one line up. This avoids an extra 695 * redraw. 696 * This is detected when the cursor column is smaller after inserting 697 * something. 698 * Don't do this when the topline changed already, it has 699 * already been adjusted (by insertchar() calling open_line())). 700 */ 701 if (curbuf->b_mod_set 702 && curwin->w_p_wrap 703 && !did_backspace 704 && curwin->w_topline == old_topline 705 #ifdef FEAT_DIFF 706 && curwin->w_topfill == old_topfill 707 #endif 708 ) 709 { 710 mincol = curwin->w_wcol; 711 validate_cursor_col(); 712 713 if ( 714 #ifdef FEAT_VARTABS 715 (int)curwin->w_wcol < mincol - tabstop_at( 716 get_nolist_virtcol(), curbuf->b_p_ts, 717 curbuf->b_p_vts_array) 718 #else 719 (int)curwin->w_wcol < mincol - curbuf->b_p_ts 720 #endif 721 && curwin->w_wrow == W_WINROW(curwin) 722 + curwin->w_height - 1 - get_scrolloff_value() 723 && (curwin->w_cursor.lnum != curwin->w_topline 724 #ifdef FEAT_DIFF 725 || curwin->w_topfill > 0 726 #endif 727 )) 728 { 729 #ifdef FEAT_DIFF 730 if (curwin->w_topfill > 0) 731 --curwin->w_topfill; 732 else 733 #endif 734 #ifdef FEAT_FOLDING 735 if (hasFolding(curwin->w_topline, NULL, &old_topline)) 736 set_topline(curwin, old_topline + 1); 737 else 738 #endif 739 set_topline(curwin, curwin->w_topline + 1); 740 } 741 } 742 743 /* May need to adjust w_topline to show the cursor. */ 744 update_topline(); 745 746 did_backspace = FALSE; 747 748 validate_cursor(); /* may set must_redraw */ 749 750 /* 751 * Redraw the display when no characters are waiting. 752 * Also shows mode, ruler and positions cursor. 753 */ 754 ins_redraw(TRUE); 755 756 if (curwin->w_p_scb) 757 do_check_scrollbind(TRUE); 758 759 if (curwin->w_p_crb) 760 do_check_cursorbind(); 761 update_curswant(); 762 old_topline = curwin->w_topline; 763 #ifdef FEAT_DIFF 764 old_topfill = curwin->w_topfill; 765 #endif 766 767 #ifdef USE_ON_FLY_SCROLL 768 dont_scroll = FALSE; /* allow scrolling here */ 769 #endif 770 771 /* 772 * Get a character for Insert mode. Ignore K_IGNORE and K_NOP. 773 */ 774 if (c != K_CURSORHOLD) 775 lastc = c; /* remember the previous char for CTRL-D */ 776 777 /* After using CTRL-G U the next cursor key will not break undo. */ 778 if (dont_sync_undo == MAYBE) 779 dont_sync_undo = TRUE; 780 else 781 dont_sync_undo = FALSE; 782 if (cmdchar == K_PS) 783 /* Got here from normal mode when bracketed paste started. */ 784 c = K_PS; 785 else 786 do 787 { 788 c = safe_vgetc(); 789 790 if (stop_insert_mode) 791 { 792 // Insert mode ended, possibly from a callback. 793 count = 0; 794 nomove = TRUE; 795 goto doESCkey; 796 } 797 } while (c == K_IGNORE || c == K_NOP); 798 799 /* Don't want K_CURSORHOLD for the second key, e.g., after CTRL-V. */ 800 did_cursorhold = TRUE; 801 802 #ifdef FEAT_RIGHTLEFT 803 if (p_hkmap && KeyTyped) 804 c = hkmap(c); /* Hebrew mode mapping */ 805 #endif 806 807 #ifdef FEAT_INS_EXPAND 808 /* 809 * Special handling of keys while the popup menu is visible or wanted 810 * and the cursor is still in the completed word. Only when there is 811 * a match, skip this when no matches were found. 812 */ 813 if (compl_started 814 && pum_wanted() 815 && curwin->w_cursor.col >= compl_col 816 && (compl_shown_match == NULL 817 || compl_shown_match != compl_shown_match->cp_next)) 818 { 819 /* BS: Delete one character from "compl_leader". */ 820 if ((c == K_BS || c == Ctrl_H) 821 && curwin->w_cursor.col > compl_col 822 && (c = ins_compl_bs()) == NUL) 823 continue; 824 825 /* When no match was selected or it was edited. */ 826 if (!compl_used_match) 827 { 828 /* CTRL-L: Add one character from the current match to 829 * "compl_leader". Except when at the original match and 830 * there is nothing to add, CTRL-L works like CTRL-P then. */ 831 if (c == Ctrl_L 832 && (!CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode) 833 || (int)STRLEN(compl_shown_match->cp_str) 834 > curwin->w_cursor.col - compl_col)) 835 { 836 ins_compl_addfrommatch(); 837 continue; 838 } 839 840 /* A non-white character that fits in with the current 841 * completion: Add to "compl_leader". */ 842 if (ins_compl_accept_char(c)) 843 { 844 #if defined(FEAT_EVAL) 845 /* Trigger InsertCharPre. */ 846 char_u *str = do_insert_char_pre(c); 847 char_u *p; 848 849 if (str != NULL) 850 { 851 for (p = str; *p != NUL; MB_PTR_ADV(p)) 852 ins_compl_addleader(PTR2CHAR(p)); 853 vim_free(str); 854 } 855 else 856 #endif 857 ins_compl_addleader(c); 858 continue; 859 } 860 861 /* Pressing CTRL-Y selects the current match. When 862 * compl_enter_selects is set the Enter key does the same. */ 863 if ((c == Ctrl_Y || (compl_enter_selects 864 && (c == CAR || c == K_KENTER || c == NL))) 865 && stop_arrow() == OK) 866 { 867 ins_compl_delete(); 868 ins_compl_insert(FALSE); 869 } 870 } 871 } 872 873 /* Prepare for or stop CTRL-X mode. This doesn't do completion, but 874 * it does fix up the text when finishing completion. */ 875 compl_get_longest = FALSE; 876 if (ins_compl_prep(c)) 877 continue; 878 #endif 879 880 /* CTRL-\ CTRL-N goes to Normal mode, 881 * CTRL-\ CTRL-G goes to mode selected with 'insertmode', 882 * CTRL-\ CTRL-O is like CTRL-O but without moving the cursor. */ 883 if (c == Ctrl_BSL) 884 { 885 /* may need to redraw when no more chars available now */ 886 ins_redraw(FALSE); 887 ++no_mapping; 888 ++allow_keys; 889 c = plain_vgetc(); 890 --no_mapping; 891 --allow_keys; 892 if (c != Ctrl_N && c != Ctrl_G && c != Ctrl_O) 893 { 894 /* it's something else */ 895 vungetc(c); 896 c = Ctrl_BSL; 897 } 898 else if (c == Ctrl_G && p_im) 899 continue; 900 else 901 { 902 if (c == Ctrl_O) 903 { 904 ins_ctrl_o(); 905 ins_at_eol = FALSE; /* cursor keeps its column */ 906 nomove = TRUE; 907 } 908 count = 0; 909 goto doESCkey; 910 } 911 } 912 913 #ifdef FEAT_DIGRAPHS 914 c = do_digraph(c); 915 #endif 916 917 #ifdef FEAT_INS_EXPAND 918 if ((c == Ctrl_V || c == Ctrl_Q) && ctrl_x_mode == CTRL_X_CMDLINE) 919 goto docomplete; 920 #endif 921 if (c == Ctrl_V || c == Ctrl_Q) 922 { 923 ins_ctrl_v(); 924 c = Ctrl_V; /* pretend CTRL-V is last typed character */ 925 continue; 926 } 927 928 #ifdef FEAT_CINDENT 929 if (cindent_on() 930 # ifdef FEAT_INS_EXPAND 931 && ctrl_x_mode == 0 932 # endif 933 ) 934 { 935 /* A key name preceded by a bang means this key is not to be 936 * inserted. Skip ahead to the re-indenting below. 937 * A key name preceded by a star means that indenting has to be 938 * done before inserting the key. */ 939 line_is_white = inindent(0); 940 if (in_cinkeys(c, '!', line_is_white)) 941 goto force_cindent; 942 if (can_cindent && in_cinkeys(c, '*', line_is_white) 943 && stop_arrow() == OK) 944 do_c_expr_indent(); 945 } 946 #endif 947 948 #ifdef FEAT_RIGHTLEFT 949 if (curwin->w_p_rl) 950 switch (c) 951 { 952 case K_LEFT: c = K_RIGHT; break; 953 case K_S_LEFT: c = K_S_RIGHT; break; 954 case K_C_LEFT: c = K_C_RIGHT; break; 955 case K_RIGHT: c = K_LEFT; break; 956 case K_S_RIGHT: c = K_S_LEFT; break; 957 case K_C_RIGHT: c = K_C_LEFT; break; 958 } 959 #endif 960 961 /* 962 * If 'keymodel' contains "startsel", may start selection. If it 963 * does, a CTRL-O and c will be stuffed, we need to get these 964 * characters. 965 */ 966 if (ins_start_select(c)) 967 continue; 968 969 /* 970 * The big switch to handle a character in insert mode. 971 */ 972 switch (c) 973 { 974 case ESC: /* End input mode */ 975 if (echeck_abbr(ESC + ABBR_OFF)) 976 break; 977 /* FALLTHROUGH */ 978 979 case Ctrl_C: /* End input mode */ 980 #ifdef FEAT_CMDWIN 981 if (c == Ctrl_C && cmdwin_type != 0) 982 { 983 /* Close the cmdline window. */ 984 cmdwin_result = K_IGNORE; 985 got_int = FALSE; /* don't stop executing autocommands et al. */ 986 nomove = TRUE; 987 goto doESCkey; 988 } 989 #endif 990 #ifdef FEAT_JOB_CHANNEL 991 if (c == Ctrl_C && bt_prompt(curbuf)) 992 { 993 if (invoke_prompt_interrupt()) 994 { 995 if (!bt_prompt(curbuf)) 996 // buffer changed to a non-prompt buffer, get out of 997 // Insert mode 998 goto doESCkey; 999 break; 1000 } 1001 } 1002 #endif 1003 1004 #ifdef UNIX 1005 do_intr: 1006 #endif 1007 /* when 'insertmode' set, and not halfway a mapping, don't leave 1008 * Insert mode */ 1009 if (goto_im()) 1010 { 1011 if (got_int) 1012 { 1013 (void)vgetc(); /* flush all buffers */ 1014 got_int = FALSE; 1015 } 1016 else 1017 vim_beep(BO_IM); 1018 break; 1019 } 1020 doESCkey: 1021 /* 1022 * This is the ONLY return from edit()! 1023 */ 1024 /* Always update o_lnum, so that a "CTRL-O ." that adds a line 1025 * still puts the cursor back after the inserted text. */ 1026 if (ins_at_eol && gchar_cursor() == NUL) 1027 o_lnum = curwin->w_cursor.lnum; 1028 1029 if (ins_esc(&count, cmdchar, nomove)) 1030 { 1031 // When CTRL-C was typed got_int will be set, with the result 1032 // that the autocommands won't be executed. When mapped got_int 1033 // is not set, but let's keep the behavior the same. 1034 if (cmdchar != 'r' && cmdchar != 'v' && c != Ctrl_C) 1035 ins_apply_autocmds(EVENT_INSERTLEAVE); 1036 did_cursorhold = FALSE; 1037 return (c == Ctrl_O); 1038 } 1039 continue; 1040 1041 case Ctrl_Z: /* suspend when 'insertmode' set */ 1042 if (!p_im) 1043 goto normalchar; /* insert CTRL-Z as normal char */ 1044 do_cmdline_cmd((char_u *)"stop"); 1045 #ifdef CURSOR_SHAPE 1046 ui_cursor_shape(); /* may need to update cursor shape */ 1047 #endif 1048 continue; 1049 1050 case Ctrl_O: /* execute one command */ 1051 #ifdef FEAT_COMPL_FUNC 1052 if (ctrl_x_mode == CTRL_X_OMNI) 1053 goto docomplete; 1054 #endif 1055 if (echeck_abbr(Ctrl_O + ABBR_OFF)) 1056 break; 1057 ins_ctrl_o(); 1058 1059 /* don't move the cursor left when 'virtualedit' has "onemore". */ 1060 if (ve_flags & VE_ONEMORE) 1061 { 1062 ins_at_eol = FALSE; 1063 nomove = TRUE; 1064 } 1065 count = 0; 1066 goto doESCkey; 1067 1068 case K_INS: /* toggle insert/replace mode */ 1069 case K_KINS: 1070 ins_insert(replaceState); 1071 break; 1072 1073 case K_SELECT: /* end of Select mode mapping - ignore */ 1074 break; 1075 1076 case K_HELP: /* Help key works like <ESC> <Help> */ 1077 case K_F1: 1078 case K_XF1: 1079 stuffcharReadbuff(K_HELP); 1080 if (p_im) 1081 need_start_insertmode = TRUE; 1082 goto doESCkey; 1083 1084 #ifdef FEAT_NETBEANS_INTG 1085 case K_F21: /* NetBeans command */ 1086 ++no_mapping; /* don't map the next key hits */ 1087 i = plain_vgetc(); 1088 --no_mapping; 1089 netbeans_keycommand(i); 1090 break; 1091 #endif 1092 1093 case K_ZERO: /* Insert the previously inserted text. */ 1094 case NUL: 1095 case Ctrl_A: 1096 /* For ^@ the trailing ESC will end the insert, unless there is an 1097 * error. */ 1098 if (stuff_inserted(NUL, 1L, (c == Ctrl_A)) == FAIL 1099 && c != Ctrl_A && !p_im) 1100 goto doESCkey; /* quit insert mode */ 1101 inserted_space = FALSE; 1102 break; 1103 1104 case Ctrl_R: /* insert the contents of a register */ 1105 ins_reg(); 1106 auto_format(FALSE, TRUE); 1107 inserted_space = FALSE; 1108 break; 1109 1110 case Ctrl_G: /* commands starting with CTRL-G */ 1111 ins_ctrl_g(); 1112 break; 1113 1114 case Ctrl_HAT: /* switch input mode and/or langmap */ 1115 ins_ctrl_hat(); 1116 break; 1117 1118 #ifdef FEAT_RIGHTLEFT 1119 case Ctrl__: /* switch between languages */ 1120 if (!p_ari) 1121 goto normalchar; 1122 ins_ctrl_(); 1123 break; 1124 #endif 1125 1126 case Ctrl_D: /* Make indent one shiftwidth smaller. */ 1127 #if defined(FEAT_INS_EXPAND) && defined(FEAT_FIND_ID) 1128 if (ctrl_x_mode == CTRL_X_PATH_DEFINES) 1129 goto docomplete; 1130 #endif 1131 /* FALLTHROUGH */ 1132 1133 case Ctrl_T: /* Make indent one shiftwidth greater. */ 1134 # ifdef FEAT_INS_EXPAND 1135 if (c == Ctrl_T && ctrl_x_mode == CTRL_X_THESAURUS) 1136 { 1137 if (has_compl_option(FALSE)) 1138 goto docomplete; 1139 break; 1140 } 1141 # endif 1142 ins_shift(c, lastc); 1143 auto_format(FALSE, TRUE); 1144 inserted_space = FALSE; 1145 break; 1146 1147 case K_DEL: /* delete character under the cursor */ 1148 case K_KDEL: 1149 ins_del(); 1150 auto_format(FALSE, TRUE); 1151 break; 1152 1153 case K_BS: /* delete character before the cursor */ 1154 case Ctrl_H: 1155 did_backspace = ins_bs(c, BACKSPACE_CHAR, &inserted_space); 1156 auto_format(FALSE, TRUE); 1157 break; 1158 1159 case Ctrl_W: /* delete word before the cursor */ 1160 #ifdef FEAT_JOB_CHANNEL 1161 if (bt_prompt(curbuf) && (mod_mask & MOD_MASK_SHIFT) == 0) 1162 { 1163 // In a prompt window CTRL-W is used for window commands. 1164 // Use Shift-CTRL-W to delete a word. 1165 stuffcharReadbuff(Ctrl_W); 1166 restart_edit = 'A'; 1167 nomove = TRUE; 1168 count = 0; 1169 goto doESCkey; 1170 } 1171 #endif 1172 did_backspace = ins_bs(c, BACKSPACE_WORD, &inserted_space); 1173 auto_format(FALSE, TRUE); 1174 break; 1175 1176 case Ctrl_U: /* delete all inserted text in current line */ 1177 # ifdef FEAT_COMPL_FUNC 1178 /* CTRL-X CTRL-U completes with 'completefunc'. */ 1179 if (ctrl_x_mode == CTRL_X_FUNCTION) 1180 goto docomplete; 1181 # endif 1182 did_backspace = ins_bs(c, BACKSPACE_LINE, &inserted_space); 1183 auto_format(FALSE, TRUE); 1184 inserted_space = FALSE; 1185 break; 1186 1187 #ifdef FEAT_MOUSE 1188 case K_LEFTMOUSE: /* mouse keys */ 1189 case K_LEFTMOUSE_NM: 1190 case K_LEFTDRAG: 1191 case K_LEFTRELEASE: 1192 case K_LEFTRELEASE_NM: 1193 case K_MOUSEMOVE: 1194 case K_MIDDLEMOUSE: 1195 case K_MIDDLEDRAG: 1196 case K_MIDDLERELEASE: 1197 case K_RIGHTMOUSE: 1198 case K_RIGHTDRAG: 1199 case K_RIGHTRELEASE: 1200 case K_X1MOUSE: 1201 case K_X1DRAG: 1202 case K_X1RELEASE: 1203 case K_X2MOUSE: 1204 case K_X2DRAG: 1205 case K_X2RELEASE: 1206 ins_mouse(c); 1207 break; 1208 1209 case K_MOUSEDOWN: /* Default action for scroll wheel up: scroll up */ 1210 ins_mousescroll(MSCR_DOWN); 1211 break; 1212 1213 case K_MOUSEUP: /* Default action for scroll wheel down: scroll down */ 1214 ins_mousescroll(MSCR_UP); 1215 break; 1216 1217 case K_MOUSELEFT: /* Scroll wheel left */ 1218 ins_mousescroll(MSCR_LEFT); 1219 break; 1220 1221 case K_MOUSERIGHT: /* Scroll wheel right */ 1222 ins_mousescroll(MSCR_RIGHT); 1223 break; 1224 #endif 1225 case K_PS: 1226 bracketed_paste(PASTE_INSERT, FALSE, NULL); 1227 if (cmdchar == K_PS) 1228 /* invoked from normal mode, bail out */ 1229 goto doESCkey; 1230 break; 1231 case K_PE: 1232 /* Got K_PE without K_PS, ignore. */ 1233 break; 1234 1235 #ifdef FEAT_GUI_TABLINE 1236 case K_TABLINE: 1237 case K_TABMENU: 1238 ins_tabline(c); 1239 break; 1240 #endif 1241 1242 case K_IGNORE: /* Something mapped to nothing */ 1243 break; 1244 1245 case K_CURSORHOLD: /* Didn't type something for a while. */ 1246 ins_apply_autocmds(EVENT_CURSORHOLDI); 1247 did_cursorhold = TRUE; 1248 break; 1249 1250 #ifdef FEAT_GUI_MSWIN 1251 /* On MS-Windows ignore <M-F4>, we get it when closing the window 1252 * was cancelled. */ 1253 case K_F4: 1254 if (mod_mask != MOD_MASK_ALT) 1255 goto normalchar; 1256 break; 1257 #endif 1258 1259 #ifdef FEAT_GUI 1260 case K_VER_SCROLLBAR: 1261 ins_scroll(); 1262 break; 1263 1264 case K_HOR_SCROLLBAR: 1265 ins_horscroll(); 1266 break; 1267 #endif 1268 1269 case K_HOME: /* <Home> */ 1270 case K_KHOME: 1271 case K_S_HOME: 1272 case K_C_HOME: 1273 ins_home(c); 1274 break; 1275 1276 case K_END: /* <End> */ 1277 case K_KEND: 1278 case K_S_END: 1279 case K_C_END: 1280 ins_end(c); 1281 break; 1282 1283 case K_LEFT: /* <Left> */ 1284 if (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)) 1285 ins_s_left(); 1286 else 1287 ins_left(dont_sync_undo == FALSE); 1288 break; 1289 1290 case K_S_LEFT: /* <S-Left> */ 1291 case K_C_LEFT: 1292 ins_s_left(); 1293 break; 1294 1295 case K_RIGHT: /* <Right> */ 1296 if (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)) 1297 ins_s_right(); 1298 else 1299 ins_right(dont_sync_undo == FALSE); 1300 break; 1301 1302 case K_S_RIGHT: /* <S-Right> */ 1303 case K_C_RIGHT: 1304 ins_s_right(); 1305 break; 1306 1307 case K_UP: /* <Up> */ 1308 #ifdef FEAT_INS_EXPAND 1309 if (pum_visible()) 1310 goto docomplete; 1311 #endif 1312 if (mod_mask & MOD_MASK_SHIFT) 1313 ins_pageup(); 1314 else 1315 ins_up(FALSE); 1316 break; 1317 1318 case K_S_UP: /* <S-Up> */ 1319 case K_PAGEUP: 1320 case K_KPAGEUP: 1321 #ifdef FEAT_INS_EXPAND 1322 if (pum_visible()) 1323 goto docomplete; 1324 #endif 1325 ins_pageup(); 1326 break; 1327 1328 case K_DOWN: /* <Down> */ 1329 #ifdef FEAT_INS_EXPAND 1330 if (pum_visible()) 1331 goto docomplete; 1332 #endif 1333 if (mod_mask & MOD_MASK_SHIFT) 1334 ins_pagedown(); 1335 else 1336 ins_down(FALSE); 1337 break; 1338 1339 case K_S_DOWN: /* <S-Down> */ 1340 case K_PAGEDOWN: 1341 case K_KPAGEDOWN: 1342 #ifdef FEAT_INS_EXPAND 1343 if (pum_visible()) 1344 goto docomplete; 1345 #endif 1346 ins_pagedown(); 1347 break; 1348 1349 #ifdef FEAT_DND 1350 case K_DROP: /* drag-n-drop event */ 1351 ins_drop(); 1352 break; 1353 #endif 1354 1355 case K_S_TAB: /* When not mapped, use like a normal TAB */ 1356 c = TAB; 1357 /* FALLTHROUGH */ 1358 1359 case TAB: /* TAB or Complete patterns along path */ 1360 #if defined(FEAT_INS_EXPAND) && defined(FEAT_FIND_ID) 1361 if (ctrl_x_mode == CTRL_X_PATH_PATTERNS) 1362 goto docomplete; 1363 #endif 1364 inserted_space = FALSE; 1365 if (ins_tab()) 1366 goto normalchar; /* insert TAB as a normal char */ 1367 auto_format(FALSE, TRUE); 1368 break; 1369 1370 case K_KENTER: /* <Enter> */ 1371 c = CAR; 1372 /* FALLTHROUGH */ 1373 case CAR: 1374 case NL: 1375 #if defined(FEAT_QUICKFIX) 1376 /* In a quickfix window a <CR> jumps to the error under the 1377 * cursor. */ 1378 if (bt_quickfix(curbuf) && c == CAR) 1379 { 1380 if (curwin->w_llist_ref == NULL) /* quickfix window */ 1381 do_cmdline_cmd((char_u *)".cc"); 1382 else /* location list window */ 1383 do_cmdline_cmd((char_u *)".ll"); 1384 break; 1385 } 1386 #endif 1387 #ifdef FEAT_CMDWIN 1388 if (cmdwin_type != 0) 1389 { 1390 /* Execute the command in the cmdline window. */ 1391 cmdwin_result = CAR; 1392 goto doESCkey; 1393 } 1394 #endif 1395 #ifdef FEAT_JOB_CHANNEL 1396 if (bt_prompt(curbuf)) 1397 { 1398 invoke_prompt_callback(); 1399 if (!bt_prompt(curbuf)) 1400 // buffer changed to a non-prompt buffer, get out of 1401 // Insert mode 1402 goto doESCkey; 1403 break; 1404 } 1405 #endif 1406 if (ins_eol(c) == FAIL && !p_im) 1407 goto doESCkey; /* out of memory */ 1408 auto_format(FALSE, FALSE); 1409 inserted_space = FALSE; 1410 break; 1411 1412 #if defined(FEAT_DIGRAPHS) || defined(FEAT_INS_EXPAND) 1413 case Ctrl_K: /* digraph or keyword completion */ 1414 # ifdef FEAT_INS_EXPAND 1415 if (ctrl_x_mode == CTRL_X_DICTIONARY) 1416 { 1417 if (has_compl_option(TRUE)) 1418 goto docomplete; 1419 break; 1420 } 1421 # endif 1422 # ifdef FEAT_DIGRAPHS 1423 c = ins_digraph(); 1424 if (c == NUL) 1425 break; 1426 # endif 1427 goto normalchar; 1428 #endif 1429 1430 #ifdef FEAT_INS_EXPAND 1431 case Ctrl_X: /* Enter CTRL-X mode */ 1432 ins_ctrl_x(); 1433 break; 1434 1435 case Ctrl_RSB: /* Tag name completion after ^X */ 1436 if (ctrl_x_mode != CTRL_X_TAGS) 1437 goto normalchar; 1438 goto docomplete; 1439 1440 case Ctrl_F: /* File name completion after ^X */ 1441 if (ctrl_x_mode != CTRL_X_FILES) 1442 goto normalchar; 1443 goto docomplete; 1444 1445 case 's': /* Spelling completion after ^X */ 1446 case Ctrl_S: 1447 if (ctrl_x_mode != CTRL_X_SPELL) 1448 goto normalchar; 1449 goto docomplete; 1450 #endif 1451 1452 case Ctrl_L: /* Whole line completion after ^X */ 1453 #ifdef FEAT_INS_EXPAND 1454 if (ctrl_x_mode != CTRL_X_WHOLE_LINE) 1455 #endif 1456 { 1457 /* CTRL-L with 'insertmode' set: Leave Insert mode */ 1458 if (p_im) 1459 { 1460 if (echeck_abbr(Ctrl_L + ABBR_OFF)) 1461 break; 1462 goto doESCkey; 1463 } 1464 goto normalchar; 1465 } 1466 #ifdef FEAT_INS_EXPAND 1467 /* FALLTHROUGH */ 1468 1469 case Ctrl_P: /* Do previous/next pattern completion */ 1470 case Ctrl_N: 1471 /* if 'complete' is empty then plain ^P is no longer special, 1472 * but it is under other ^X modes */ 1473 if (*curbuf->b_p_cpt == NUL 1474 && (ctrl_x_mode == CTRL_X_NORMAL 1475 || ctrl_x_mode == CTRL_X_WHOLE_LINE) 1476 && !(compl_cont_status & CONT_LOCAL)) 1477 goto normalchar; 1478 1479 docomplete: 1480 compl_busy = TRUE; 1481 #ifdef FEAT_FOLDING 1482 disable_fold_update++; /* don't redraw folds here */ 1483 #endif 1484 if (ins_complete(c, TRUE) == FAIL) 1485 compl_cont_status = 0; 1486 #ifdef FEAT_FOLDING 1487 disable_fold_update--; 1488 #endif 1489 compl_busy = FALSE; 1490 break; 1491 #endif /* FEAT_INS_EXPAND */ 1492 1493 case Ctrl_Y: /* copy from previous line or scroll down */ 1494 case Ctrl_E: /* copy from next line or scroll up */ 1495 c = ins_ctrl_ey(c); 1496 break; 1497 1498 default: 1499 #ifdef UNIX 1500 if (c == intr_char) /* special interrupt char */ 1501 goto do_intr; 1502 #endif 1503 1504 normalchar: 1505 /* 1506 * Insert a normal character. 1507 */ 1508 #if defined(FEAT_EVAL) 1509 if (!p_paste) 1510 { 1511 /* Trigger InsertCharPre. */ 1512 char_u *str = do_insert_char_pre(c); 1513 char_u *p; 1514 1515 if (str != NULL) 1516 { 1517 if (*str != NUL && stop_arrow() != FAIL) 1518 { 1519 /* Insert the new value of v:char literally. */ 1520 for (p = str; *p != NUL; MB_PTR_ADV(p)) 1521 { 1522 c = PTR2CHAR(p); 1523 if (c == CAR || c == K_KENTER || c == NL) 1524 ins_eol(c); 1525 else 1526 ins_char(c); 1527 } 1528 AppendToRedobuffLit(str, -1); 1529 } 1530 vim_free(str); 1531 c = NUL; 1532 } 1533 1534 /* If the new value is already inserted or an empty string 1535 * then don't insert any character. */ 1536 if (c == NUL) 1537 break; 1538 } 1539 #endif 1540 #ifdef FEAT_SMARTINDENT 1541 /* Try to perform smart-indenting. */ 1542 ins_try_si(c); 1543 #endif 1544 1545 if (c == ' ') 1546 { 1547 inserted_space = TRUE; 1548 #ifdef FEAT_CINDENT 1549 if (inindent(0)) 1550 can_cindent = FALSE; 1551 #endif 1552 if (Insstart_blank_vcol == MAXCOL 1553 && curwin->w_cursor.lnum == Insstart.lnum) 1554 Insstart_blank_vcol = get_nolist_virtcol(); 1555 } 1556 1557 /* Insert a normal character and check for abbreviations on a 1558 * special character. Let CTRL-] expand abbreviations without 1559 * inserting it. */ 1560 if (vim_iswordc(c) || (!echeck_abbr( 1561 // Add ABBR_OFF for characters above 0x100, this is 1562 // what check_abbr() expects. 1563 (has_mbyte && c >= 0x100) ? (c + ABBR_OFF) : c) 1564 && c != Ctrl_RSB)) 1565 { 1566 insert_special(c, FALSE, FALSE); 1567 #ifdef FEAT_RIGHTLEFT 1568 revins_legal++; 1569 revins_chars++; 1570 #endif 1571 } 1572 1573 auto_format(FALSE, TRUE); 1574 1575 #ifdef FEAT_FOLDING 1576 /* When inserting a character the cursor line must never be in a 1577 * closed fold. */ 1578 foldOpenCursor(); 1579 #endif 1580 break; 1581 } /* end of switch (c) */ 1582 1583 /* If typed something may trigger CursorHoldI again. */ 1584 if (c != K_CURSORHOLD 1585 #ifdef FEAT_COMPL_FUNC 1586 /* but not in CTRL-X mode, a script can't restore the state */ 1587 && ctrl_x_mode == CTRL_X_NORMAL 1588 #endif 1589 ) 1590 did_cursorhold = FALSE; 1591 1592 /* If the cursor was moved we didn't just insert a space */ 1593 if (arrow_used) 1594 inserted_space = FALSE; 1595 1596 #ifdef FEAT_CINDENT 1597 if (can_cindent && cindent_on() 1598 # ifdef FEAT_INS_EXPAND 1599 && ctrl_x_mode == CTRL_X_NORMAL 1600 # endif 1601 ) 1602 { 1603 force_cindent: 1604 /* 1605 * Indent now if a key was typed that is in 'cinkeys'. 1606 */ 1607 if (in_cinkeys(c, ' ', line_is_white)) 1608 { 1609 if (stop_arrow() == OK) 1610 /* re-indent the current line */ 1611 do_c_expr_indent(); 1612 } 1613 } 1614 #endif /* FEAT_CINDENT */ 1615 1616 } /* for (;;) */ 1617 /* NOTREACHED */ 1618 } 1619 1620 /* 1621 * Redraw for Insert mode. 1622 * This is postponed until getting the next character to make '$' in the 'cpo' 1623 * option work correctly. 1624 * Only redraw when there are no characters available. This speeds up 1625 * inserting sequences of characters (e.g., for CTRL-R). 1626 */ 1627 static void 1628 ins_redraw( 1629 int ready UNUSED) /* not busy with something */ 1630 { 1631 #ifdef FEAT_CONCEAL 1632 linenr_T conceal_old_cursor_line = 0; 1633 linenr_T conceal_new_cursor_line = 0; 1634 int conceal_update_lines = FALSE; 1635 #endif 1636 1637 if (char_avail()) 1638 return; 1639 1640 #if defined(FEAT_CONCEAL) 1641 /* Trigger CursorMoved if the cursor moved. Not when the popup menu is 1642 * visible, the command might delete it. */ 1643 if (ready && (has_cursormovedI() 1644 # if defined(FEAT_CONCEAL) 1645 || curwin->w_p_cole > 0 1646 # endif 1647 ) 1648 && !EQUAL_POS(last_cursormoved, curwin->w_cursor) 1649 # ifdef FEAT_INS_EXPAND 1650 && !pum_visible() 1651 # endif 1652 ) 1653 { 1654 # ifdef FEAT_SYN_HL 1655 /* Need to update the screen first, to make sure syntax 1656 * highlighting is correct after making a change (e.g., inserting 1657 * a "(". The autocommand may also require a redraw, so it's done 1658 * again below, unfortunately. */ 1659 if (syntax_present(curwin) && must_redraw) 1660 update_screen(0); 1661 # endif 1662 if (has_cursormovedI()) 1663 { 1664 /* Make sure curswant is correct, an autocommand may call 1665 * getcurpos(). */ 1666 update_curswant(); 1667 ins_apply_autocmds(EVENT_CURSORMOVEDI); 1668 } 1669 # ifdef FEAT_CONCEAL 1670 if (curwin->w_p_cole > 0) 1671 { 1672 conceal_old_cursor_line = last_cursormoved.lnum; 1673 conceal_new_cursor_line = curwin->w_cursor.lnum; 1674 conceal_update_lines = TRUE; 1675 } 1676 # endif 1677 last_cursormoved = curwin->w_cursor; 1678 } 1679 #endif 1680 1681 /* Trigger TextChangedI if b_changedtick differs. */ 1682 if (ready && has_textchangedI() 1683 && curbuf->b_last_changedtick != CHANGEDTICK(curbuf) 1684 #ifdef FEAT_INS_EXPAND 1685 && !pum_visible() 1686 #endif 1687 ) 1688 { 1689 aco_save_T aco; 1690 varnumber_T tick = CHANGEDTICK(curbuf); 1691 1692 // save and restore curwin and curbuf, in case the autocmd changes them 1693 aucmd_prepbuf(&aco, curbuf); 1694 apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf); 1695 aucmd_restbuf(&aco); 1696 curbuf->b_last_changedtick = CHANGEDTICK(curbuf); 1697 if (tick != CHANGEDTICK(curbuf)) // see ins_apply_autocmds() 1698 u_save(curwin->w_cursor.lnum, 1699 (linenr_T)(curwin->w_cursor.lnum + 1)); 1700 } 1701 1702 #ifdef FEAT_INS_EXPAND 1703 /* Trigger TextChangedP if b_changedtick differs. When the popupmenu closes 1704 * TextChangedI will need to trigger for backwards compatibility, thus use 1705 * different b_last_changedtick* variables. */ 1706 if (ready && has_textchangedP() 1707 && curbuf->b_last_changedtick_pum != CHANGEDTICK(curbuf) 1708 && pum_visible()) 1709 { 1710 aco_save_T aco; 1711 varnumber_T tick = CHANGEDTICK(curbuf); 1712 1713 // save and restore curwin and curbuf, in case the autocmd changes them 1714 aucmd_prepbuf(&aco, curbuf); 1715 apply_autocmds(EVENT_TEXTCHANGEDP, NULL, NULL, FALSE, curbuf); 1716 aucmd_restbuf(&aco); 1717 curbuf->b_last_changedtick_pum = CHANGEDTICK(curbuf); 1718 if (tick != CHANGEDTICK(curbuf)) // see ins_apply_autocmds() 1719 u_save(curwin->w_cursor.lnum, 1720 (linenr_T)(curwin->w_cursor.lnum + 1)); 1721 } 1722 #endif 1723 1724 #if defined(FEAT_CONCEAL) 1725 if ((conceal_update_lines 1726 && (conceal_old_cursor_line != conceal_new_cursor_line 1727 || conceal_cursor_line(curwin))) 1728 || need_cursor_line_redraw) 1729 { 1730 if (conceal_old_cursor_line != conceal_new_cursor_line) 1731 redrawWinline(curwin, conceal_old_cursor_line); 1732 redrawWinline(curwin, conceal_new_cursor_line == 0 1733 ? curwin->w_cursor.lnum : conceal_new_cursor_line); 1734 curwin->w_valid &= ~VALID_CROW; 1735 need_cursor_line_redraw = FALSE; 1736 } 1737 #endif 1738 if (must_redraw) 1739 update_screen(0); 1740 else if (clear_cmdline || redraw_cmdline) 1741 showmode(); /* clear cmdline and show mode */ 1742 showruler(FALSE); 1743 setcursor(); 1744 emsg_on_display = FALSE; /* may remove error message now */ 1745 } 1746 1747 /* 1748 * Handle a CTRL-V or CTRL-Q typed in Insert mode. 1749 */ 1750 static void 1751 ins_ctrl_v(void) 1752 { 1753 int c; 1754 int did_putchar = FALSE; 1755 1756 /* may need to redraw when no more chars available now */ 1757 ins_redraw(FALSE); 1758 1759 if (redrawing() && !char_avail()) 1760 { 1761 edit_putchar('^', TRUE); 1762 did_putchar = TRUE; 1763 } 1764 AppendToRedobuff((char_u *)CTRL_V_STR); /* CTRL-V */ 1765 1766 #ifdef FEAT_CMDL_INFO 1767 add_to_showcmd_c(Ctrl_V); 1768 #endif 1769 1770 c = get_literal(); 1771 if (did_putchar) 1772 /* when the line fits in 'columns' the '^' is at the start of the next 1773 * line and will not removed by the redraw */ 1774 edit_unputchar(); 1775 #ifdef FEAT_CMDL_INFO 1776 clear_showcmd(); 1777 #endif 1778 insert_special(c, FALSE, TRUE); 1779 #ifdef FEAT_RIGHTLEFT 1780 revins_chars++; 1781 revins_legal++; 1782 #endif 1783 } 1784 1785 /* 1786 * Put a character directly onto the screen. It's not stored in a buffer. 1787 * Used while handling CTRL-K, CTRL-V, etc. in Insert mode. 1788 */ 1789 static int pc_status; 1790 #define PC_STATUS_UNSET 0 /* pc_bytes was not set */ 1791 #define PC_STATUS_RIGHT 1 /* right halve of double-wide char */ 1792 #define PC_STATUS_LEFT 2 /* left halve of double-wide char */ 1793 #define PC_STATUS_SET 3 /* pc_bytes was filled */ 1794 static char_u pc_bytes[MB_MAXBYTES + 1]; /* saved bytes */ 1795 static int pc_attr; 1796 static int pc_row; 1797 static int pc_col; 1798 1799 void 1800 edit_putchar(int c, int highlight) 1801 { 1802 int attr; 1803 1804 if (ScreenLines != NULL) 1805 { 1806 update_topline(); /* just in case w_topline isn't valid */ 1807 validate_cursor(); 1808 if (highlight) 1809 attr = HL_ATTR(HLF_8); 1810 else 1811 attr = 0; 1812 pc_row = W_WINROW(curwin) + curwin->w_wrow; 1813 pc_col = curwin->w_wincol; 1814 pc_status = PC_STATUS_UNSET; 1815 #ifdef FEAT_RIGHTLEFT 1816 if (curwin->w_p_rl) 1817 { 1818 pc_col += curwin->w_width - 1 - curwin->w_wcol; 1819 if (has_mbyte) 1820 { 1821 int fix_col = mb_fix_col(pc_col, pc_row); 1822 1823 if (fix_col != pc_col) 1824 { 1825 screen_putchar(' ', pc_row, fix_col, attr); 1826 --curwin->w_wcol; 1827 pc_status = PC_STATUS_RIGHT; 1828 } 1829 } 1830 } 1831 else 1832 #endif 1833 { 1834 pc_col += curwin->w_wcol; 1835 if (mb_lefthalve(pc_row, pc_col)) 1836 pc_status = PC_STATUS_LEFT; 1837 } 1838 1839 /* save the character to be able to put it back */ 1840 if (pc_status == PC_STATUS_UNSET) 1841 { 1842 screen_getbytes(pc_row, pc_col, pc_bytes, &pc_attr); 1843 pc_status = PC_STATUS_SET; 1844 } 1845 screen_putchar(c, pc_row, pc_col, attr); 1846 } 1847 } 1848 1849 #if defined(FEAT_JOB_CHANNEL) || defined(PROTO) 1850 /* 1851 * Return the effective prompt for the current buffer. 1852 */ 1853 char_u * 1854 prompt_text(void) 1855 { 1856 if (curbuf->b_prompt_text == NULL) 1857 return (char_u *)"% "; 1858 return curbuf->b_prompt_text; 1859 } 1860 1861 /* 1862 * Prepare for prompt mode: Make sure the last line has the prompt text. 1863 * Move the cursor to this line. 1864 */ 1865 static void 1866 init_prompt(int cmdchar_todo) 1867 { 1868 char_u *prompt = prompt_text(); 1869 char_u *text; 1870 1871 curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; 1872 text = ml_get_curline(); 1873 if (STRNCMP(text, prompt, STRLEN(prompt)) != 0) 1874 { 1875 // prompt is missing, insert it or append a line with it 1876 if (*text == NUL) 1877 ml_replace(curbuf->b_ml.ml_line_count, prompt, TRUE); 1878 else 1879 ml_append(curbuf->b_ml.ml_line_count, prompt, 0, FALSE); 1880 curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; 1881 coladvance((colnr_T)MAXCOL); 1882 changed_bytes(curbuf->b_ml.ml_line_count, 0); 1883 } 1884 1885 // Insert always starts after the prompt, allow editing text after it. 1886 if (Insstart_orig.lnum != curwin->w_cursor.lnum 1887 || Insstart_orig.col != (int)STRLEN(prompt)) 1888 { 1889 Insstart.lnum = curwin->w_cursor.lnum; 1890 Insstart.col = (int)STRLEN(prompt); 1891 Insstart_orig = Insstart; 1892 Insstart_textlen = Insstart.col; 1893 Insstart_blank_vcol = MAXCOL; 1894 arrow_used = FALSE; 1895 } 1896 1897 if (cmdchar_todo == 'A') 1898 coladvance((colnr_T)MAXCOL); 1899 if (cmdchar_todo == 'I' || curwin->w_cursor.col <= (int)STRLEN(prompt)) 1900 curwin->w_cursor.col = (int)STRLEN(prompt); 1901 /* Make sure the cursor is in a valid position. */ 1902 check_cursor(); 1903 } 1904 1905 /* 1906 * Return TRUE if the cursor is in the editable position of the prompt line. 1907 */ 1908 int 1909 prompt_curpos_editable() 1910 { 1911 return curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count 1912 && curwin->w_cursor.col >= (int)STRLEN(prompt_text()); 1913 } 1914 #endif 1915 1916 /* 1917 * Undo the previous edit_putchar(). 1918 */ 1919 void 1920 edit_unputchar(void) 1921 { 1922 if (pc_status != PC_STATUS_UNSET && pc_row >= msg_scrolled) 1923 { 1924 if (pc_status == PC_STATUS_RIGHT) 1925 ++curwin->w_wcol; 1926 if (pc_status == PC_STATUS_RIGHT || pc_status == PC_STATUS_LEFT) 1927 redrawWinline(curwin, curwin->w_cursor.lnum); 1928 else 1929 screen_puts(pc_bytes, pc_row - msg_scrolled, pc_col, pc_attr); 1930 } 1931 } 1932 1933 /* 1934 * Called when p_dollar is set: display a '$' at the end of the changed text 1935 * Only works when cursor is in the line that changes. 1936 */ 1937 void 1938 display_dollar(colnr_T col) 1939 { 1940 colnr_T save_col; 1941 1942 if (!redrawing()) 1943 return; 1944 1945 cursor_off(); 1946 save_col = curwin->w_cursor.col; 1947 curwin->w_cursor.col = col; 1948 if (has_mbyte) 1949 { 1950 char_u *p; 1951 1952 /* If on the last byte of a multi-byte move to the first byte. */ 1953 p = ml_get_curline(); 1954 curwin->w_cursor.col -= (*mb_head_off)(p, p + col); 1955 } 1956 curs_columns(FALSE); /* recompute w_wrow and w_wcol */ 1957 if (curwin->w_wcol < curwin->w_width) 1958 { 1959 edit_putchar('$', FALSE); 1960 dollar_vcol = curwin->w_virtcol; 1961 } 1962 curwin->w_cursor.col = save_col; 1963 } 1964 1965 /* 1966 * Call this function before moving the cursor from the normal insert position 1967 * in insert mode. 1968 */ 1969 static void 1970 undisplay_dollar(void) 1971 { 1972 if (dollar_vcol >= 0) 1973 { 1974 dollar_vcol = -1; 1975 redrawWinline(curwin, curwin->w_cursor.lnum); 1976 } 1977 } 1978 1979 /* 1980 * Insert an indent (for <Tab> or CTRL-T) or delete an indent (for CTRL-D). 1981 * Keep the cursor on the same character. 1982 * type == INDENT_INC increase indent (for CTRL-T or <Tab>) 1983 * type == INDENT_DEC decrease indent (for CTRL-D) 1984 * type == INDENT_SET set indent to "amount" 1985 * if round is TRUE, round the indent to 'shiftwidth' (only with _INC and _Dec). 1986 */ 1987 void 1988 change_indent( 1989 int type, 1990 int amount, 1991 int round, 1992 int replaced, /* replaced character, put on replace stack */ 1993 int call_changed_bytes) /* call changed_bytes() */ 1994 { 1995 int vcol; 1996 int last_vcol; 1997 int insstart_less; /* reduction for Insstart.col */ 1998 int new_cursor_col; 1999 int i; 2000 char_u *ptr; 2001 int save_p_list; 2002 int start_col; 2003 colnr_T vc; 2004 colnr_T orig_col = 0; /* init for GCC */ 2005 char_u *new_line, *orig_line = NULL; /* init for GCC */ 2006 2007 /* VREPLACE mode needs to know what the line was like before changing */ 2008 if (State & VREPLACE_FLAG) 2009 { 2010 orig_line = vim_strsave(ml_get_curline()); /* Deal with NULL below */ 2011 orig_col = curwin->w_cursor.col; 2012 } 2013 2014 /* for the following tricks we don't want list mode */ 2015 save_p_list = curwin->w_p_list; 2016 curwin->w_p_list = FALSE; 2017 vc = getvcol_nolist(&curwin->w_cursor); 2018 vcol = vc; 2019 2020 /* 2021 * For Replace mode we need to fix the replace stack later, which is only 2022 * possible when the cursor is in the indent. Remember the number of 2023 * characters before the cursor if it's possible. 2024 */ 2025 start_col = curwin->w_cursor.col; 2026 2027 /* determine offset from first non-blank */ 2028 new_cursor_col = curwin->w_cursor.col; 2029 beginline(BL_WHITE); 2030 new_cursor_col -= curwin->w_cursor.col; 2031 2032 insstart_less = curwin->w_cursor.col; 2033 2034 /* 2035 * If the cursor is in the indent, compute how many screen columns the 2036 * cursor is to the left of the first non-blank. 2037 */ 2038 if (new_cursor_col < 0) 2039 vcol = get_indent() - vcol; 2040 2041 if (new_cursor_col > 0) /* can't fix replace stack */ 2042 start_col = -1; 2043 2044 /* 2045 * Set the new indent. The cursor will be put on the first non-blank. 2046 */ 2047 if (type == INDENT_SET) 2048 (void)set_indent(amount, call_changed_bytes ? SIN_CHANGED : 0); 2049 else 2050 { 2051 int save_State = State; 2052 2053 /* Avoid being called recursively. */ 2054 if (State & VREPLACE_FLAG) 2055 State = INSERT; 2056 shift_line(type == INDENT_DEC, round, 1, call_changed_bytes); 2057 State = save_State; 2058 } 2059 insstart_less -= curwin->w_cursor.col; 2060 2061 /* 2062 * Try to put cursor on same character. 2063 * If the cursor is at or after the first non-blank in the line, 2064 * compute the cursor column relative to the column of the first 2065 * non-blank character. 2066 * If we are not in insert mode, leave the cursor on the first non-blank. 2067 * If the cursor is before the first non-blank, position it relative 2068 * to the first non-blank, counted in screen columns. 2069 */ 2070 if (new_cursor_col >= 0) 2071 { 2072 /* 2073 * When changing the indent while the cursor is touching it, reset 2074 * Insstart_col to 0. 2075 */ 2076 if (new_cursor_col == 0) 2077 insstart_less = MAXCOL; 2078 new_cursor_col += curwin->w_cursor.col; 2079 } 2080 else if (!(State & INSERT)) 2081 new_cursor_col = curwin->w_cursor.col; 2082 else 2083 { 2084 /* 2085 * Compute the screen column where the cursor should be. 2086 */ 2087 vcol = get_indent() - vcol; 2088 curwin->w_virtcol = (colnr_T)((vcol < 0) ? 0 : vcol); 2089 2090 /* 2091 * Advance the cursor until we reach the right screen column. 2092 */ 2093 vcol = last_vcol = 0; 2094 new_cursor_col = -1; 2095 ptr = ml_get_curline(); 2096 while (vcol <= (int)curwin->w_virtcol) 2097 { 2098 last_vcol = vcol; 2099 if (has_mbyte && new_cursor_col >= 0) 2100 new_cursor_col += (*mb_ptr2len)(ptr + new_cursor_col); 2101 else 2102 ++new_cursor_col; 2103 vcol += lbr_chartabsize(ptr, ptr + new_cursor_col, (colnr_T)vcol); 2104 } 2105 vcol = last_vcol; 2106 2107 /* 2108 * May need to insert spaces to be able to position the cursor on 2109 * the right screen column. 2110 */ 2111 if (vcol != (int)curwin->w_virtcol) 2112 { 2113 curwin->w_cursor.col = (colnr_T)new_cursor_col; 2114 i = (int)curwin->w_virtcol - vcol; 2115 ptr = alloc((unsigned)(i + 1)); 2116 if (ptr != NULL) 2117 { 2118 new_cursor_col += i; 2119 ptr[i] = NUL; 2120 while (--i >= 0) 2121 ptr[i] = ' '; 2122 ins_str(ptr); 2123 vim_free(ptr); 2124 } 2125 } 2126 2127 /* 2128 * When changing the indent while the cursor is in it, reset 2129 * Insstart_col to 0. 2130 */ 2131 insstart_less = MAXCOL; 2132 } 2133 2134 curwin->w_p_list = save_p_list; 2135 2136 if (new_cursor_col <= 0) 2137 curwin->w_cursor.col = 0; 2138 else 2139 curwin->w_cursor.col = (colnr_T)new_cursor_col; 2140 curwin->w_set_curswant = TRUE; 2141 changed_cline_bef_curs(); 2142 2143 /* 2144 * May have to adjust the start of the insert. 2145 */ 2146 if (State & INSERT) 2147 { 2148 if (curwin->w_cursor.lnum == Insstart.lnum && Insstart.col != 0) 2149 { 2150 if ((int)Insstart.col <= insstart_less) 2151 Insstart.col = 0; 2152 else 2153 Insstart.col -= insstart_less; 2154 } 2155 if ((int)ai_col <= insstart_less) 2156 ai_col = 0; 2157 else 2158 ai_col -= insstart_less; 2159 } 2160 2161 /* 2162 * For REPLACE mode, may have to fix the replace stack, if it's possible. 2163 * If the number of characters before the cursor decreased, need to pop a 2164 * few characters from the replace stack. 2165 * If the number of characters before the cursor increased, need to push a 2166 * few NULs onto the replace stack. 2167 */ 2168 if (REPLACE_NORMAL(State) && start_col >= 0) 2169 { 2170 while (start_col > (int)curwin->w_cursor.col) 2171 { 2172 replace_join(0); /* remove a NUL from the replace stack */ 2173 --start_col; 2174 } 2175 while (start_col < (int)curwin->w_cursor.col || replaced) 2176 { 2177 replace_push(NUL); 2178 if (replaced) 2179 { 2180 replace_push(replaced); 2181 replaced = NUL; 2182 } 2183 ++start_col; 2184 } 2185 } 2186 2187 /* 2188 * For VREPLACE mode, we also have to fix the replace stack. In this case 2189 * it is always possible because we backspace over the whole line and then 2190 * put it back again the way we wanted it. 2191 */ 2192 if (State & VREPLACE_FLAG) 2193 { 2194 /* If orig_line didn't allocate, just return. At least we did the job, 2195 * even if you can't backspace. */ 2196 if (orig_line == NULL) 2197 return; 2198 2199 /* Save new line */ 2200 new_line = vim_strsave(ml_get_curline()); 2201 if (new_line == NULL) 2202 return; 2203 2204 /* We only put back the new line up to the cursor */ 2205 new_line[curwin->w_cursor.col] = NUL; 2206 2207 /* Put back original line */ 2208 ml_replace(curwin->w_cursor.lnum, orig_line, FALSE); 2209 curwin->w_cursor.col = orig_col; 2210 2211 /* Backspace from cursor to start of line */ 2212 backspace_until_column(0); 2213 2214 /* Insert new stuff into line again */ 2215 ins_bytes(new_line); 2216 2217 vim_free(new_line); 2218 } 2219 } 2220 2221 /* 2222 * Truncate the space at the end of a line. This is to be used only in an 2223 * insert mode. It handles fixing the replace stack for REPLACE and VREPLACE 2224 * modes. 2225 */ 2226 void 2227 truncate_spaces(char_u *line) 2228 { 2229 int i; 2230 2231 /* find start of trailing white space */ 2232 for (i = (int)STRLEN(line) - 1; i >= 0 && VIM_ISWHITE(line[i]); i--) 2233 { 2234 if (State & REPLACE_FLAG) 2235 replace_join(0); /* remove a NUL from the replace stack */ 2236 } 2237 line[i + 1] = NUL; 2238 } 2239 2240 /* 2241 * Backspace the cursor until the given column. Handles REPLACE and VREPLACE 2242 * modes correctly. May also be used when not in insert mode at all. 2243 * Will attempt not to go before "col" even when there is a composing 2244 * character. 2245 */ 2246 void 2247 backspace_until_column(int col) 2248 { 2249 while ((int)curwin->w_cursor.col > col) 2250 { 2251 curwin->w_cursor.col--; 2252 if (State & REPLACE_FLAG) 2253 replace_do_bs(col); 2254 else if (!del_char_after_col(col)) 2255 break; 2256 } 2257 } 2258 2259 /* 2260 * Like del_char(), but make sure not to go before column "limit_col". 2261 * Only matters when there are composing characters. 2262 * Return TRUE when something was deleted. 2263 */ 2264 static int 2265 del_char_after_col(int limit_col UNUSED) 2266 { 2267 if (enc_utf8 && limit_col >= 0) 2268 { 2269 colnr_T ecol = curwin->w_cursor.col + 1; 2270 2271 /* Make sure the cursor is at the start of a character, but 2272 * skip forward again when going too far back because of a 2273 * composing character. */ 2274 mb_adjust_cursor(); 2275 while (curwin->w_cursor.col < (colnr_T)limit_col) 2276 { 2277 int l = utf_ptr2len(ml_get_cursor()); 2278 2279 if (l == 0) /* end of line */ 2280 break; 2281 curwin->w_cursor.col += l; 2282 } 2283 if (*ml_get_cursor() == NUL || curwin->w_cursor.col == ecol) 2284 return FALSE; 2285 del_bytes((long)((int)ecol - curwin->w_cursor.col), FALSE, TRUE); 2286 } 2287 else 2288 (void)del_char(FALSE); 2289 return TRUE; 2290 } 2291 2292 #if defined(FEAT_INS_EXPAND) || defined(PROTO) 2293 /* 2294 * CTRL-X pressed in Insert mode. 2295 */ 2296 static void 2297 ins_ctrl_x(void) 2298 { 2299 /* CTRL-X after CTRL-X CTRL-V doesn't do anything, so that CTRL-X 2300 * CTRL-V works like CTRL-N */ 2301 if (ctrl_x_mode != CTRL_X_CMDLINE) 2302 { 2303 /* if the next ^X<> won't ADD nothing, then reset 2304 * compl_cont_status */ 2305 if (compl_cont_status & CONT_N_ADDS) 2306 compl_cont_status |= CONT_INTRPT; 2307 else 2308 compl_cont_status = 0; 2309 /* We're not sure which CTRL-X mode it will be yet */ 2310 ctrl_x_mode = CTRL_X_NOT_DEFINED_YET; 2311 edit_submode = (char_u *)_(CTRL_X_MSG(ctrl_x_mode)); 2312 edit_submode_pre = NULL; 2313 showmode(); 2314 } 2315 } 2316 2317 /* 2318 * Whether other than default completion has been selected. 2319 */ 2320 int 2321 ctrl_x_mode_not_default(void) 2322 { 2323 return ctrl_x_mode != CTRL_X_NORMAL; 2324 } 2325 2326 /* 2327 * Whether CTRL-X was typed without a following character. 2328 */ 2329 int 2330 ctrl_x_mode_not_defined_yet(void) 2331 { 2332 return ctrl_x_mode == CTRL_X_NOT_DEFINED_YET; 2333 } 2334 2335 /* 2336 * Return TRUE if the 'dict' or 'tsr' option can be used. 2337 */ 2338 static int 2339 has_compl_option(int dict_opt) 2340 { 2341 if (dict_opt ? (*curbuf->b_p_dict == NUL && *p_dict == NUL 2342 # ifdef FEAT_SPELL 2343 && !curwin->w_p_spell 2344 # endif 2345 ) 2346 : (*curbuf->b_p_tsr == NUL && *p_tsr == NUL)) 2347 { 2348 ctrl_x_mode = CTRL_X_NORMAL; 2349 edit_submode = NULL; 2350 msg_attr(dict_opt ? _("'dictionary' option is empty") 2351 : _("'thesaurus' option is empty"), 2352 HL_ATTR(HLF_E)); 2353 if (emsg_silent == 0) 2354 { 2355 vim_beep(BO_COMPL); 2356 setcursor(); 2357 out_flush(); 2358 #ifdef FEAT_EVAL 2359 if (!get_vim_var_nr(VV_TESTING)) 2360 #endif 2361 ui_delay(2000L, FALSE); 2362 } 2363 return FALSE; 2364 } 2365 return TRUE; 2366 } 2367 2368 /* 2369 * Is the character 'c' a valid key to go to or keep us in CTRL-X mode? 2370 * This depends on the current mode. 2371 */ 2372 int 2373 vim_is_ctrl_x_key(int c) 2374 { 2375 // Always allow ^R - let its results then be checked 2376 if (c == Ctrl_R) 2377 return TRUE; 2378 2379 /* Accept <PageUp> and <PageDown> if the popup menu is visible. */ 2380 if (ins_compl_pum_key(c)) 2381 return TRUE; 2382 2383 switch (ctrl_x_mode) 2384 { 2385 case 0: /* Not in any CTRL-X mode */ 2386 return (c == Ctrl_N || c == Ctrl_P || c == Ctrl_X); 2387 case CTRL_X_NOT_DEFINED_YET: 2388 return ( c == Ctrl_X || c == Ctrl_Y || c == Ctrl_E 2389 || c == Ctrl_L || c == Ctrl_F || c == Ctrl_RSB 2390 || c == Ctrl_I || c == Ctrl_D || c == Ctrl_P 2391 || c == Ctrl_N || c == Ctrl_T || c == Ctrl_V 2392 || c == Ctrl_Q || c == Ctrl_U || c == Ctrl_O 2393 || c == Ctrl_S || c == Ctrl_K || c == 's'); 2394 case CTRL_X_SCROLL: 2395 return (c == Ctrl_Y || c == Ctrl_E); 2396 case CTRL_X_WHOLE_LINE: 2397 return (c == Ctrl_L || c == Ctrl_P || c == Ctrl_N); 2398 case CTRL_X_FILES: 2399 return (c == Ctrl_F || c == Ctrl_P || c == Ctrl_N); 2400 case CTRL_X_DICTIONARY: 2401 return (c == Ctrl_K || c == Ctrl_P || c == Ctrl_N); 2402 case CTRL_X_THESAURUS: 2403 return (c == Ctrl_T || c == Ctrl_P || c == Ctrl_N); 2404 case CTRL_X_TAGS: 2405 return (c == Ctrl_RSB || c == Ctrl_P || c == Ctrl_N); 2406 #ifdef FEAT_FIND_ID 2407 case CTRL_X_PATH_PATTERNS: 2408 return (c == Ctrl_P || c == Ctrl_N); 2409 case CTRL_X_PATH_DEFINES: 2410 return (c == Ctrl_D || c == Ctrl_P || c == Ctrl_N); 2411 #endif 2412 case CTRL_X_CMDLINE: 2413 return (c == Ctrl_V || c == Ctrl_Q || c == Ctrl_P || c == Ctrl_N 2414 || c == Ctrl_X); 2415 #ifdef FEAT_COMPL_FUNC 2416 case CTRL_X_FUNCTION: 2417 return (c == Ctrl_U || c == Ctrl_P || c == Ctrl_N); 2418 case CTRL_X_OMNI: 2419 return (c == Ctrl_O || c == Ctrl_P || c == Ctrl_N); 2420 #endif 2421 case CTRL_X_SPELL: 2422 return (c == Ctrl_S || c == Ctrl_P || c == Ctrl_N); 2423 case CTRL_X_EVAL: 2424 return (c == Ctrl_P || c == Ctrl_N); 2425 } 2426 internal_error("vim_is_ctrl_x_key()"); 2427 return FALSE; 2428 } 2429 2430 /* 2431 * Return TRUE when character "c" is part of the item currently being 2432 * completed. Used to decide whether to abandon complete mode when the menu 2433 * is visible. 2434 */ 2435 static int 2436 ins_compl_accept_char(int c) 2437 { 2438 if (ctrl_x_mode & CTRL_X_WANT_IDENT) 2439 /* When expanding an identifier only accept identifier chars. */ 2440 return vim_isIDc(c); 2441 2442 switch (ctrl_x_mode) 2443 { 2444 case CTRL_X_FILES: 2445 /* When expanding file name only accept file name chars. But not 2446 * path separators, so that "proto/<Tab>" expands files in 2447 * "proto", not "proto/" as a whole */ 2448 return vim_isfilec(c) && !vim_ispathsep(c); 2449 2450 case CTRL_X_CMDLINE: 2451 case CTRL_X_OMNI: 2452 /* Command line and Omni completion can work with just about any 2453 * printable character, but do stop at white space. */ 2454 return vim_isprintc(c) && !VIM_ISWHITE(c); 2455 2456 case CTRL_X_WHOLE_LINE: 2457 /* For while line completion a space can be part of the line. */ 2458 return vim_isprintc(c); 2459 } 2460 return vim_iswordc(c); 2461 } 2462 2463 /* 2464 * This is like ins_compl_add(), but if 'ic' and 'inf' are set, then the 2465 * case of the originally typed text is used, and the case of the completed 2466 * text is inferred, ie this tries to work out what case you probably wanted 2467 * the rest of the word to be in -- webb 2468 */ 2469 int 2470 ins_compl_add_infercase( 2471 char_u *str, 2472 int len, 2473 int icase, 2474 char_u *fname, 2475 int dir, 2476 int flags) 2477 { 2478 char_u *p; 2479 int i, c; 2480 int actual_len; /* Take multi-byte characters */ 2481 int actual_compl_length; /* into account. */ 2482 int min_len; 2483 int *wca; /* Wide character array. */ 2484 int has_lower = FALSE; 2485 int was_letter = FALSE; 2486 2487 if (p_ic && curbuf->b_p_inf && len > 0) 2488 { 2489 /* Infer case of completed part. */ 2490 2491 /* Find actual length of completion. */ 2492 if (has_mbyte) 2493 { 2494 p = str; 2495 actual_len = 0; 2496 while (*p != NUL) 2497 { 2498 MB_PTR_ADV(p); 2499 ++actual_len; 2500 } 2501 } 2502 else 2503 actual_len = len; 2504 2505 /* Find actual length of original text. */ 2506 if (has_mbyte) 2507 { 2508 p = compl_orig_text; 2509 actual_compl_length = 0; 2510 while (*p != NUL) 2511 { 2512 MB_PTR_ADV(p); 2513 ++actual_compl_length; 2514 } 2515 } 2516 else 2517 actual_compl_length = compl_length; 2518 2519 /* "actual_len" may be smaller than "actual_compl_length" when using 2520 * thesaurus, only use the minimum when comparing. */ 2521 min_len = actual_len < actual_compl_length 2522 ? actual_len : actual_compl_length; 2523 2524 /* Allocate wide character array for the completion and fill it. */ 2525 wca = (int *)alloc((unsigned)(actual_len * sizeof(int))); 2526 if (wca != NULL) 2527 { 2528 p = str; 2529 for (i = 0; i < actual_len; ++i) 2530 if (has_mbyte) 2531 wca[i] = mb_ptr2char_adv(&p); 2532 else 2533 wca[i] = *(p++); 2534 2535 /* Rule 1: Were any chars converted to lower? */ 2536 p = compl_orig_text; 2537 for (i = 0; i < min_len; ++i) 2538 { 2539 if (has_mbyte) 2540 c = mb_ptr2char_adv(&p); 2541 else 2542 c = *(p++); 2543 if (MB_ISLOWER(c)) 2544 { 2545 has_lower = TRUE; 2546 if (MB_ISUPPER(wca[i])) 2547 { 2548 /* Rule 1 is satisfied. */ 2549 for (i = actual_compl_length; i < actual_len; ++i) 2550 wca[i] = MB_TOLOWER(wca[i]); 2551 break; 2552 } 2553 } 2554 } 2555 2556 /* 2557 * Rule 2: No lower case, 2nd consecutive letter converted to 2558 * upper case. 2559 */ 2560 if (!has_lower) 2561 { 2562 p = compl_orig_text; 2563 for (i = 0; i < min_len; ++i) 2564 { 2565 if (has_mbyte) 2566 c = mb_ptr2char_adv(&p); 2567 else 2568 c = *(p++); 2569 if (was_letter && MB_ISUPPER(c) && MB_ISLOWER(wca[i])) 2570 { 2571 /* Rule 2 is satisfied. */ 2572 for (i = actual_compl_length; i < actual_len; ++i) 2573 wca[i] = MB_TOUPPER(wca[i]); 2574 break; 2575 } 2576 was_letter = MB_ISLOWER(c) || MB_ISUPPER(c); 2577 } 2578 } 2579 2580 /* Copy the original case of the part we typed. */ 2581 p = compl_orig_text; 2582 for (i = 0; i < min_len; ++i) 2583 { 2584 if (has_mbyte) 2585 c = mb_ptr2char_adv(&p); 2586 else 2587 c = *(p++); 2588 if (MB_ISLOWER(c)) 2589 wca[i] = MB_TOLOWER(wca[i]); 2590 else if (MB_ISUPPER(c)) 2591 wca[i] = MB_TOUPPER(wca[i]); 2592 } 2593 2594 /* 2595 * Generate encoding specific output from wide character array. 2596 * Multi-byte characters can occupy up to five bytes more than 2597 * ASCII characters, and we also need one byte for NUL, so stay 2598 * six bytes away from the edge of IObuff. 2599 */ 2600 p = IObuff; 2601 i = 0; 2602 while (i < actual_len && (p - IObuff + 6) < IOSIZE) 2603 if (has_mbyte) 2604 p += (*mb_char2bytes)(wca[i++], p); 2605 else 2606 *(p++) = wca[i++]; 2607 *p = NUL; 2608 2609 vim_free(wca); 2610 } 2611 2612 return ins_compl_add(IObuff, len, icase, fname, NULL, dir, 2613 flags, FALSE); 2614 } 2615 return ins_compl_add(str, len, icase, fname, NULL, dir, flags, FALSE); 2616 } 2617 2618 /* 2619 * Add a match to the list of matches. 2620 * If the given string is already in the list of completions, then return 2621 * NOTDONE, otherwise add it to the list and return OK. If there is an error, 2622 * maybe because alloc() returns NULL, then FAIL is returned. 2623 */ 2624 static int 2625 ins_compl_add( 2626 char_u *str, 2627 int len, 2628 int icase, 2629 char_u *fname, 2630 char_u **cptext, /* extra text for popup menu or NULL */ 2631 int cdir, 2632 int flags, 2633 int adup) /* accept duplicate match */ 2634 { 2635 compl_T *match; 2636 int dir = (cdir == 0 ? compl_direction : cdir); 2637 2638 ui_breakcheck(); 2639 if (got_int) 2640 return FAIL; 2641 if (len < 0) 2642 len = (int)STRLEN(str); 2643 2644 /* 2645 * If the same match is already present, don't add it. 2646 */ 2647 if (compl_first_match != NULL && !adup) 2648 { 2649 match = compl_first_match; 2650 do 2651 { 2652 if ( !(match->cp_flags & ORIGINAL_TEXT) 2653 && STRNCMP(match->cp_str, str, len) == 0 2654 && match->cp_str[len] == NUL) 2655 return NOTDONE; 2656 match = match->cp_next; 2657 } while (match != NULL && match != compl_first_match); 2658 } 2659 2660 /* Remove any popup menu before changing the list of matches. */ 2661 ins_compl_del_pum(); 2662 2663 /* 2664 * Allocate a new match structure. 2665 * Copy the values to the new match structure. 2666 */ 2667 match = (compl_T *)alloc_clear((unsigned)sizeof(compl_T)); 2668 if (match == NULL) 2669 return FAIL; 2670 match->cp_number = -1; 2671 if (flags & ORIGINAL_TEXT) 2672 match->cp_number = 0; 2673 if ((match->cp_str = vim_strnsave(str, len)) == NULL) 2674 { 2675 vim_free(match); 2676 return FAIL; 2677 } 2678 match->cp_icase = icase; 2679 2680 /* match-fname is: 2681 * - compl_curr_match->cp_fname if it is a string equal to fname. 2682 * - a copy of fname, FREE_FNAME is set to free later THE allocated mem. 2683 * - NULL otherwise. --Acevedo */ 2684 if (fname != NULL 2685 && compl_curr_match != NULL 2686 && compl_curr_match->cp_fname != NULL 2687 && STRCMP(fname, compl_curr_match->cp_fname) == 0) 2688 match->cp_fname = compl_curr_match->cp_fname; 2689 else if (fname != NULL) 2690 { 2691 match->cp_fname = vim_strsave(fname); 2692 flags |= FREE_FNAME; 2693 } 2694 else 2695 match->cp_fname = NULL; 2696 match->cp_flags = flags; 2697 2698 if (cptext != NULL) 2699 { 2700 int i; 2701 2702 for (i = 0; i < CPT_COUNT; ++i) 2703 if (cptext[i] != NULL && *cptext[i] != NUL) 2704 match->cp_text[i] = vim_strsave(cptext[i]); 2705 } 2706 2707 /* 2708 * Link the new match structure in the list of matches. 2709 */ 2710 if (compl_first_match == NULL) 2711 match->cp_next = match->cp_prev = NULL; 2712 else if (dir == FORWARD) 2713 { 2714 match->cp_next = compl_curr_match->cp_next; 2715 match->cp_prev = compl_curr_match; 2716 } 2717 else /* BACKWARD */ 2718 { 2719 match->cp_next = compl_curr_match; 2720 match->cp_prev = compl_curr_match->cp_prev; 2721 } 2722 if (match->cp_next) 2723 match->cp_next->cp_prev = match; 2724 if (match->cp_prev) 2725 match->cp_prev->cp_next = match; 2726 else /* if there's nothing before, it is the first match */ 2727 compl_first_match = match; 2728 compl_curr_match = match; 2729 2730 /* 2731 * Find the longest common string if still doing that. 2732 */ 2733 if (compl_get_longest && (flags & ORIGINAL_TEXT) == 0) 2734 ins_compl_longest_match(match); 2735 2736 return OK; 2737 } 2738 2739 /* 2740 * Return TRUE if "str[len]" matches with match->cp_str, considering 2741 * match->cp_icase. 2742 */ 2743 static int 2744 ins_compl_equal(compl_T *match, char_u *str, int len) 2745 { 2746 if (match->cp_icase) 2747 return STRNICMP(match->cp_str, str, (size_t)len) == 0; 2748 return STRNCMP(match->cp_str, str, (size_t)len) == 0; 2749 } 2750 2751 /* 2752 * Reduce the longest common string for match "match". 2753 */ 2754 static void 2755 ins_compl_longest_match(compl_T *match) 2756 { 2757 char_u *p, *s; 2758 int c1, c2; 2759 int had_match; 2760 2761 if (compl_leader == NULL) 2762 { 2763 /* First match, use it as a whole. */ 2764 compl_leader = vim_strsave(match->cp_str); 2765 if (compl_leader != NULL) 2766 { 2767 had_match = (curwin->w_cursor.col > compl_col); 2768 ins_compl_delete(); 2769 ins_bytes(compl_leader + ins_compl_len()); 2770 ins_redraw(FALSE); 2771 2772 /* When the match isn't there (to avoid matching itself) remove it 2773 * again after redrawing. */ 2774 if (!had_match) 2775 ins_compl_delete(); 2776 compl_used_match = FALSE; 2777 } 2778 } 2779 else 2780 { 2781 /* Reduce the text if this match differs from compl_leader. */ 2782 p = compl_leader; 2783 s = match->cp_str; 2784 while (*p != NUL) 2785 { 2786 if (has_mbyte) 2787 { 2788 c1 = mb_ptr2char(p); 2789 c2 = mb_ptr2char(s); 2790 } 2791 else 2792 { 2793 c1 = *p; 2794 c2 = *s; 2795 } 2796 if (match->cp_icase ? (MB_TOLOWER(c1) != MB_TOLOWER(c2)) 2797 : (c1 != c2)) 2798 break; 2799 if (has_mbyte) 2800 { 2801 MB_PTR_ADV(p); 2802 MB_PTR_ADV(s); 2803 } 2804 else 2805 { 2806 ++p; 2807 ++s; 2808 } 2809 } 2810 2811 if (*p != NUL) 2812 { 2813 /* Leader was shortened, need to change the inserted text. */ 2814 *p = NUL; 2815 had_match = (curwin->w_cursor.col > compl_col); 2816 ins_compl_delete(); 2817 ins_bytes(compl_leader + ins_compl_len()); 2818 ins_redraw(FALSE); 2819 2820 /* When the match isn't there (to avoid matching itself) remove it 2821 * again after redrawing. */ 2822 if (!had_match) 2823 ins_compl_delete(); 2824 } 2825 2826 compl_used_match = FALSE; 2827 } 2828 } 2829 2830 /* 2831 * Add an array of matches to the list of matches. 2832 * Frees matches[]. 2833 */ 2834 static void 2835 ins_compl_add_matches( 2836 int num_matches, 2837 char_u **matches, 2838 int icase) 2839 { 2840 int i; 2841 int add_r = OK; 2842 int dir = compl_direction; 2843 2844 for (i = 0; i < num_matches && add_r != FAIL; i++) 2845 if ((add_r = ins_compl_add(matches[i], -1, icase, 2846 NULL, NULL, dir, 0, FALSE)) == OK) 2847 /* if dir was BACKWARD then honor it just once */ 2848 dir = FORWARD; 2849 FreeWild(num_matches, matches); 2850 } 2851 2852 /* Make the completion list cyclic. 2853 * Return the number of matches (excluding the original). 2854 */ 2855 static int 2856 ins_compl_make_cyclic(void) 2857 { 2858 compl_T *match; 2859 int count = 0; 2860 2861 if (compl_first_match != NULL) 2862 { 2863 /* 2864 * Find the end of the list. 2865 */ 2866 match = compl_first_match; 2867 /* there's always an entry for the compl_orig_text, it doesn't count. */ 2868 while (match->cp_next != NULL && match->cp_next != compl_first_match) 2869 { 2870 match = match->cp_next; 2871 ++count; 2872 } 2873 match->cp_next = compl_first_match; 2874 compl_first_match->cp_prev = match; 2875 } 2876 return count; 2877 } 2878 2879 /* 2880 * Set variables that store noselect and noinsert behavior from the 2881 * 'completeopt' value. 2882 */ 2883 void 2884 completeopt_was_set(void) 2885 { 2886 compl_no_insert = FALSE; 2887 compl_no_select = FALSE; 2888 if (strstr((char *)p_cot, "noselect") != NULL) 2889 compl_no_select = TRUE; 2890 if (strstr((char *)p_cot, "noinsert") != NULL) 2891 compl_no_insert = TRUE; 2892 } 2893 2894 /* 2895 * Start completion for the complete() function. 2896 * "startcol" is where the matched text starts (1 is first column). 2897 * "list" is the list of matches. 2898 */ 2899 void 2900 set_completion(colnr_T startcol, list_T *list) 2901 { 2902 int save_w_wrow = curwin->w_wrow; 2903 int save_w_leftcol = curwin->w_leftcol; 2904 2905 /* If already doing completions stop it. */ 2906 if (ctrl_x_mode != CTRL_X_NORMAL) 2907 ins_compl_prep(' '); 2908 ins_compl_clear(); 2909 ins_compl_free(); 2910 2911 compl_direction = FORWARD; 2912 if (startcol > curwin->w_cursor.col) 2913 startcol = curwin->w_cursor.col; 2914 compl_col = startcol; 2915 compl_length = (int)curwin->w_cursor.col - (int)startcol; 2916 /* compl_pattern doesn't need to be set */ 2917 compl_orig_text = vim_strnsave(ml_get_curline() + compl_col, compl_length); 2918 if (compl_orig_text == NULL || ins_compl_add(compl_orig_text, 2919 -1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK) 2920 return; 2921 2922 ctrl_x_mode = CTRL_X_EVAL; 2923 2924 ins_compl_add_list(list); 2925 compl_matches = ins_compl_make_cyclic(); 2926 compl_started = TRUE; 2927 compl_used_match = TRUE; 2928 compl_cont_status = 0; 2929 2930 compl_curr_match = compl_first_match; 2931 if (compl_no_insert || compl_no_select) 2932 { 2933 ins_complete(K_DOWN, FALSE); 2934 if (compl_no_select) 2935 /* Down/Up has no real effect. */ 2936 ins_complete(K_UP, FALSE); 2937 } 2938 else 2939 ins_complete(Ctrl_N, FALSE); 2940 compl_enter_selects = compl_no_insert; 2941 2942 /* Lazily show the popup menu, unless we got interrupted. */ 2943 if (!compl_interrupted) 2944 show_pum(save_w_wrow, save_w_leftcol); 2945 out_flush(); 2946 } 2947 2948 2949 /* "compl_match_array" points the currently displayed list of entries in the 2950 * popup menu. It is NULL when there is no popup menu. */ 2951 static pumitem_T *compl_match_array = NULL; 2952 static int compl_match_arraysize; 2953 2954 /* 2955 * Update the screen and when there is any scrolling remove the popup menu. 2956 */ 2957 static void 2958 ins_compl_upd_pum(void) 2959 { 2960 int h; 2961 2962 if (compl_match_array != NULL) 2963 { 2964 h = curwin->w_cline_height; 2965 // Update the screen later, before drawing the popup menu over it. 2966 pum_call_update_screen(); 2967 if (h != curwin->w_cline_height) 2968 ins_compl_del_pum(); 2969 } 2970 } 2971 2972 /* 2973 * Remove any popup menu. 2974 */ 2975 static void 2976 ins_compl_del_pum(void) 2977 { 2978 if (compl_match_array != NULL) 2979 { 2980 pum_undisplay(); 2981 VIM_CLEAR(compl_match_array); 2982 } 2983 } 2984 2985 /* 2986 * Return TRUE if the popup menu should be displayed. 2987 */ 2988 static int 2989 pum_wanted(void) 2990 { 2991 /* 'completeopt' must contain "menu" or "menuone" */ 2992 if (vim_strchr(p_cot, 'm') == NULL) 2993 return FALSE; 2994 2995 /* The display looks bad on a B&W display. */ 2996 if (t_colors < 8 2997 #ifdef FEAT_GUI 2998 && !gui.in_use 2999 #endif 3000 ) 3001 return FALSE; 3002 return TRUE; 3003 } 3004 3005 /* 3006 * Return TRUE if there are two or more matches to be shown in the popup menu. 3007 * One if 'completopt' contains "menuone". 3008 */ 3009 static int 3010 pum_enough_matches(void) 3011 { 3012 compl_T *compl; 3013 int i; 3014 3015 /* Don't display the popup menu if there are no matches or there is only 3016 * one (ignoring the original text). */ 3017 compl = compl_first_match; 3018 i = 0; 3019 do 3020 { 3021 if (compl == NULL 3022 || ((compl->cp_flags & ORIGINAL_TEXT) == 0 && ++i == 2)) 3023 break; 3024 compl = compl->cp_next; 3025 } while (compl != compl_first_match); 3026 3027 if (strstr((char *)p_cot, "menuone") != NULL) 3028 return (i >= 1); 3029 return (i >= 2); 3030 } 3031 3032 /* 3033 * Show the popup menu for the list of matches. 3034 * Also adjusts "compl_shown_match" to an entry that is actually displayed. 3035 */ 3036 void 3037 ins_compl_show_pum(void) 3038 { 3039 compl_T *compl; 3040 compl_T *shown_compl = NULL; 3041 int did_find_shown_match = FALSE; 3042 int shown_match_ok = FALSE; 3043 int i; 3044 int cur = -1; 3045 colnr_T col; 3046 int lead_len = 0; 3047 3048 if (!pum_wanted() || !pum_enough_matches()) 3049 return; 3050 3051 #if defined(FEAT_EVAL) 3052 /* Dirty hard-coded hack: remove any matchparen highlighting. */ 3053 do_cmdline_cmd((char_u *)"if exists('g:loaded_matchparen')|3match none|endif"); 3054 #endif 3055 3056 // Update the screen later, before drawing the popup menu over it. 3057 pum_call_update_screen(); 3058 3059 if (compl_match_array == NULL) 3060 { 3061 /* Need to build the popup menu list. */ 3062 compl_match_arraysize = 0; 3063 compl = compl_first_match; 3064 if (compl_leader != NULL) 3065 lead_len = (int)STRLEN(compl_leader); 3066 do 3067 { 3068 if ((compl->cp_flags & ORIGINAL_TEXT) == 0 3069 && (compl_leader == NULL 3070 || ins_compl_equal(compl, compl_leader, lead_len))) 3071 ++compl_match_arraysize; 3072 compl = compl->cp_next; 3073 } while (compl != NULL && compl != compl_first_match); 3074 if (compl_match_arraysize == 0) 3075 return; 3076 compl_match_array = (pumitem_T *)alloc_clear( 3077 (unsigned)(sizeof(pumitem_T) 3078 * compl_match_arraysize)); 3079 if (compl_match_array != NULL) 3080 { 3081 /* If the current match is the original text don't find the first 3082 * match after it, don't highlight anything. */ 3083 if (compl_shown_match->cp_flags & ORIGINAL_TEXT) 3084 shown_match_ok = TRUE; 3085 3086 i = 0; 3087 compl = compl_first_match; 3088 do 3089 { 3090 if ((compl->cp_flags & ORIGINAL_TEXT) == 0 3091 && (compl_leader == NULL 3092 || ins_compl_equal(compl, compl_leader, lead_len))) 3093 { 3094 if (!shown_match_ok) 3095 { 3096 if (compl == compl_shown_match || did_find_shown_match) 3097 { 3098 /* This item is the shown match or this is the 3099 * first displayed item after the shown match. */ 3100 compl_shown_match = compl; 3101 did_find_shown_match = TRUE; 3102 shown_match_ok = TRUE; 3103 } 3104 else 3105 /* Remember this displayed match for when the 3106 * shown match is just below it. */ 3107 shown_compl = compl; 3108 cur = i; 3109 } 3110 3111 if (compl->cp_text[CPT_ABBR] != NULL) 3112 compl_match_array[i].pum_text = 3113 compl->cp_text[CPT_ABBR]; 3114 else 3115 compl_match_array[i].pum_text = compl->cp_str; 3116 compl_match_array[i].pum_kind = compl->cp_text[CPT_KIND]; 3117 compl_match_array[i].pum_info = compl->cp_text[CPT_INFO]; 3118 if (compl->cp_text[CPT_MENU] != NULL) 3119 compl_match_array[i++].pum_extra = 3120 compl->cp_text[CPT_MENU]; 3121 else 3122 compl_match_array[i++].pum_extra = compl->cp_fname; 3123 } 3124 3125 if (compl == compl_shown_match) 3126 { 3127 did_find_shown_match = TRUE; 3128 3129 /* When the original text is the shown match don't set 3130 * compl_shown_match. */ 3131 if (compl->cp_flags & ORIGINAL_TEXT) 3132 shown_match_ok = TRUE; 3133 3134 if (!shown_match_ok && shown_compl != NULL) 3135 { 3136 /* The shown match isn't displayed, set it to the 3137 * previously displayed match. */ 3138 compl_shown_match = shown_compl; 3139 shown_match_ok = TRUE; 3140 } 3141 } 3142 compl = compl->cp_next; 3143 } while (compl != NULL && compl != compl_first_match); 3144 3145 if (!shown_match_ok) /* no displayed match at all */ 3146 cur = -1; 3147 } 3148 } 3149 else 3150 { 3151 /* popup menu already exists, only need to find the current item.*/ 3152 for (i = 0; i < compl_match_arraysize; ++i) 3153 if (compl_match_array[i].pum_text == compl_shown_match->cp_str 3154 || compl_match_array[i].pum_text 3155 == compl_shown_match->cp_text[CPT_ABBR]) 3156 { 3157 cur = i; 3158 break; 3159 } 3160 } 3161 3162 if (compl_match_array != NULL) 3163 { 3164 /* In Replace mode when a $ is displayed at the end of the line only 3165 * part of the screen would be updated. We do need to redraw here. */ 3166 dollar_vcol = -1; 3167 3168 /* Compute the screen column of the start of the completed text. 3169 * Use the cursor to get all wrapping and other settings right. */ 3170 col = curwin->w_cursor.col; 3171 curwin->w_cursor.col = compl_col; 3172 pum_display(compl_match_array, compl_match_arraysize, cur); 3173 curwin->w_cursor.col = col; 3174 } 3175 } 3176 3177 #define DICT_FIRST (1) /* use just first element in "dict" */ 3178 #define DICT_EXACT (2) /* "dict" is the exact name of a file */ 3179 3180 /* 3181 * Add any identifiers that match the given pattern in the list of dictionary 3182 * files "dict_start" to the list of completions. 3183 */ 3184 static void 3185 ins_compl_dictionaries( 3186 char_u *dict_start, 3187 char_u *pat, 3188 int flags, /* DICT_FIRST and/or DICT_EXACT */ 3189 int thesaurus) /* Thesaurus completion */ 3190 { 3191 char_u *dict = dict_start; 3192 char_u *ptr; 3193 char_u *buf; 3194 regmatch_T regmatch; 3195 char_u **files; 3196 int count; 3197 int save_p_scs; 3198 int dir = compl_direction; 3199 3200 if (*dict == NUL) 3201 { 3202 #ifdef FEAT_SPELL 3203 /* When 'dictionary' is empty and spell checking is enabled use 3204 * "spell". */ 3205 if (!thesaurus && curwin->w_p_spell) 3206 dict = (char_u *)"spell"; 3207 else 3208 #endif 3209 return; 3210 } 3211 3212 buf = alloc(LSIZE); 3213 if (buf == NULL) 3214 return; 3215 regmatch.regprog = NULL; /* so that we can goto theend */ 3216 3217 /* If 'infercase' is set, don't use 'smartcase' here */ 3218 save_p_scs = p_scs; 3219 if (curbuf->b_p_inf) 3220 p_scs = FALSE; 3221 3222 /* When invoked to match whole lines for CTRL-X CTRL-L adjust the pattern 3223 * to only match at the start of a line. Otherwise just match the 3224 * pattern. Also need to double backslashes. */ 3225 if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) 3226 { 3227 char_u *pat_esc = vim_strsave_escaped(pat, (char_u *)"\\"); 3228 size_t len; 3229 3230 if (pat_esc == NULL) 3231 goto theend; 3232 len = STRLEN(pat_esc) + 10; 3233 ptr = alloc((unsigned)len); 3234 if (ptr == NULL) 3235 { 3236 vim_free(pat_esc); 3237 goto theend; 3238 } 3239 vim_snprintf((char *)ptr, len, "^\\s*\\zs\\V%s", pat_esc); 3240 regmatch.regprog = vim_regcomp(ptr, RE_MAGIC); 3241 vim_free(pat_esc); 3242 vim_free(ptr); 3243 } 3244 else 3245 { 3246 regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0); 3247 if (regmatch.regprog == NULL) 3248 goto theend; 3249 } 3250 3251 /* ignore case depends on 'ignorecase', 'smartcase' and "pat" */ 3252 regmatch.rm_ic = ignorecase(pat); 3253 while (*dict != NUL && !got_int && !compl_interrupted) 3254 { 3255 /* copy one dictionary file name into buf */ 3256 if (flags == DICT_EXACT) 3257 { 3258 count = 1; 3259 files = &dict; 3260 } 3261 else 3262 { 3263 /* Expand wildcards in the dictionary name, but do not allow 3264 * backticks (for security, the 'dict' option may have been set in 3265 * a modeline). */ 3266 copy_option_part(&dict, buf, LSIZE, ","); 3267 # ifdef FEAT_SPELL 3268 if (!thesaurus && STRCMP(buf, "spell") == 0) 3269 count = -1; 3270 else 3271 # endif 3272 if (vim_strchr(buf, '`') != NULL 3273 || expand_wildcards(1, &buf, &count, &files, 3274 EW_FILE|EW_SILENT) != OK) 3275 count = 0; 3276 } 3277 3278 # ifdef FEAT_SPELL 3279 if (count == -1) 3280 { 3281 /* Complete from active spelling. Skip "\<" in the pattern, we 3282 * don't use it as a RE. */ 3283 if (pat[0] == '\\' && pat[1] == '<') 3284 ptr = pat + 2; 3285 else 3286 ptr = pat; 3287 spell_dump_compl(ptr, regmatch.rm_ic, &dir, 0); 3288 } 3289 else 3290 # endif 3291 if (count > 0) /* avoid warning for using "files" uninit */ 3292 { 3293 ins_compl_files(count, files, thesaurus, flags, 3294 ®match, buf, &dir); 3295 if (flags != DICT_EXACT) 3296 FreeWild(count, files); 3297 } 3298 if (flags != 0) 3299 break; 3300 } 3301 3302 theend: 3303 p_scs = save_p_scs; 3304 vim_regfree(regmatch.regprog); 3305 vim_free(buf); 3306 } 3307 3308 static void 3309 ins_compl_files( 3310 int count, 3311 char_u **files, 3312 int thesaurus, 3313 int flags, 3314 regmatch_T *regmatch, 3315 char_u *buf, 3316 int *dir) 3317 { 3318 char_u *ptr; 3319 int i; 3320 FILE *fp; 3321 int add_r; 3322 3323 for (i = 0; i < count && !got_int && !compl_interrupted; i++) 3324 { 3325 fp = mch_fopen((char *)files[i], "r"); /* open dictionary file */ 3326 if (flags != DICT_EXACT) 3327 { 3328 vim_snprintf((char *)IObuff, IOSIZE, 3329 _("Scanning dictionary: %s"), (char *)files[i]); 3330 (void)msg_trunc_attr((char *)IObuff, TRUE, HL_ATTR(HLF_R)); 3331 } 3332 3333 if (fp != NULL) 3334 { 3335 /* 3336 * Read dictionary file line by line. 3337 * Check each line for a match. 3338 */ 3339 while (!got_int && !compl_interrupted 3340 && !vim_fgets(buf, LSIZE, fp)) 3341 { 3342 ptr = buf; 3343 while (vim_regexec(regmatch, buf, (colnr_T)(ptr - buf))) 3344 { 3345 ptr = regmatch->startp[0]; 3346 if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) 3347 ptr = find_line_end(ptr); 3348 else 3349 ptr = find_word_end(ptr); 3350 add_r = ins_compl_add_infercase(regmatch->startp[0], 3351 (int)(ptr - regmatch->startp[0]), 3352 p_ic, files[i], *dir, 0); 3353 if (thesaurus) 3354 { 3355 char_u *wstart; 3356 3357 /* 3358 * Add the other matches on the line 3359 */ 3360 ptr = buf; 3361 while (!got_int) 3362 { 3363 /* Find start of the next word. Skip white 3364 * space and punctuation. */ 3365 ptr = find_word_start(ptr); 3366 if (*ptr == NUL || *ptr == NL) 3367 break; 3368 wstart = ptr; 3369 3370 /* Find end of the word. */ 3371 if (has_mbyte) 3372 /* Japanese words may have characters in 3373 * different classes, only separate words 3374 * with single-byte non-word characters. */ 3375 while (*ptr != NUL) 3376 { 3377 int l = (*mb_ptr2len)(ptr); 3378 3379 if (l < 2 && !vim_iswordc(*ptr)) 3380 break; 3381 ptr += l; 3382 } 3383 else 3384 ptr = find_word_end(ptr); 3385 3386 /* Add the word. Skip the regexp match. */ 3387 if (wstart != regmatch->startp[0]) 3388 add_r = ins_compl_add_infercase(wstart, 3389 (int)(ptr - wstart), 3390 p_ic, files[i], *dir, 0); 3391 } 3392 } 3393 if (add_r == OK) 3394 /* if dir was BACKWARD then honor it just once */ 3395 *dir = FORWARD; 3396 else if (add_r == FAIL) 3397 break; 3398 /* avoid expensive call to vim_regexec() when at end 3399 * of line */ 3400 if (*ptr == '\n' || got_int) 3401 break; 3402 } 3403 line_breakcheck(); 3404 ins_compl_check_keys(50, FALSE); 3405 } 3406 fclose(fp); 3407 } 3408 } 3409 } 3410 3411 /* 3412 * Find the start of the next word. 3413 * Returns a pointer to the first char of the word. Also stops at a NUL. 3414 */ 3415 char_u * 3416 find_word_start(char_u *ptr) 3417 { 3418 if (has_mbyte) 3419 while (*ptr != NUL && *ptr != '\n' && mb_get_class(ptr) <= 1) 3420 ptr += (*mb_ptr2len)(ptr); 3421 else 3422 while (*ptr != NUL && *ptr != '\n' && !vim_iswordc(*ptr)) 3423 ++ptr; 3424 return ptr; 3425 } 3426 3427 /* 3428 * Find the end of the word. Assumes it starts inside a word. 3429 * Returns a pointer to just after the word. 3430 */ 3431 char_u * 3432 find_word_end(char_u *ptr) 3433 { 3434 int start_class; 3435 3436 if (has_mbyte) 3437 { 3438 start_class = mb_get_class(ptr); 3439 if (start_class > 1) 3440 while (*ptr != NUL) 3441 { 3442 ptr += (*mb_ptr2len)(ptr); 3443 if (mb_get_class(ptr) != start_class) 3444 break; 3445 } 3446 } 3447 else 3448 while (vim_iswordc(*ptr)) 3449 ++ptr; 3450 return ptr; 3451 } 3452 3453 /* 3454 * Find the end of the line, omitting CR and NL at the end. 3455 * Returns a pointer to just after the line. 3456 */ 3457 static char_u * 3458 find_line_end(char_u *ptr) 3459 { 3460 char_u *s; 3461 3462 s = ptr + STRLEN(ptr); 3463 while (s > ptr && (s[-1] == CAR || s[-1] == NL)) 3464 --s; 3465 return s; 3466 } 3467 3468 /* 3469 * Free the list of completions 3470 */ 3471 static void 3472 ins_compl_free(void) 3473 { 3474 compl_T *match; 3475 int i; 3476 3477 VIM_CLEAR(compl_pattern); 3478 VIM_CLEAR(compl_leader); 3479 3480 if (compl_first_match == NULL) 3481 return; 3482 3483 ins_compl_del_pum(); 3484 pum_clear(); 3485 3486 compl_curr_match = compl_first_match; 3487 do 3488 { 3489 match = compl_curr_match; 3490 compl_curr_match = compl_curr_match->cp_next; 3491 vim_free(match->cp_str); 3492 /* several entries may use the same fname, free it just once. */ 3493 if (match->cp_flags & FREE_FNAME) 3494 vim_free(match->cp_fname); 3495 for (i = 0; i < CPT_COUNT; ++i) 3496 vim_free(match->cp_text[i]); 3497 vim_free(match); 3498 } while (compl_curr_match != NULL && compl_curr_match != compl_first_match); 3499 compl_first_match = compl_curr_match = NULL; 3500 compl_shown_match = NULL; 3501 compl_old_match = NULL; 3502 } 3503 3504 static void 3505 ins_compl_clear(void) 3506 { 3507 compl_cont_status = 0; 3508 compl_started = FALSE; 3509 compl_matches = 0; 3510 VIM_CLEAR(compl_pattern); 3511 VIM_CLEAR(compl_leader); 3512 edit_submode_extra = NULL; 3513 VIM_CLEAR(compl_orig_text); 3514 compl_enter_selects = FALSE; 3515 /* clear v:completed_item */ 3516 set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc_lock(VAR_FIXED)); 3517 } 3518 3519 /* 3520 * Return TRUE when Insert completion is active. 3521 */ 3522 int 3523 ins_compl_active(void) 3524 { 3525 return compl_started; 3526 } 3527 3528 /* 3529 * Delete one character before the cursor and show the subset of the matches 3530 * that match the word that is now before the cursor. 3531 * Returns the character to be used, NUL if the work is done and another char 3532 * to be got from the user. 3533 */ 3534 static int 3535 ins_compl_bs(void) 3536 { 3537 char_u *line; 3538 char_u *p; 3539 3540 line = ml_get_curline(); 3541 p = line + curwin->w_cursor.col; 3542 MB_PTR_BACK(line, p); 3543 3544 /* Stop completion when the whole word was deleted. For Omni completion 3545 * allow the word to be deleted, we won't match everything. 3546 * Respect the 'backspace' option. */ 3547 if ((int)(p - line) - (int)compl_col < 0 3548 || ((int)(p - line) - (int)compl_col == 0 3549 && ctrl_x_mode != CTRL_X_OMNI) || ctrl_x_mode == CTRL_X_EVAL 3550 || (!can_bs(BS_START) && (int)(p - line) - (int)compl_col 3551 - compl_length < 0)) 3552 return K_BS; 3553 3554 /* Deleted more than what was used to find matches or didn't finish 3555 * finding all matches: need to look for matches all over again. */ 3556 if (curwin->w_cursor.col <= compl_col + compl_length 3557 || ins_compl_need_restart()) 3558 ins_compl_restart(); 3559 3560 vim_free(compl_leader); 3561 compl_leader = vim_strnsave(line + compl_col, (int)(p - line) - compl_col); 3562 if (compl_leader != NULL) 3563 { 3564 ins_compl_new_leader(); 3565 if (compl_shown_match != NULL) 3566 /* Make sure current match is not a hidden item. */ 3567 compl_curr_match = compl_shown_match; 3568 return NUL; 3569 } 3570 return K_BS; 3571 } 3572 3573 /* 3574 * Return TRUE when we need to find matches again, ins_compl_restart() is to 3575 * be called. 3576 */ 3577 static int 3578 ins_compl_need_restart(void) 3579 { 3580 /* Return TRUE if we didn't complete finding matches or when the 3581 * 'completefunc' returned "always" in the "refresh" dictionary item. */ 3582 return compl_was_interrupted 3583 || ((ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI) 3584 && compl_opt_refresh_always); 3585 } 3586 3587 /* 3588 * Called after changing "compl_leader". 3589 * Show the popup menu with a different set of matches. 3590 * May also search for matches again if the previous search was interrupted. 3591 */ 3592 static void 3593 ins_compl_new_leader(void) 3594 { 3595 ins_compl_del_pum(); 3596 ins_compl_delete(); 3597 ins_bytes(compl_leader + ins_compl_len()); 3598 compl_used_match = FALSE; 3599 3600 if (compl_started) 3601 ins_compl_set_original_text(compl_leader); 3602 else 3603 { 3604 #ifdef FEAT_SPELL 3605 spell_bad_len = 0; /* need to redetect bad word */ 3606 #endif 3607 /* 3608 * Matches were cleared, need to search for them now. Befor drawing 3609 * the popup menu display the changed text before the cursor. Set 3610 * "compl_restarting" to avoid that the first match is inserted. 3611 */ 3612 pum_call_update_screen(); 3613 #ifdef FEAT_GUI 3614 if (gui.in_use) 3615 { 3616 /* Show the cursor after the match, not after the redrawn text. */ 3617 setcursor(); 3618 out_flush_cursor(FALSE, FALSE); 3619 } 3620 #endif 3621 compl_restarting = TRUE; 3622 if (ins_complete(Ctrl_N, TRUE) == FAIL) 3623 compl_cont_status = 0; 3624 compl_restarting = FALSE; 3625 } 3626 3627 compl_enter_selects = !compl_used_match; 3628 3629 /* Show the popup menu with a different set of matches. */ 3630 ins_compl_show_pum(); 3631 3632 /* Don't let Enter select the original text when there is no popup menu. */ 3633 if (compl_match_array == NULL) 3634 compl_enter_selects = FALSE; 3635 } 3636 3637 /* 3638 * Return the length of the completion, from the completion start column to 3639 * the cursor column. Making sure it never goes below zero. 3640 */ 3641 static int 3642 ins_compl_len(void) 3643 { 3644 int off = (int)curwin->w_cursor.col - (int)compl_col; 3645 3646 if (off < 0) 3647 return 0; 3648 return off; 3649 } 3650 3651 /* 3652 * Append one character to the match leader. May reduce the number of 3653 * matches. 3654 */ 3655 static void 3656 ins_compl_addleader(int c) 3657 { 3658 int cc; 3659 3660 if (stop_arrow() == FAIL) 3661 return; 3662 if (has_mbyte && (cc = (*mb_char2len)(c)) > 1) 3663 { 3664 char_u buf[MB_MAXBYTES + 1]; 3665 3666 (*mb_char2bytes)(c, buf); 3667 buf[cc] = NUL; 3668 ins_char_bytes(buf, cc); 3669 if (compl_opt_refresh_always) 3670 AppendToRedobuff(buf); 3671 } 3672 else 3673 { 3674 ins_char(c); 3675 if (compl_opt_refresh_always) 3676 AppendCharToRedobuff(c); 3677 } 3678 3679 /* If we didn't complete finding matches we must search again. */ 3680 if (ins_compl_need_restart()) 3681 ins_compl_restart(); 3682 3683 /* When 'always' is set, don't reset compl_leader. While completing, 3684 * cursor doesn't point original position, changing compl_leader would 3685 * break redo. */ 3686 if (!compl_opt_refresh_always) 3687 { 3688 vim_free(compl_leader); 3689 compl_leader = vim_strnsave(ml_get_curline() + compl_col, 3690 (int)(curwin->w_cursor.col - compl_col)); 3691 if (compl_leader != NULL) 3692 ins_compl_new_leader(); 3693 } 3694 } 3695 3696 /* 3697 * Setup for finding completions again without leaving CTRL-X mode. Used when 3698 * BS or a key was typed while still searching for matches. 3699 */ 3700 static void 3701 ins_compl_restart(void) 3702 { 3703 ins_compl_free(); 3704 compl_started = FALSE; 3705 compl_matches = 0; 3706 compl_cont_status = 0; 3707 compl_cont_mode = 0; 3708 } 3709 3710 /* 3711 * Set the first match, the original text. 3712 */ 3713 static void 3714 ins_compl_set_original_text(char_u *str) 3715 { 3716 char_u *p; 3717 3718 /* Replace the original text entry. 3719 * The ORIGINAL_TEXT flag is either at the first item or might possibly be 3720 * at the last item for backward completion */ 3721 if (compl_first_match->cp_flags & ORIGINAL_TEXT) /* safety check */ 3722 { 3723 p = vim_strsave(str); 3724 if (p != NULL) 3725 { 3726 vim_free(compl_first_match->cp_str); 3727 compl_first_match->cp_str = p; 3728 } 3729 } 3730 else if (compl_first_match->cp_prev != NULL 3731 && (compl_first_match->cp_prev->cp_flags & ORIGINAL_TEXT)) 3732 { 3733 p = vim_strsave(str); 3734 if (p != NULL) 3735 { 3736 vim_free(compl_first_match->cp_prev->cp_str); 3737 compl_first_match->cp_prev->cp_str = p; 3738 } 3739 } 3740 } 3741 3742 /* 3743 * Append one character to the match leader. May reduce the number of 3744 * matches. 3745 */ 3746 static void 3747 ins_compl_addfrommatch(void) 3748 { 3749 char_u *p; 3750 int len = (int)curwin->w_cursor.col - (int)compl_col; 3751 int c; 3752 compl_T *cp; 3753 3754 p = compl_shown_match->cp_str; 3755 if ((int)STRLEN(p) <= len) /* the match is too short */ 3756 { 3757 /* When still at the original match use the first entry that matches 3758 * the leader. */ 3759 if (compl_shown_match->cp_flags & ORIGINAL_TEXT) 3760 { 3761 p = NULL; 3762 for (cp = compl_shown_match->cp_next; cp != NULL 3763 && cp != compl_first_match; cp = cp->cp_next) 3764 { 3765 if (compl_leader == NULL 3766 || ins_compl_equal(cp, compl_leader, 3767 (int)STRLEN(compl_leader))) 3768 { 3769 p = cp->cp_str; 3770 break; 3771 } 3772 } 3773 if (p == NULL || (int)STRLEN(p) <= len) 3774 return; 3775 } 3776 else 3777 return; 3778 } 3779 p += len; 3780 c = PTR2CHAR(p); 3781 ins_compl_addleader(c); 3782 } 3783 3784 /* 3785 * Prepare for Insert mode completion, or stop it. 3786 * Called just after typing a character in Insert mode. 3787 * Returns TRUE when the character is not to be inserted; 3788 */ 3789 static int 3790 ins_compl_prep(int c) 3791 { 3792 char_u *ptr; 3793 int want_cindent; 3794 int retval = FALSE; 3795 3796 /* Forget any previous 'special' messages if this is actually 3797 * a ^X mode key - bar ^R, in which case we wait to see what it gives us. 3798 */ 3799 if (c != Ctrl_R && vim_is_ctrl_x_key(c)) 3800 edit_submode_extra = NULL; 3801 3802 /* Ignore end of Select mode mapping and mouse scroll buttons. */ 3803 if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP 3804 || c == K_MOUSELEFT || c == K_MOUSERIGHT) 3805 return retval; 3806 3807 /* Set "compl_get_longest" when finding the first matches. */ 3808 if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET 3809 || (ctrl_x_mode == CTRL_X_NORMAL && !compl_started)) 3810 { 3811 compl_get_longest = (strstr((char *)p_cot, "longest") != NULL); 3812 compl_used_match = TRUE; 3813 3814 } 3815 3816 if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET) 3817 { 3818 /* 3819 * We have just typed CTRL-X and aren't quite sure which CTRL-X mode 3820 * it will be yet. Now we decide. 3821 */ 3822 switch (c) 3823 { 3824 case Ctrl_E: 3825 case Ctrl_Y: 3826 ctrl_x_mode = CTRL_X_SCROLL; 3827 if (!(State & REPLACE_FLAG)) 3828 edit_submode = (char_u *)_(" (insert) Scroll (^E/^Y)"); 3829 else 3830 edit_submode = (char_u *)_(" (replace) Scroll (^E/^Y)"); 3831 edit_submode_pre = NULL; 3832 showmode(); 3833 break; 3834 case Ctrl_L: 3835 ctrl_x_mode = CTRL_X_WHOLE_LINE; 3836 break; 3837 case Ctrl_F: 3838 ctrl_x_mode = CTRL_X_FILES; 3839 break; 3840 case Ctrl_K: 3841 ctrl_x_mode = CTRL_X_DICTIONARY; 3842 break; 3843 case Ctrl_R: 3844 /* Simply allow ^R to happen without affecting ^X mode */ 3845 break; 3846 case Ctrl_T: 3847 ctrl_x_mode = CTRL_X_THESAURUS; 3848 break; 3849 #ifdef FEAT_COMPL_FUNC 3850 case Ctrl_U: 3851 ctrl_x_mode = CTRL_X_FUNCTION; 3852 break; 3853 case Ctrl_O: 3854 ctrl_x_mode = CTRL_X_OMNI; 3855 break; 3856 #endif 3857 case 's': 3858 case Ctrl_S: 3859 ctrl_x_mode = CTRL_X_SPELL; 3860 #ifdef FEAT_SPELL 3861 ++emsg_off; /* Avoid getting the E756 error twice. */ 3862 spell_back_to_badword(); 3863 --emsg_off; 3864 #endif 3865 break; 3866 case Ctrl_RSB: 3867 ctrl_x_mode = CTRL_X_TAGS; 3868 break; 3869 #ifdef FEAT_FIND_ID 3870 case Ctrl_I: 3871 case K_S_TAB: 3872 ctrl_x_mode = CTRL_X_PATH_PATTERNS; 3873 break; 3874 case Ctrl_D: 3875 ctrl_x_mode = CTRL_X_PATH_DEFINES; 3876 break; 3877 #endif 3878 case Ctrl_V: 3879 case Ctrl_Q: 3880 ctrl_x_mode = CTRL_X_CMDLINE; 3881 break; 3882 case Ctrl_P: 3883 case Ctrl_N: 3884 /* ^X^P means LOCAL expansion if nothing interrupted (eg we 3885 * just started ^X mode, or there were enough ^X's to cancel 3886 * the previous mode, say ^X^F^X^X^P or ^P^X^X^X^P, see below) 3887 * do normal expansion when interrupting a different mode (say 3888 * ^X^F^X^P or ^P^X^X^P, see below) 3889 * nothing changes if interrupting mode 0, (eg, the flag 3890 * doesn't change when going to ADDING mode -- Acevedo */ 3891 if (!(compl_cont_status & CONT_INTRPT)) 3892 compl_cont_status |= CONT_LOCAL; 3893 else if (compl_cont_mode != 0) 3894 compl_cont_status &= ~CONT_LOCAL; 3895 /* FALLTHROUGH */ 3896 default: 3897 /* If we have typed at least 2 ^X's... for modes != 0, we set 3898 * compl_cont_status = 0 (eg, as if we had just started ^X 3899 * mode). 3900 * For mode 0, we set "compl_cont_mode" to an impossible 3901 * value, in both cases ^X^X can be used to restart the same 3902 * mode (avoiding ADDING mode). 3903 * Undocumented feature: In a mode != 0 ^X^P and ^X^X^P start 3904 * 'complete' and local ^P expansions respectively. 3905 * In mode 0 an extra ^X is needed since ^X^P goes to ADDING 3906 * mode -- Acevedo */ 3907 if (c == Ctrl_X) 3908 { 3909 if (compl_cont_mode != 0) 3910 compl_cont_status = 0; 3911 else 3912 compl_cont_mode = CTRL_X_NOT_DEFINED_YET; 3913 } 3914 ctrl_x_mode = CTRL_X_NORMAL; 3915 edit_submode = NULL; 3916 showmode(); 3917 break; 3918 } 3919 } 3920 else if (ctrl_x_mode != CTRL_X_NORMAL) 3921 { 3922 /* We're already in CTRL-X mode, do we stay in it? */ 3923 if (!vim_is_ctrl_x_key(c)) 3924 { 3925 if (ctrl_x_mode == CTRL_X_SCROLL) 3926 ctrl_x_mode = CTRL_X_NORMAL; 3927 else 3928 ctrl_x_mode = CTRL_X_FINISHED; 3929 edit_submode = NULL; 3930 } 3931 showmode(); 3932 } 3933 3934 if (compl_started || ctrl_x_mode == CTRL_X_FINISHED) 3935 { 3936 /* Show error message from attempted keyword completion (probably 3937 * 'Pattern not found') until another key is hit, then go back to 3938 * showing what mode we are in. */ 3939 showmode(); 3940 if ((ctrl_x_mode == CTRL_X_NORMAL && c != Ctrl_N && c != Ctrl_P 3941 && c != Ctrl_R && !ins_compl_pum_key(c)) 3942 || ctrl_x_mode == CTRL_X_FINISHED) 3943 { 3944 /* Get here when we have finished typing a sequence of ^N and 3945 * ^P or other completion characters in CTRL-X mode. Free up 3946 * memory that was used, and make sure we can redo the insert. */ 3947 if (compl_curr_match != NULL || compl_leader != NULL || c == Ctrl_E) 3948 { 3949 /* 3950 * If any of the original typed text has been changed, eg when 3951 * ignorecase is set, we must add back-spaces to the redo 3952 * buffer. We add as few as necessary to delete just the part 3953 * of the original text that has changed. 3954 * When using the longest match, edited the match or used 3955 * CTRL-E then don't use the current match. 3956 */ 3957 if (compl_curr_match != NULL && compl_used_match && c != Ctrl_E) 3958 ptr = compl_curr_match->cp_str; 3959 else 3960 ptr = NULL; 3961 ins_compl_fixRedoBufForLeader(ptr); 3962 } 3963 3964 #ifdef FEAT_CINDENT 3965 want_cindent = (can_cindent && cindent_on()); 3966 #endif 3967 /* 3968 * When completing whole lines: fix indent for 'cindent'. 3969 * Otherwise, break line if it's too long. 3970 */ 3971 if (compl_cont_mode == CTRL_X_WHOLE_LINE) 3972 { 3973 #ifdef FEAT_CINDENT 3974 /* re-indent the current line */ 3975 if (want_cindent) 3976 { 3977 do_c_expr_indent(); 3978 want_cindent = FALSE; /* don't do it again */ 3979 } 3980 #endif 3981 } 3982 else 3983 { 3984 int prev_col = curwin->w_cursor.col; 3985 3986 /* put the cursor on the last char, for 'tw' formatting */ 3987 if (prev_col > 0) 3988 dec_cursor(); 3989 /* only format when something was inserted */ 3990 if (!arrow_used && !ins_need_undo && c != Ctrl_E) 3991 insertchar(NUL, 0, -1); 3992 if (prev_col > 0 3993 && ml_get_curline()[curwin->w_cursor.col] != NUL) 3994 inc_cursor(); 3995 } 3996 3997 /* If the popup menu is displayed pressing CTRL-Y means accepting 3998 * the selection without inserting anything. When 3999 * compl_enter_selects is set the Enter key does the same. */ 4000 if ((c == Ctrl_Y || (compl_enter_selects 4001 && (c == CAR || c == K_KENTER || c == NL))) 4002 && pum_visible()) 4003 retval = TRUE; 4004 4005 /* CTRL-E means completion is Ended, go back to the typed text. 4006 * but only do this, if the Popup is still visible */ 4007 if (c == Ctrl_E) 4008 { 4009 ins_compl_delete(); 4010 if (compl_leader != NULL) 4011 ins_bytes(compl_leader + ins_compl_len()); 4012 else if (compl_first_match != NULL) 4013 ins_bytes(compl_orig_text + ins_compl_len()); 4014 retval = TRUE; 4015 } 4016 4017 auto_format(FALSE, TRUE); 4018 4019 ins_compl_free(); 4020 compl_started = FALSE; 4021 compl_matches = 0; 4022 if (!shortmess(SHM_COMPLETIONMENU)) 4023 msg_clr_cmdline(); /* necessary for "noshowmode" */ 4024 ctrl_x_mode = CTRL_X_NORMAL; 4025 compl_enter_selects = FALSE; 4026 if (edit_submode != NULL) 4027 { 4028 edit_submode = NULL; 4029 showmode(); 4030 } 4031 4032 #ifdef FEAT_CMDWIN 4033 if (c == Ctrl_C && cmdwin_type != 0) 4034 /* Avoid the popup menu remains displayed when leaving the 4035 * command line window. */ 4036 update_screen(0); 4037 #endif 4038 #ifdef FEAT_CINDENT 4039 /* 4040 * Indent now if a key was typed that is in 'cinkeys'. 4041 */ 4042 if (want_cindent && in_cinkeys(KEY_COMPLETE, ' ', inindent(0))) 4043 do_c_expr_indent(); 4044 #endif 4045 /* Trigger the CompleteDone event to give scripts a chance to act 4046 * upon the completion. */ 4047 ins_apply_autocmds(EVENT_COMPLETEDONE); 4048 } 4049 } 4050 else if (ctrl_x_mode == CTRL_X_LOCAL_MSG) 4051 /* Trigger the CompleteDone event to give scripts a chance to act 4052 * upon the (possibly failed) completion. */ 4053 ins_apply_autocmds(EVENT_COMPLETEDONE); 4054 4055 /* reset continue_* if we left expansion-mode, if we stay they'll be 4056 * (re)set properly in ins_complete() */ 4057 if (!vim_is_ctrl_x_key(c)) 4058 { 4059 compl_cont_status = 0; 4060 compl_cont_mode = 0; 4061 } 4062 4063 return retval; 4064 } 4065 4066 /* 4067 * Fix the redo buffer for the completion leader replacing some of the typed 4068 * text. This inserts backspaces and appends the changed text. 4069 * "ptr" is the known leader text or NUL. 4070 */ 4071 static void 4072 ins_compl_fixRedoBufForLeader(char_u *ptr_arg) 4073 { 4074 int len; 4075 char_u *p; 4076 char_u *ptr = ptr_arg; 4077 4078 if (ptr == NULL) 4079 { 4080 if (compl_leader != NULL) 4081 ptr = compl_leader; 4082 else 4083 return; /* nothing to do */ 4084 } 4085 if (compl_orig_text != NULL) 4086 { 4087 p = compl_orig_text; 4088 for (len = 0; p[len] != NUL && p[len] == ptr[len]; ++len) 4089 ; 4090 if (len > 0) 4091 len -= (*mb_head_off)(p, p + len); 4092 for (p += len; *p != NUL; MB_PTR_ADV(p)) 4093 AppendCharToRedobuff(K_BS); 4094 } 4095 else 4096 len = 0; 4097 if (ptr != NULL) 4098 AppendToRedobuffLit(ptr + len, -1); 4099 } 4100 4101 /* 4102 * Loops through the list of windows, loaded-buffers or non-loaded-buffers 4103 * (depending on flag) starting from buf and looking for a non-scanned 4104 * buffer (other than curbuf). curbuf is special, if it is called with 4105 * buf=curbuf then it has to be the first call for a given flag/expansion. 4106 * 4107 * Returns the buffer to scan, if any, otherwise returns curbuf -- Acevedo 4108 */ 4109 static buf_T * 4110 ins_compl_next_buf(buf_T *buf, int flag) 4111 { 4112 static win_T *wp; 4113 4114 if (flag == 'w') /* just windows */ 4115 { 4116 if (buf == curbuf) /* first call for this flag/expansion */ 4117 wp = curwin; 4118 while ((wp = (wp->w_next != NULL ? wp->w_next : firstwin)) != curwin 4119 && wp->w_buffer->b_scanned) 4120 ; 4121 buf = wp->w_buffer; 4122 } 4123 else 4124 /* 'b' (just loaded buffers), 'u' (just non-loaded buffers) or 'U' 4125 * (unlisted buffers) 4126 * When completing whole lines skip unloaded buffers. */ 4127 while ((buf = (buf->b_next != NULL ? buf->b_next : firstbuf)) != curbuf 4128 && ((flag == 'U' 4129 ? buf->b_p_bl 4130 : (!buf->b_p_bl 4131 || (buf->b_ml.ml_mfp == NULL) != (flag == 'u'))) 4132 || buf->b_scanned)) 4133 ; 4134 return buf; 4135 } 4136 4137 #ifdef FEAT_COMPL_FUNC 4138 /* 4139 * Execute user defined complete function 'completefunc' or 'omnifunc', and 4140 * get matches in "matches". 4141 */ 4142 static void 4143 expand_by_function( 4144 int type, /* CTRL_X_OMNI or CTRL_X_FUNCTION */ 4145 char_u *base) 4146 { 4147 list_T *matchlist = NULL; 4148 dict_T *matchdict = NULL; 4149 typval_T args[3]; 4150 char_u *funcname; 4151 pos_T pos; 4152 win_T *curwin_save; 4153 buf_T *curbuf_save; 4154 typval_T rettv; 4155 int save_State = State; 4156 4157 funcname = (type == CTRL_X_FUNCTION) ? curbuf->b_p_cfu : curbuf->b_p_ofu; 4158 if (*funcname == NUL) 4159 return; 4160 4161 /* Call 'completefunc' to obtain the list of matches. */ 4162 args[0].v_type = VAR_NUMBER; 4163 args[0].vval.v_number = 0; 4164 args[1].v_type = VAR_STRING; 4165 args[1].vval.v_string = base != NULL ? base : (char_u *)""; 4166 args[2].v_type = VAR_UNKNOWN; 4167 4168 pos = curwin->w_cursor; 4169 curwin_save = curwin; 4170 curbuf_save = curbuf; 4171 4172 /* Call a function, which returns a list or dict. */ 4173 if (call_vim_function(funcname, 2, args, &rettv) == OK) 4174 { 4175 switch (rettv.v_type) 4176 { 4177 case VAR_LIST: 4178 matchlist = rettv.vval.v_list; 4179 break; 4180 case VAR_DICT: 4181 matchdict = rettv.vval.v_dict; 4182 break; 4183 case VAR_SPECIAL: 4184 if (rettv.vval.v_number == VVAL_NONE) 4185 compl_opt_suppress_empty = TRUE; 4186 // FALLTHROUGH 4187 default: 4188 // TODO: Give error message? 4189 clear_tv(&rettv); 4190 break; 4191 } 4192 } 4193 4194 if (curwin_save != curwin || curbuf_save != curbuf) 4195 { 4196 emsg(_(e_complwin)); 4197 goto theend; 4198 } 4199 curwin->w_cursor = pos; /* restore the cursor position */ 4200 validate_cursor(); 4201 if (!EQUAL_POS(curwin->w_cursor, pos)) 4202 { 4203 emsg(_(e_compldel)); 4204 goto theend; 4205 } 4206 4207 if (matchlist != NULL) 4208 ins_compl_add_list(matchlist); 4209 else if (matchdict != NULL) 4210 ins_compl_add_dict(matchdict); 4211 4212 theend: 4213 // Restore State, it might have been changed. 4214 State = save_State; 4215 4216 if (matchdict != NULL) 4217 dict_unref(matchdict); 4218 if (matchlist != NULL) 4219 list_unref(matchlist); 4220 } 4221 #endif /* FEAT_COMPL_FUNC */ 4222 4223 #if defined(FEAT_COMPL_FUNC) || defined(FEAT_EVAL) || defined(PROTO) 4224 /* 4225 * Add completions from a list. 4226 */ 4227 static void 4228 ins_compl_add_list(list_T *list) 4229 { 4230 listitem_T *li; 4231 int dir = compl_direction; 4232 4233 /* Go through the List with matches and add each of them. */ 4234 for (li = list->lv_first; li != NULL; li = li->li_next) 4235 { 4236 if (ins_compl_add_tv(&li->li_tv, dir) == OK) 4237 /* if dir was BACKWARD then honor it just once */ 4238 dir = FORWARD; 4239 else if (did_emsg) 4240 break; 4241 } 4242 } 4243 4244 /* 4245 * Add completions from a dict. 4246 */ 4247 static void 4248 ins_compl_add_dict(dict_T *dict) 4249 { 4250 dictitem_T *di_refresh; 4251 dictitem_T *di_words; 4252 4253 /* Check for optional "refresh" item. */ 4254 compl_opt_refresh_always = FALSE; 4255 di_refresh = dict_find(dict, (char_u *)"refresh", 7); 4256 if (di_refresh != NULL && di_refresh->di_tv.v_type == VAR_STRING) 4257 { 4258 char_u *v = di_refresh->di_tv.vval.v_string; 4259 4260 if (v != NULL && STRCMP(v, (char_u *)"always") == 0) 4261 compl_opt_refresh_always = TRUE; 4262 } 4263 4264 /* Add completions from a "words" list. */ 4265 di_words = dict_find(dict, (char_u *)"words", 5); 4266 if (di_words != NULL && di_words->di_tv.v_type == VAR_LIST) 4267 ins_compl_add_list(di_words->di_tv.vval.v_list); 4268 } 4269 4270 /* 4271 * Add a match to the list of matches from a typeval_T. 4272 * If the given string is already in the list of completions, then return 4273 * NOTDONE, otherwise add it to the list and return OK. If there is an error, 4274 * maybe because alloc() returns NULL, then FAIL is returned. 4275 */ 4276 int 4277 ins_compl_add_tv(typval_T *tv, int dir) 4278 { 4279 char_u *word; 4280 int icase = FALSE; 4281 int adup = FALSE; 4282 int aempty = FALSE; 4283 char_u *(cptext[CPT_COUNT]); 4284 4285 if (tv->v_type == VAR_DICT && tv->vval.v_dict != NULL) 4286 { 4287 word = dict_get_string(tv->vval.v_dict, (char_u *)"word", FALSE); 4288 cptext[CPT_ABBR] = dict_get_string(tv->vval.v_dict, 4289 (char_u *)"abbr", FALSE); 4290 cptext[CPT_MENU] = dict_get_string(tv->vval.v_dict, 4291 (char_u *)"menu", FALSE); 4292 cptext[CPT_KIND] = dict_get_string(tv->vval.v_dict, 4293 (char_u *)"kind", FALSE); 4294 cptext[CPT_INFO] = dict_get_string(tv->vval.v_dict, 4295 (char_u *)"info", FALSE); 4296 cptext[CPT_USER_DATA] = dict_get_string(tv->vval.v_dict, 4297 (char_u *)"user_data", FALSE); 4298 if (dict_get_string(tv->vval.v_dict, (char_u *)"icase", FALSE) != NULL) 4299 icase = dict_get_number(tv->vval.v_dict, (char_u *)"icase"); 4300 if (dict_get_string(tv->vval.v_dict, (char_u *)"dup", FALSE) != NULL) 4301 adup = dict_get_number(tv->vval.v_dict, (char_u *)"dup"); 4302 if (dict_get_string(tv->vval.v_dict, (char_u *)"empty", FALSE) != NULL) 4303 aempty = dict_get_number(tv->vval.v_dict, (char_u *)"empty"); 4304 } 4305 else 4306 { 4307 word = tv_get_string_chk(tv); 4308 vim_memset(cptext, 0, sizeof(cptext)); 4309 } 4310 if (word == NULL || (!aempty && *word == NUL)) 4311 return FAIL; 4312 return ins_compl_add(word, -1, icase, NULL, cptext, dir, 0, adup); 4313 } 4314 #endif 4315 4316 /* 4317 * Get the next expansion(s), using "compl_pattern". 4318 * The search starts at position "ini" in curbuf and in the direction 4319 * compl_direction. 4320 * When "compl_started" is FALSE start at that position, otherwise continue 4321 * where we stopped searching before. 4322 * This may return before finding all the matches. 4323 * Return the total number of matches or -1 if still unknown -- Acevedo 4324 */ 4325 static int 4326 ins_compl_get_exp(pos_T *ini) 4327 { 4328 static pos_T first_match_pos; 4329 static pos_T last_match_pos; 4330 static char_u *e_cpt = (char_u *)""; /* curr. entry in 'complete' */ 4331 static int found_all = FALSE; /* Found all matches of a 4332 certain type. */ 4333 static buf_T *ins_buf = NULL; /* buffer being scanned */ 4334 4335 pos_T *pos; 4336 char_u **matches; 4337 int save_p_scs; 4338 int save_p_ws; 4339 int save_p_ic; 4340 int i; 4341 int num_matches; 4342 int len; 4343 int found_new_match; 4344 int type = ctrl_x_mode; 4345 char_u *ptr; 4346 char_u *dict = NULL; 4347 int dict_f = 0; 4348 int set_match_pos; 4349 4350 if (!compl_started) 4351 { 4352 FOR_ALL_BUFFERS(ins_buf) 4353 ins_buf->b_scanned = 0; 4354 found_all = FALSE; 4355 ins_buf = curbuf; 4356 e_cpt = (compl_cont_status & CONT_LOCAL) 4357 ? (char_u *)"." : curbuf->b_p_cpt; 4358 last_match_pos = first_match_pos = *ini; 4359 } 4360 else if (ins_buf != curbuf && !buf_valid(ins_buf)) 4361 ins_buf = curbuf; // In case the buffer was wiped out. 4362 4363 compl_old_match = compl_curr_match; /* remember the last current match */ 4364 pos = (compl_direction == FORWARD) ? &last_match_pos : &first_match_pos; 4365 4366 /* 4367 * For ^N/^P loop over all the flags/windows/buffers in 'complete'. 4368 */ 4369 for (;;) 4370 { 4371 found_new_match = FAIL; 4372 set_match_pos = FALSE; 4373 4374 /* For ^N/^P pick a new entry from e_cpt if compl_started is off, 4375 * or if found_all says this entry is done. For ^X^L only use the 4376 * entries from 'complete' that look in loaded buffers. */ 4377 if ((ctrl_x_mode == CTRL_X_NORMAL 4378 || CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) 4379 && (!compl_started || found_all)) 4380 { 4381 found_all = FALSE; 4382 while (*e_cpt == ',' || *e_cpt == ' ') 4383 e_cpt++; 4384 if (*e_cpt == '.' && !curbuf->b_scanned) 4385 { 4386 ins_buf = curbuf; 4387 first_match_pos = *ini; 4388 /* Move the cursor back one character so that ^N can match the 4389 * word immediately after the cursor. */ 4390 if (ctrl_x_mode == CTRL_X_NORMAL && dec(&first_match_pos) < 0) 4391 { 4392 /* Move the cursor to after the last character in the 4393 * buffer, so that word at start of buffer is found 4394 * correctly. */ 4395 first_match_pos.lnum = ins_buf->b_ml.ml_line_count; 4396 first_match_pos.col = 4397 (colnr_T)STRLEN(ml_get(first_match_pos.lnum)); 4398 } 4399 last_match_pos = first_match_pos; 4400 type = 0; 4401 4402 /* Remember the first match so that the loop stops when we 4403 * wrap and come back there a second time. */ 4404 set_match_pos = TRUE; 4405 } 4406 else if (vim_strchr((char_u *)"buwU", *e_cpt) != NULL 4407 && (ins_buf = ins_compl_next_buf(ins_buf, *e_cpt)) != curbuf) 4408 { 4409 /* Scan a buffer, but not the current one. */ 4410 if (ins_buf->b_ml.ml_mfp != NULL) /* loaded buffer */ 4411 { 4412 compl_started = TRUE; 4413 first_match_pos.col = last_match_pos.col = 0; 4414 first_match_pos.lnum = ins_buf->b_ml.ml_line_count + 1; 4415 last_match_pos.lnum = 0; 4416 type = 0; 4417 } 4418 else /* unloaded buffer, scan like dictionary */ 4419 { 4420 found_all = TRUE; 4421 if (ins_buf->b_fname == NULL) 4422 continue; 4423 type = CTRL_X_DICTIONARY; 4424 dict = ins_buf->b_fname; 4425 dict_f = DICT_EXACT; 4426 } 4427 vim_snprintf((char *)IObuff, IOSIZE, _("Scanning: %s"), 4428 ins_buf->b_fname == NULL 4429 ? buf_spname(ins_buf) 4430 : ins_buf->b_sfname == NULL 4431 ? ins_buf->b_fname 4432 : ins_buf->b_sfname); 4433 (void)msg_trunc_attr((char *)IObuff, TRUE, HL_ATTR(HLF_R)); 4434 } 4435 else if (*e_cpt == NUL) 4436 break; 4437 else 4438 { 4439 if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) 4440 type = -1; 4441 else if (*e_cpt == 'k' || *e_cpt == 's') 4442 { 4443 if (*e_cpt == 'k') 4444 type = CTRL_X_DICTIONARY; 4445 else 4446 type = CTRL_X_THESAURUS; 4447 if (*++e_cpt != ',' && *e_cpt != NUL) 4448 { 4449 dict = e_cpt; 4450 dict_f = DICT_FIRST; 4451 } 4452 } 4453 #ifdef FEAT_FIND_ID 4454 else if (*e_cpt == 'i') 4455 type = CTRL_X_PATH_PATTERNS; 4456 else if (*e_cpt == 'd') 4457 type = CTRL_X_PATH_DEFINES; 4458 #endif 4459 else if (*e_cpt == ']' || *e_cpt == 't') 4460 { 4461 type = CTRL_X_TAGS; 4462 vim_snprintf((char *)IObuff, IOSIZE, _("Scanning tags.")); 4463 (void)msg_trunc_attr((char *)IObuff, TRUE, HL_ATTR(HLF_R)); 4464 } 4465 else 4466 type = -1; 4467 4468 /* in any case e_cpt is advanced to the next entry */ 4469 (void)copy_option_part(&e_cpt, IObuff, IOSIZE, ","); 4470 4471 found_all = TRUE; 4472 if (type == -1) 4473 continue; 4474 } 4475 } 4476 4477 /* If complete() was called then compl_pattern has been reset. The 4478 * following won't work then, bail out. */ 4479 if (compl_pattern == NULL) 4480 break; 4481 4482 switch (type) 4483 { 4484 case -1: 4485 break; 4486 #ifdef FEAT_FIND_ID 4487 case CTRL_X_PATH_PATTERNS: 4488 case CTRL_X_PATH_DEFINES: 4489 find_pattern_in_path(compl_pattern, compl_direction, 4490 (int)STRLEN(compl_pattern), FALSE, FALSE, 4491 (type == CTRL_X_PATH_DEFINES 4492 && !(compl_cont_status & CONT_SOL)) 4493 ? FIND_DEFINE : FIND_ANY, 1L, ACTION_EXPAND, 4494 (linenr_T)1, (linenr_T)MAXLNUM); 4495 break; 4496 #endif 4497 4498 case CTRL_X_DICTIONARY: 4499 case CTRL_X_THESAURUS: 4500 ins_compl_dictionaries( 4501 dict != NULL ? dict 4502 : (type == CTRL_X_THESAURUS 4503 ? (*curbuf->b_p_tsr == NUL 4504 ? p_tsr 4505 : curbuf->b_p_tsr) 4506 : (*curbuf->b_p_dict == NUL 4507 ? p_dict 4508 : curbuf->b_p_dict)), 4509 compl_pattern, 4510 dict != NULL ? dict_f 4511 : 0, type == CTRL_X_THESAURUS); 4512 dict = NULL; 4513 break; 4514 4515 case CTRL_X_TAGS: 4516 /* set p_ic according to p_ic, p_scs and pat for find_tags(). */ 4517 save_p_ic = p_ic; 4518 p_ic = ignorecase(compl_pattern); 4519 4520 /* Find up to TAG_MANY matches. Avoids that an enormous number 4521 * of matches is found when compl_pattern is empty */ 4522 if (find_tags(compl_pattern, &num_matches, &matches, 4523 TAG_REGEXP | TAG_NAMES | TAG_NOIC | TAG_INS_COMP 4524 | (ctrl_x_mode != CTRL_X_NORMAL ? TAG_VERBOSE : 0), 4525 TAG_MANY, curbuf->b_ffname) == OK && num_matches > 0) 4526 { 4527 ins_compl_add_matches(num_matches, matches, p_ic); 4528 } 4529 p_ic = save_p_ic; 4530 break; 4531 4532 case CTRL_X_FILES: 4533 if (expand_wildcards(1, &compl_pattern, &num_matches, &matches, 4534 EW_FILE|EW_DIR|EW_ADDSLASH|EW_SILENT) == OK) 4535 { 4536 4537 /* May change home directory back to "~". */ 4538 tilde_replace(compl_pattern, num_matches, matches); 4539 ins_compl_add_matches(num_matches, matches, p_fic || p_wic); 4540 } 4541 break; 4542 4543 case CTRL_X_CMDLINE: 4544 if (expand_cmdline(&compl_xp, compl_pattern, 4545 (int)STRLEN(compl_pattern), 4546 &num_matches, &matches) == EXPAND_OK) 4547 ins_compl_add_matches(num_matches, matches, FALSE); 4548 break; 4549 4550 #ifdef FEAT_COMPL_FUNC 4551 case CTRL_X_FUNCTION: 4552 case CTRL_X_OMNI: 4553 expand_by_function(type, compl_pattern); 4554 break; 4555 #endif 4556 4557 case CTRL_X_SPELL: 4558 #ifdef FEAT_SPELL 4559 num_matches = expand_spelling(first_match_pos.lnum, 4560 compl_pattern, &matches); 4561 if (num_matches > 0) 4562 ins_compl_add_matches(num_matches, matches, p_ic); 4563 #endif 4564 break; 4565 4566 default: /* normal ^P/^N and ^X^L */ 4567 /* 4568 * If 'infercase' is set, don't use 'smartcase' here 4569 */ 4570 save_p_scs = p_scs; 4571 if (ins_buf->b_p_inf) 4572 p_scs = FALSE; 4573 4574 /* Buffers other than curbuf are scanned from the beginning or the 4575 * end but never from the middle, thus setting nowrapscan in this 4576 * buffers is a good idea, on the other hand, we always set 4577 * wrapscan for curbuf to avoid missing matches -- Acevedo,Webb */ 4578 save_p_ws = p_ws; 4579 if (ins_buf != curbuf) 4580 p_ws = FALSE; 4581 else if (*e_cpt == '.') 4582 p_ws = TRUE; 4583 for (;;) 4584 { 4585 int flags = 0; 4586 4587 ++msg_silent; /* Don't want messages for wrapscan. */ 4588 4589 /* CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode) 4590 * || word-wise search that 4591 * has added a word that was at the beginning of the line */ 4592 if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode) 4593 || (compl_cont_status & CONT_SOL)) 4594 found_new_match = search_for_exact_line(ins_buf, pos, 4595 compl_direction, compl_pattern); 4596 else 4597 found_new_match = searchit(NULL, ins_buf, pos, NULL, 4598 compl_direction, 4599 compl_pattern, 1L, SEARCH_KEEP + SEARCH_NFMSG, 4600 RE_LAST, (linenr_T)0, NULL, NULL); 4601 --msg_silent; 4602 if (!compl_started || set_match_pos) 4603 { 4604 /* set "compl_started" even on fail */ 4605 compl_started = TRUE; 4606 first_match_pos = *pos; 4607 last_match_pos = *pos; 4608 set_match_pos = FALSE; 4609 } 4610 else if (first_match_pos.lnum == last_match_pos.lnum 4611 && first_match_pos.col == last_match_pos.col) 4612 found_new_match = FAIL; 4613 if (found_new_match == FAIL) 4614 { 4615 if (ins_buf == curbuf) 4616 found_all = TRUE; 4617 break; 4618 } 4619 4620 /* when ADDING, the text before the cursor matches, skip it */ 4621 if ( (compl_cont_status & CONT_ADDING) && ins_buf == curbuf 4622 && ini->lnum == pos->lnum 4623 && ini->col == pos->col) 4624 continue; 4625 ptr = ml_get_buf(ins_buf, pos->lnum, FALSE) + pos->col; 4626 if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) 4627 { 4628 if (compl_cont_status & CONT_ADDING) 4629 { 4630 if (pos->lnum >= ins_buf->b_ml.ml_line_count) 4631 continue; 4632 ptr = ml_get_buf(ins_buf, pos->lnum + 1, FALSE); 4633 if (!p_paste) 4634 ptr = skipwhite(ptr); 4635 } 4636 len = (int)STRLEN(ptr); 4637 } 4638 else 4639 { 4640 char_u *tmp_ptr = ptr; 4641 4642 if (compl_cont_status & CONT_ADDING) 4643 { 4644 tmp_ptr += compl_length; 4645 /* Skip if already inside a word. */ 4646 if (vim_iswordp(tmp_ptr)) 4647 continue; 4648 /* Find start of next word. */ 4649 tmp_ptr = find_word_start(tmp_ptr); 4650 } 4651 /* Find end of this word. */ 4652 tmp_ptr = find_word_end(tmp_ptr); 4653 len = (int)(tmp_ptr - ptr); 4654 4655 if ((compl_cont_status & CONT_ADDING) 4656 && len == compl_length) 4657 { 4658 if (pos->lnum < ins_buf->b_ml.ml_line_count) 4659 { 4660 /* Try next line, if any. the new word will be 4661 * "join" as if the normal command "J" was used. 4662 * IOSIZE is always greater than 4663 * compl_length, so the next STRNCPY always 4664 * works -- Acevedo */ 4665 STRNCPY(IObuff, ptr, len); 4666 ptr = ml_get_buf(ins_buf, pos->lnum + 1, FALSE); 4667 tmp_ptr = ptr = skipwhite(ptr); 4668 /* Find start of next word. */ 4669 tmp_ptr = find_word_start(tmp_ptr); 4670 /* Find end of next word. */ 4671 tmp_ptr = find_word_end(tmp_ptr); 4672 if (tmp_ptr > ptr) 4673 { 4674 if (*ptr != ')' && IObuff[len - 1] != TAB) 4675 { 4676 if (IObuff[len - 1] != ' ') 4677 IObuff[len++] = ' '; 4678 /* IObuf =~ "\k.* ", thus len >= 2 */ 4679 if (p_js 4680 && (IObuff[len - 2] == '.' 4681 || (vim_strchr(p_cpo, CPO_JOINSP) 4682 == NULL 4683 && (IObuff[len - 2] == '?' 4684 || IObuff[len - 2] == '!')))) 4685 IObuff[len++] = ' '; 4686 } 4687 /* copy as much as possible of the new word */ 4688 if (tmp_ptr - ptr >= IOSIZE - len) 4689 tmp_ptr = ptr + IOSIZE - len - 1; 4690 STRNCPY(IObuff + len, ptr, tmp_ptr - ptr); 4691 len += (int)(tmp_ptr - ptr); 4692 flags |= CONT_S_IPOS; 4693 } 4694 IObuff[len] = NUL; 4695 ptr = IObuff; 4696 } 4697 if (len == compl_length) 4698 continue; 4699 } 4700 } 4701 if (ins_compl_add_infercase(ptr, len, p_ic, 4702 ins_buf == curbuf ? NULL : ins_buf->b_sfname, 4703 0, flags) != NOTDONE) 4704 { 4705 found_new_match = OK; 4706 break; 4707 } 4708 } 4709 p_scs = save_p_scs; 4710 p_ws = save_p_ws; 4711 } 4712 4713 /* check if compl_curr_match has changed, (e.g. other type of 4714 * expansion added something) */ 4715 if (type != 0 && compl_curr_match != compl_old_match) 4716 found_new_match = OK; 4717 4718 /* break the loop for specialized modes (use 'complete' just for the 4719 * generic ctrl_x_mode == CTRL_X_NORMAL) or when we've found a new 4720 * match */ 4721 if ((ctrl_x_mode != CTRL_X_NORMAL 4722 && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) 4723 || found_new_match != FAIL) 4724 { 4725 if (got_int) 4726 break; 4727 /* Fill the popup menu as soon as possible. */ 4728 if (type != -1) 4729 ins_compl_check_keys(0, FALSE); 4730 4731 if ((ctrl_x_mode != CTRL_X_NORMAL 4732 && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) 4733 || compl_interrupted) 4734 break; 4735 compl_started = TRUE; 4736 } 4737 else 4738 { 4739 /* Mark a buffer scanned when it has been scanned completely */ 4740 if (type == 0 || type == CTRL_X_PATH_PATTERNS) 4741 ins_buf->b_scanned = TRUE; 4742 4743 compl_started = FALSE; 4744 } 4745 } 4746 compl_started = TRUE; 4747 4748 if ((ctrl_x_mode == CTRL_X_NORMAL || CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) 4749 && *e_cpt == NUL) /* Got to end of 'complete' */ 4750 found_new_match = FAIL; 4751 4752 i = -1; /* total of matches, unknown */ 4753 if (found_new_match == FAIL || (ctrl_x_mode != CTRL_X_NORMAL 4754 && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))) 4755 i = ins_compl_make_cyclic(); 4756 4757 if (compl_old_match != NULL) 4758 { 4759 /* If several matches were added (FORWARD) or the search failed and has 4760 * just been made cyclic then we have to move compl_curr_match to the 4761 * next or previous entry (if any) -- Acevedo */ 4762 compl_curr_match = compl_direction == FORWARD ? compl_old_match->cp_next 4763 : compl_old_match->cp_prev; 4764 if (compl_curr_match == NULL) 4765 compl_curr_match = compl_old_match; 4766 } 4767 return i; 4768 } 4769 4770 /* Delete the old text being completed. */ 4771 static void 4772 ins_compl_delete(void) 4773 { 4774 int col; 4775 4776 /* 4777 * In insert mode: Delete the typed part. 4778 * In replace mode: Put the old characters back, if any. 4779 */ 4780 col = compl_col + (compl_cont_status & CONT_ADDING ? compl_length : 0); 4781 if ((int)curwin->w_cursor.col > col) 4782 { 4783 if (stop_arrow() == FAIL) 4784 return; 4785 backspace_until_column(col); 4786 } 4787 4788 /* TODO: is this sufficient for redrawing? Redrawing everything causes 4789 * flicker, thus we can't do that. */ 4790 changed_cline_bef_curs(); 4791 /* clear v:completed_item */ 4792 set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc_lock(VAR_FIXED)); 4793 } 4794 4795 /* 4796 * Insert the new text being completed. 4797 * "in_compl_func" is TRUE when called from complete_check(). 4798 */ 4799 static void 4800 ins_compl_insert(int in_compl_func) 4801 { 4802 dict_T *dict; 4803 4804 ins_bytes(compl_shown_match->cp_str + ins_compl_len()); 4805 if (compl_shown_match->cp_flags & ORIGINAL_TEXT) 4806 compl_used_match = FALSE; 4807 else 4808 compl_used_match = TRUE; 4809 4810 /* Set completed item. */ 4811 /* { word, abbr, menu, kind, info } */ 4812 dict = dict_alloc_lock(VAR_FIXED); 4813 if (dict != NULL) 4814 { 4815 dict_add_string(dict, "word", compl_shown_match->cp_str); 4816 dict_add_string(dict, "abbr", compl_shown_match->cp_text[CPT_ABBR]); 4817 dict_add_string(dict, "menu", compl_shown_match->cp_text[CPT_MENU]); 4818 dict_add_string(dict, "kind", compl_shown_match->cp_text[CPT_KIND]); 4819 dict_add_string(dict, "info", compl_shown_match->cp_text[CPT_INFO]); 4820 dict_add_string(dict, "user_data", 4821 compl_shown_match->cp_text[CPT_USER_DATA]); 4822 } 4823 set_vim_var_dict(VV_COMPLETED_ITEM, dict); 4824 if (!in_compl_func) 4825 compl_curr_match = compl_shown_match; 4826 } 4827 4828 /* 4829 * Fill in the next completion in the current direction. 4830 * If "allow_get_expansion" is TRUE, then we may call ins_compl_get_exp() to 4831 * get more completions. If it is FALSE, then we just do nothing when there 4832 * are no more completions in a given direction. The latter case is used when 4833 * we are still in the middle of finding completions, to allow browsing 4834 * through the ones found so far. 4835 * Return the total number of matches, or -1 if still unknown -- webb. 4836 * 4837 * compl_curr_match is currently being used by ins_compl_get_exp(), so we use 4838 * compl_shown_match here. 4839 * 4840 * Note that this function may be called recursively once only. First with 4841 * "allow_get_expansion" TRUE, which calls ins_compl_get_exp(), which in turn 4842 * calls this function with "allow_get_expansion" FALSE. 4843 */ 4844 static int 4845 ins_compl_next( 4846 int allow_get_expansion, 4847 int count, /* repeat completion this many times; should 4848 be at least 1 */ 4849 int insert_match, /* Insert the newly selected match */ 4850 int in_compl_func) /* called from complete_check() */ 4851 { 4852 int num_matches = -1; 4853 int todo = count; 4854 compl_T *found_compl = NULL; 4855 int found_end = FALSE; 4856 int advance; 4857 int started = compl_started; 4858 4859 /* When user complete function return -1 for findstart which is next 4860 * time of 'always', compl_shown_match become NULL. */ 4861 if (compl_shown_match == NULL) 4862 return -1; 4863 4864 if (compl_leader != NULL 4865 && (compl_shown_match->cp_flags & ORIGINAL_TEXT) == 0) 4866 { 4867 /* Set "compl_shown_match" to the actually shown match, it may differ 4868 * when "compl_leader" is used to omit some of the matches. */ 4869 while (!ins_compl_equal(compl_shown_match, 4870 compl_leader, (int)STRLEN(compl_leader)) 4871 && compl_shown_match->cp_next != NULL 4872 && compl_shown_match->cp_next != compl_first_match) 4873 compl_shown_match = compl_shown_match->cp_next; 4874 4875 /* If we didn't find it searching forward, and compl_shows_dir is 4876 * backward, find the last match. */ 4877 if (compl_shows_dir == BACKWARD 4878 && !ins_compl_equal(compl_shown_match, 4879 compl_leader, (int)STRLEN(compl_leader)) 4880 && (compl_shown_match->cp_next == NULL 4881 || compl_shown_match->cp_next == compl_first_match)) 4882 { 4883 while (!ins_compl_equal(compl_shown_match, 4884 compl_leader, (int)STRLEN(compl_leader)) 4885 && compl_shown_match->cp_prev != NULL 4886 && compl_shown_match->cp_prev != compl_first_match) 4887 compl_shown_match = compl_shown_match->cp_prev; 4888 } 4889 } 4890 4891 if (allow_get_expansion && insert_match 4892 && (!(compl_get_longest || compl_restarting) || compl_used_match)) 4893 /* Delete old text to be replaced */ 4894 ins_compl_delete(); 4895 4896 /* When finding the longest common text we stick at the original text, 4897 * don't let CTRL-N or CTRL-P move to the first match. */ 4898 advance = count != 1 || !allow_get_expansion || !compl_get_longest; 4899 4900 /* When restarting the search don't insert the first match either. */ 4901 if (compl_restarting) 4902 { 4903 advance = FALSE; 4904 compl_restarting = FALSE; 4905 } 4906 4907 /* Repeat this for when <PageUp> or <PageDown> is typed. But don't wrap 4908 * around. */ 4909 while (--todo >= 0) 4910 { 4911 if (compl_shows_dir == FORWARD && compl_shown_match->cp_next != NULL) 4912 { 4913 compl_shown_match = compl_shown_match->cp_next; 4914 found_end = (compl_first_match != NULL 4915 && (compl_shown_match->cp_next == compl_first_match 4916 || compl_shown_match == compl_first_match)); 4917 } 4918 else if (compl_shows_dir == BACKWARD 4919 && compl_shown_match->cp_prev != NULL) 4920 { 4921 found_end = (compl_shown_match == compl_first_match); 4922 compl_shown_match = compl_shown_match->cp_prev; 4923 found_end |= (compl_shown_match == compl_first_match); 4924 } 4925 else 4926 { 4927 if (!allow_get_expansion) 4928 { 4929 if (advance) 4930 { 4931 if (compl_shows_dir == BACKWARD) 4932 compl_pending -= todo + 1; 4933 else 4934 compl_pending += todo + 1; 4935 } 4936 return -1; 4937 } 4938 4939 if (!compl_no_select && advance) 4940 { 4941 if (compl_shows_dir == BACKWARD) 4942 --compl_pending; 4943 else 4944 ++compl_pending; 4945 } 4946 4947 /* Find matches. */ 4948 num_matches = ins_compl_get_exp(&compl_startpos); 4949 4950 /* handle any pending completions */ 4951 while (compl_pending != 0 && compl_direction == compl_shows_dir 4952 && advance) 4953 { 4954 if (compl_pending > 0 && compl_shown_match->cp_next != NULL) 4955 { 4956 compl_shown_match = compl_shown_match->cp_next; 4957 --compl_pending; 4958 } 4959 if (compl_pending < 0 && compl_shown_match->cp_prev != NULL) 4960 { 4961 compl_shown_match = compl_shown_match->cp_prev; 4962 ++compl_pending; 4963 } 4964 else 4965 break; 4966 } 4967 found_end = FALSE; 4968 } 4969 if ((compl_shown_match->cp_flags & ORIGINAL_TEXT) == 0 4970 && compl_leader != NULL 4971 && !ins_compl_equal(compl_shown_match, 4972 compl_leader, (int)STRLEN(compl_leader))) 4973 ++todo; 4974 else 4975 /* Remember a matching item. */ 4976 found_compl = compl_shown_match; 4977 4978 /* Stop at the end of the list when we found a usable match. */ 4979 if (found_end) 4980 { 4981 if (found_compl != NULL) 4982 { 4983 compl_shown_match = found_compl; 4984 break; 4985 } 4986 todo = 1; /* use first usable match after wrapping around */ 4987 } 4988 } 4989 4990 /* Insert the text of the new completion, or the compl_leader. */ 4991 if (compl_no_insert && !started) 4992 { 4993 ins_bytes(compl_orig_text + ins_compl_len()); 4994 compl_used_match = FALSE; 4995 } 4996 else if (insert_match) 4997 { 4998 if (!compl_get_longest || compl_used_match) 4999 ins_compl_insert(in_compl_func); 5000 else 5001 ins_bytes(compl_leader + ins_compl_len()); 5002 } 5003 else 5004 compl_used_match = FALSE; 5005 5006 if (!allow_get_expansion) 5007 { 5008 /* may undisplay the popup menu first */ 5009 ins_compl_upd_pum(); 5010 5011 if (pum_enough_matches()) 5012 // Will display the popup menu, don't redraw yet to avoid flicker. 5013 pum_call_update_screen(); 5014 else 5015 // Not showing the popup menu yet, redraw to show the user what was 5016 // inserted. 5017 update_screen(0); 5018 5019 /* display the updated popup menu */ 5020 ins_compl_show_pum(); 5021 #ifdef FEAT_GUI 5022 if (gui.in_use) 5023 { 5024 /* Show the cursor after the match, not after the redrawn text. */ 5025 setcursor(); 5026 out_flush_cursor(FALSE, FALSE); 5027 } 5028 #endif 5029 5030 /* Delete old text to be replaced, since we're still searching and 5031 * don't want to match ourselves! */ 5032 ins_compl_delete(); 5033 } 5034 5035 /* Enter will select a match when the match wasn't inserted and the popup 5036 * menu is visible. */ 5037 if (compl_no_insert && !started) 5038 compl_enter_selects = TRUE; 5039 else 5040 compl_enter_selects = !insert_match && compl_match_array != NULL; 5041 5042 /* 5043 * Show the file name for the match (if any) 5044 * Truncate the file name to avoid a wait for return. 5045 */ 5046 if (compl_shown_match->cp_fname != NULL) 5047 { 5048 char *lead = _("match in file"); 5049 int space = sc_col - vim_strsize((char_u *)lead) - 2; 5050 char_u *s; 5051 char_u *e; 5052 5053 if (space > 0) 5054 { 5055 /* We need the tail that fits. With double-byte encoding going 5056 * back from the end is very slow, thus go from the start and keep 5057 * the text that fits in "space" between "s" and "e". */ 5058 for (s = e = compl_shown_match->cp_fname; *e != NUL; MB_PTR_ADV(e)) 5059 { 5060 space -= ptr2cells(e); 5061 while (space < 0) 5062 { 5063 space += ptr2cells(s); 5064 MB_PTR_ADV(s); 5065 } 5066 } 5067 vim_snprintf((char *)IObuff, IOSIZE, "%s %s%s", lead, 5068 s > compl_shown_match->cp_fname ? "<" : "", s); 5069 msg((char *)IObuff); 5070 redraw_cmdline = FALSE; /* don't overwrite! */ 5071 } 5072 } 5073 5074 return num_matches; 5075 } 5076 5077 /* 5078 * Call this while finding completions, to check whether the user has hit a key 5079 * that should change the currently displayed completion, or exit completion 5080 * mode. Also, when compl_pending is not zero, show a completion as soon as 5081 * possible. -- webb 5082 * "frequency" specifies out of how many calls we actually check. 5083 * "in_compl_func" is TRUE when called from complete_check(), don't set 5084 * compl_curr_match. 5085 */ 5086 void 5087 ins_compl_check_keys(int frequency, int in_compl_func) 5088 { 5089 static int count = 0; 5090 int c; 5091 5092 /* Don't check when reading keys from a script, :normal or feedkeys(). 5093 * That would break the test scripts. But do check for keys when called 5094 * from complete_check(). */ 5095 if (!in_compl_func && (using_script() || ex_normal_busy)) 5096 return; 5097 5098 /* Only do this at regular intervals */ 5099 if (++count < frequency) 5100 return; 5101 count = 0; 5102 5103 /* Check for a typed key. Do use mappings, otherwise vim_is_ctrl_x_key() 5104 * can't do its work correctly. */ 5105 c = vpeekc_any(); 5106 if (c != NUL) 5107 { 5108 if (vim_is_ctrl_x_key(c) && c != Ctrl_X && c != Ctrl_R) 5109 { 5110 c = safe_vgetc(); /* Eat the character */ 5111 compl_shows_dir = ins_compl_key2dir(c); 5112 (void)ins_compl_next(FALSE, ins_compl_key2count(c), 5113 c != K_UP && c != K_DOWN, in_compl_func); 5114 } 5115 else 5116 { 5117 /* Need to get the character to have KeyTyped set. We'll put it 5118 * back with vungetc() below. But skip K_IGNORE. */ 5119 c = safe_vgetc(); 5120 if (c != K_IGNORE) 5121 { 5122 /* Don't interrupt completion when the character wasn't typed, 5123 * e.g., when doing @q to replay keys. */ 5124 if (c != Ctrl_R && KeyTyped) 5125 compl_interrupted = TRUE; 5126 5127 vungetc(c); 5128 } 5129 } 5130 } 5131 if (compl_pending != 0 && !got_int && !compl_no_insert) 5132 { 5133 int todo = compl_pending > 0 ? compl_pending : -compl_pending; 5134 5135 compl_pending = 0; 5136 (void)ins_compl_next(FALSE, todo, TRUE, in_compl_func); 5137 } 5138 } 5139 5140 /* 5141 * Decide the direction of Insert mode complete from the key typed. 5142 * Returns BACKWARD or FORWARD. 5143 */ 5144 static int 5145 ins_compl_key2dir(int c) 5146 { 5147 if (c == Ctrl_P || c == Ctrl_L 5148 || c == K_PAGEUP || c == K_KPAGEUP || c == K_S_UP || c == K_UP) 5149 return BACKWARD; 5150 return FORWARD; 5151 } 5152 5153 /* 5154 * Return TRUE for keys that are used for completion only when the popup menu 5155 * is visible. 5156 */ 5157 static int 5158 ins_compl_pum_key(int c) 5159 { 5160 return pum_visible() && (c == K_PAGEUP || c == K_KPAGEUP || c == K_S_UP 5161 || c == K_PAGEDOWN || c == K_KPAGEDOWN || c == K_S_DOWN 5162 || c == K_UP || c == K_DOWN); 5163 } 5164 5165 /* 5166 * Decide the number of completions to move forward. 5167 * Returns 1 for most keys, height of the popup menu for page-up/down keys. 5168 */ 5169 static int 5170 ins_compl_key2count(int c) 5171 { 5172 int h; 5173 5174 if (ins_compl_pum_key(c) && c != K_UP && c != K_DOWN) 5175 { 5176 h = pum_get_height(); 5177 if (h > 3) 5178 h -= 2; /* keep some context */ 5179 return h; 5180 } 5181 return 1; 5182 } 5183 5184 /* 5185 * Return TRUE if completion with "c" should insert the match, FALSE if only 5186 * to change the currently selected completion. 5187 */ 5188 static int 5189 ins_compl_use_match(int c) 5190 { 5191 switch (c) 5192 { 5193 case K_UP: 5194 case K_DOWN: 5195 case K_PAGEDOWN: 5196 case K_KPAGEDOWN: 5197 case K_S_DOWN: 5198 case K_PAGEUP: 5199 case K_KPAGEUP: 5200 case K_S_UP: 5201 return FALSE; 5202 } 5203 return TRUE; 5204 } 5205 5206 /* 5207 * Do Insert mode completion. 5208 * Called when character "c" was typed, which has a meaning for completion. 5209 * Returns OK if completion was done, FAIL if something failed (out of mem). 5210 */ 5211 static int 5212 ins_complete(int c, int enable_pum) 5213 { 5214 char_u *line; 5215 int startcol = 0; /* column where searched text starts */ 5216 colnr_T curs_col; /* cursor column */ 5217 int n; 5218 int save_w_wrow; 5219 int save_w_leftcol; 5220 int insert_match; 5221 int save_did_ai = did_ai; 5222 5223 compl_direction = ins_compl_key2dir(c); 5224 insert_match = ins_compl_use_match(c); 5225 5226 if (!compl_started) 5227 { 5228 /* First time we hit ^N or ^P (in a row, I mean) */ 5229 5230 did_ai = FALSE; 5231 #ifdef FEAT_SMARTINDENT 5232 did_si = FALSE; 5233 can_si = FALSE; 5234 can_si_back = FALSE; 5235 #endif 5236 if (stop_arrow() == FAIL) 5237 return FAIL; 5238 5239 line = ml_get(curwin->w_cursor.lnum); 5240 curs_col = curwin->w_cursor.col; 5241 compl_pending = 0; 5242 5243 /* If this same ctrl_x_mode has been interrupted use the text from 5244 * "compl_startpos" to the cursor as a pattern to add a new word 5245 * instead of expand the one before the cursor, in word-wise if 5246 * "compl_startpos" is not in the same line as the cursor then fix it 5247 * (the line has been split because it was longer than 'tw'). if SOL 5248 * is set then skip the previous pattern, a word at the beginning of 5249 * the line has been inserted, we'll look for that -- Acevedo. */ 5250 if ((compl_cont_status & CONT_INTRPT) == CONT_INTRPT 5251 && compl_cont_mode == ctrl_x_mode) 5252 { 5253 /* 5254 * it is a continued search 5255 */ 5256 compl_cont_status &= ~CONT_INTRPT; /* remove INTRPT */ 5257 if (ctrl_x_mode == CTRL_X_NORMAL 5258 || ctrl_x_mode == CTRL_X_PATH_PATTERNS 5259 || ctrl_x_mode == CTRL_X_PATH_DEFINES) 5260 { 5261 if (compl_startpos.lnum != curwin->w_cursor.lnum) 5262 { 5263 /* line (probably) wrapped, set compl_startpos to the 5264 * first non_blank in the line, if it is not a wordchar 5265 * include it to get a better pattern, but then we don't 5266 * want the "\\<" prefix, check it bellow */ 5267 compl_col = (colnr_T)getwhitecols(line); 5268 compl_startpos.col = compl_col; 5269 compl_startpos.lnum = curwin->w_cursor.lnum; 5270 compl_cont_status &= ~CONT_SOL; /* clear SOL if present */ 5271 } 5272 else 5273 { 5274 /* S_IPOS was set when we inserted a word that was at the 5275 * beginning of the line, which means that we'll go to SOL 5276 * mode but first we need to redefine compl_startpos */ 5277 if (compl_cont_status & CONT_S_IPOS) 5278 { 5279 compl_cont_status |= CONT_SOL; 5280 compl_startpos.col = (colnr_T)(skipwhite( 5281 line + compl_length 5282 + compl_startpos.col) - line); 5283 } 5284 compl_col = compl_startpos.col; 5285 } 5286 compl_length = curwin->w_cursor.col - (int)compl_col; 5287 /* IObuff is used to add a "word from the next line" would we 5288 * have enough space? just being paranoid */ 5289 #define MIN_SPACE 75 5290 if (compl_length > (IOSIZE - MIN_SPACE)) 5291 { 5292 compl_cont_status &= ~CONT_SOL; 5293 compl_length = (IOSIZE - MIN_SPACE); 5294 compl_col = curwin->w_cursor.col - compl_length; 5295 } 5296 compl_cont_status |= CONT_ADDING | CONT_N_ADDS; 5297 if (compl_length < 1) 5298 compl_cont_status &= CONT_LOCAL; 5299 } 5300 else if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) 5301 compl_cont_status = CONT_ADDING | CONT_N_ADDS; 5302 else 5303 compl_cont_status = 0; 5304 } 5305 else 5306 compl_cont_status &= CONT_LOCAL; 5307 5308 if (!(compl_cont_status & CONT_ADDING)) /* normal expansion */ 5309 { 5310 compl_cont_mode = ctrl_x_mode; 5311 if (ctrl_x_mode != CTRL_X_NORMAL) 5312 /* Remove LOCAL if ctrl_x_mode != CTRL_X_NORMAL */ 5313 compl_cont_status = 0; 5314 compl_cont_status |= CONT_N_ADDS; 5315 compl_startpos = curwin->w_cursor; 5316 startcol = (int)curs_col; 5317 compl_col = 0; 5318 } 5319 5320 /* Work out completion pattern and original text -- webb */ 5321 if (ctrl_x_mode == CTRL_X_NORMAL || (ctrl_x_mode & CTRL_X_WANT_IDENT)) 5322 { 5323 if ((compl_cont_status & CONT_SOL) 5324 || ctrl_x_mode == CTRL_X_PATH_DEFINES) 5325 { 5326 if (!(compl_cont_status & CONT_ADDING)) 5327 { 5328 while (--startcol >= 0 && vim_isIDc(line[startcol])) 5329 ; 5330 compl_col += ++startcol; 5331 compl_length = curs_col - startcol; 5332 } 5333 if (p_ic) 5334 compl_pattern = str_foldcase(line + compl_col, 5335 compl_length, NULL, 0); 5336 else 5337 compl_pattern = vim_strnsave(line + compl_col, 5338 compl_length); 5339 if (compl_pattern == NULL) 5340 return FAIL; 5341 } 5342 else if (compl_cont_status & CONT_ADDING) 5343 { 5344 char_u *prefix = (char_u *)"\\<"; 5345 5346 /* we need up to 2 extra chars for the prefix */ 5347 compl_pattern = alloc(quote_meta(NULL, line + compl_col, 5348 compl_length) + 2); 5349 if (compl_pattern == NULL) 5350 return FAIL; 5351 if (!vim_iswordp(line + compl_col) 5352 || (compl_col > 0 5353 && (vim_iswordp(mb_prevptr(line, line + compl_col))))) 5354 prefix = (char_u *)""; 5355 STRCPY((char *)compl_pattern, prefix); 5356 (void)quote_meta(compl_pattern + STRLEN(prefix), 5357 line + compl_col, compl_length); 5358 } 5359 else if (--startcol < 0 5360 || !vim_iswordp(mb_prevptr(line, line + startcol + 1))) 5361 { 5362 /* Match any word of at least two chars */ 5363 compl_pattern = vim_strsave((char_u *)"\\<\\k\\k"); 5364 if (compl_pattern == NULL) 5365 return FAIL; 5366 compl_col += curs_col; 5367 compl_length = 0; 5368 } 5369 else 5370 { 5371 /* Search the point of change class of multibyte character 5372 * or not a word single byte character backward. */ 5373 if (has_mbyte) 5374 { 5375 int base_class; 5376 int head_off; 5377 5378 startcol -= (*mb_head_off)(line, line + startcol); 5379 base_class = mb_get_class(line + startcol); 5380 while (--startcol >= 0) 5381 { 5382 head_off = (*mb_head_off)(line, line + startcol); 5383 if (base_class != mb_get_class(line + startcol 5384 - head_off)) 5385 break; 5386 startcol -= head_off; 5387 } 5388 } 5389 else 5390 while (--startcol >= 0 && vim_iswordc(line[startcol])) 5391 ; 5392 compl_col += ++startcol; 5393 compl_length = (int)curs_col - startcol; 5394 if (compl_length == 1) 5395 { 5396 /* Only match word with at least two chars -- webb 5397 * there's no need to call quote_meta, 5398 * alloc(7) is enough -- Acevedo 5399 */ 5400 compl_pattern = alloc(7); 5401 if (compl_pattern == NULL) 5402 return FAIL; 5403 STRCPY((char *)compl_pattern, "\\<"); 5404 (void)quote_meta(compl_pattern + 2, line + compl_col, 1); 5405 STRCAT((char *)compl_pattern, "\\k"); 5406 } 5407 else 5408 { 5409 compl_pattern = alloc(quote_meta(NULL, line + compl_col, 5410 compl_length) + 2); 5411 if (compl_pattern == NULL) 5412 return FAIL; 5413 STRCPY((char *)compl_pattern, "\\<"); 5414 (void)quote_meta(compl_pattern + 2, line + compl_col, 5415 compl_length); 5416 } 5417 } 5418 } 5419 else if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) 5420 { 5421 compl_col = (colnr_T)getwhitecols(line); 5422 compl_length = (int)curs_col - (int)compl_col; 5423 if (compl_length < 0) /* cursor in indent: empty pattern */ 5424 compl_length = 0; 5425 if (p_ic) 5426 compl_pattern = str_foldcase(line + compl_col, compl_length, 5427 NULL, 0); 5428 else 5429 compl_pattern = vim_strnsave(line + compl_col, compl_length); 5430 if (compl_pattern == NULL) 5431 return FAIL; 5432 } 5433 else if (ctrl_x_mode == CTRL_X_FILES) 5434 { 5435 /* Go back to just before the first filename character. */ 5436 if (startcol > 0) 5437 { 5438 char_u *p = line + startcol; 5439 5440 MB_PTR_BACK(line, p); 5441 while (p > line && vim_isfilec(PTR2CHAR(p))) 5442 MB_PTR_BACK(line, p); 5443 if (p == line && vim_isfilec(PTR2CHAR(p))) 5444 startcol = 0; 5445 else 5446 startcol = (int)(p - line) + 1; 5447 } 5448 5449 compl_col += startcol; 5450 compl_length = (int)curs_col - startcol; 5451 compl_pattern = addstar(line + compl_col, compl_length, 5452 EXPAND_FILES); 5453 if (compl_pattern == NULL) 5454 return FAIL; 5455 } 5456 else if (ctrl_x_mode == CTRL_X_CMDLINE) 5457 { 5458 compl_pattern = vim_strnsave(line, curs_col); 5459 if (compl_pattern == NULL) 5460 return FAIL; 5461 set_cmd_context(&compl_xp, compl_pattern, 5462 (int)STRLEN(compl_pattern), curs_col, FALSE); 5463 if (compl_xp.xp_context == EXPAND_UNSUCCESSFUL 5464 || compl_xp.xp_context == EXPAND_NOTHING) 5465 /* No completion possible, use an empty pattern to get a 5466 * "pattern not found" message. */ 5467 compl_col = curs_col; 5468 else 5469 compl_col = (int)(compl_xp.xp_pattern - compl_pattern); 5470 compl_length = curs_col - compl_col; 5471 } 5472 else if (ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI) 5473 { 5474 #ifdef FEAT_COMPL_FUNC 5475 /* 5476 * Call user defined function 'completefunc' with "a:findstart" 5477 * set to 1 to obtain the length of text to use for completion. 5478 */ 5479 typval_T args[3]; 5480 int col; 5481 char_u *funcname; 5482 pos_T pos; 5483 win_T *curwin_save; 5484 buf_T *curbuf_save; 5485 int save_State = State; 5486 5487 /* Call 'completefunc' or 'omnifunc' and get pattern length as a 5488 * string */ 5489 funcname = ctrl_x_mode == CTRL_X_FUNCTION 5490 ? curbuf->b_p_cfu : curbuf->b_p_ofu; 5491 if (*funcname == NUL) 5492 { 5493 semsg(_(e_notset), ctrl_x_mode == CTRL_X_FUNCTION 5494 ? "completefunc" : "omnifunc"); 5495 /* restore did_ai, so that adding comment leader works */ 5496 did_ai = save_did_ai; 5497 return FAIL; 5498 } 5499 5500 args[0].v_type = VAR_NUMBER; 5501 args[0].vval.v_number = 1; 5502 args[1].v_type = VAR_STRING; 5503 args[1].vval.v_string = (char_u *)""; 5504 args[2].v_type = VAR_UNKNOWN; 5505 pos = curwin->w_cursor; 5506 curwin_save = curwin; 5507 curbuf_save = curbuf; 5508 col = call_func_retnr(funcname, 2, args); 5509 5510 State = save_State; 5511 if (curwin_save != curwin || curbuf_save != curbuf) 5512 { 5513 emsg(_(e_complwin)); 5514 return FAIL; 5515 } 5516 curwin->w_cursor = pos; /* restore the cursor position */ 5517 validate_cursor(); 5518 if (!EQUAL_POS(curwin->w_cursor, pos)) 5519 { 5520 emsg(_(e_compldel)); 5521 return FAIL; 5522 } 5523 5524 /* Return value -2 means the user complete function wants to 5525 * cancel the complete without an error. 5526 * Return value -3 does the same as -2 and leaves CTRL-X mode.*/ 5527 if (col == -2) 5528 return FAIL; 5529 if (col == -3) 5530 { 5531 ctrl_x_mode = CTRL_X_NORMAL; 5532 edit_submode = NULL; 5533 if (!shortmess(SHM_COMPLETIONMENU)) 5534 msg_clr_cmdline(); 5535 return FAIL; 5536 } 5537 5538 /* 5539 * Reset extended parameters of completion, when start new 5540 * completion. 5541 */ 5542 compl_opt_refresh_always = FALSE; 5543 compl_opt_suppress_empty = FALSE; 5544 5545 if (col < 0) 5546 col = curs_col; 5547 compl_col = col; 5548 if (compl_col > curs_col) 5549 compl_col = curs_col; 5550 5551 /* Setup variables for completion. Need to obtain "line" again, 5552 * it may have become invalid. */ 5553 line = ml_get(curwin->w_cursor.lnum); 5554 compl_length = curs_col - compl_col; 5555 compl_pattern = vim_strnsave(line + compl_col, compl_length); 5556 if (compl_pattern == NULL) 5557 #endif 5558 return FAIL; 5559 } 5560 else if (ctrl_x_mode == CTRL_X_SPELL) 5561 { 5562 #ifdef FEAT_SPELL 5563 if (spell_bad_len > 0) 5564 compl_col = curs_col - spell_bad_len; 5565 else 5566 compl_col = spell_word_start(startcol); 5567 if (compl_col >= (colnr_T)startcol) 5568 { 5569 compl_length = 0; 5570 compl_col = curs_col; 5571 } 5572 else 5573 { 5574 spell_expand_check_cap(compl_col); 5575 compl_length = (int)curs_col - compl_col; 5576 } 5577 /* Need to obtain "line" again, it may have become invalid. */ 5578 line = ml_get(curwin->w_cursor.lnum); 5579 compl_pattern = vim_strnsave(line + compl_col, compl_length); 5580 if (compl_pattern == NULL) 5581 #endif 5582 return FAIL; 5583 } 5584 else 5585 { 5586 internal_error("ins_complete()"); 5587 return FAIL; 5588 } 5589 5590 if (compl_cont_status & CONT_ADDING) 5591 { 5592 edit_submode_pre = (char_u *)_(" Adding"); 5593 if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) 5594 { 5595 /* Insert a new line, keep indentation but ignore 'comments' */ 5596 #ifdef FEAT_COMMENTS 5597 char_u *old = curbuf->b_p_com; 5598 5599 curbuf->b_p_com = (char_u *)""; 5600 #endif 5601 compl_startpos.lnum = curwin->w_cursor.lnum; 5602 compl_startpos.col = compl_col; 5603 ins_eol('\r'); 5604 #ifdef FEAT_COMMENTS 5605 curbuf->b_p_com = old; 5606 #endif 5607 compl_length = 0; 5608 compl_col = curwin->w_cursor.col; 5609 } 5610 } 5611 else 5612 { 5613 edit_submode_pre = NULL; 5614 compl_startpos.col = compl_col; 5615 } 5616 5617 if (compl_cont_status & CONT_LOCAL) 5618 edit_submode = (char_u *)_(ctrl_x_msgs[CTRL_X_LOCAL_MSG]); 5619 else 5620 edit_submode = (char_u *)_(CTRL_X_MSG(ctrl_x_mode)); 5621 5622 /* If any of the original typed text has been changed we need to fix 5623 * the redo buffer. */ 5624 ins_compl_fixRedoBufForLeader(NULL); 5625 5626 /* Always add completion for the original text. */ 5627 vim_free(compl_orig_text); 5628 compl_orig_text = vim_strnsave(line + compl_col, compl_length); 5629 if (compl_orig_text == NULL || ins_compl_add(compl_orig_text, 5630 -1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK) 5631 { 5632 VIM_CLEAR(compl_pattern); 5633 VIM_CLEAR(compl_orig_text); 5634 return FAIL; 5635 } 5636 5637 /* showmode might reset the internal line pointers, so it must 5638 * be called before line = ml_get(), or when this address is no 5639 * longer needed. -- Acevedo. 5640 */ 5641 edit_submode_extra = (char_u *)_("-- Searching..."); 5642 edit_submode_highl = HLF_COUNT; 5643 showmode(); 5644 edit_submode_extra = NULL; 5645 out_flush(); 5646 } 5647 else if (insert_match && stop_arrow() == FAIL) 5648 return FAIL; 5649 5650 compl_shown_match = compl_curr_match; 5651 compl_shows_dir = compl_direction; 5652 5653 /* 5654 * Find next match (and following matches). 5655 */ 5656 save_w_wrow = curwin->w_wrow; 5657 save_w_leftcol = curwin->w_leftcol; 5658 n = ins_compl_next(TRUE, ins_compl_key2count(c), insert_match, FALSE); 5659 5660 /* may undisplay the popup menu */ 5661 ins_compl_upd_pum(); 5662 5663 if (n > 1) /* all matches have been found */ 5664 compl_matches = n; 5665 compl_curr_match = compl_shown_match; 5666 compl_direction = compl_shows_dir; 5667 5668 /* Eat the ESC that vgetc() returns after a CTRL-C to avoid leaving Insert 5669 * mode. */ 5670 if (got_int && !global_busy) 5671 { 5672 (void)vgetc(); 5673 got_int = FALSE; 5674 } 5675 5676 /* we found no match if the list has only the "compl_orig_text"-entry */ 5677 if (compl_first_match == compl_first_match->cp_next) 5678 { 5679 edit_submode_extra = (compl_cont_status & CONT_ADDING) 5680 && compl_length > 1 5681 ? (char_u *)_(e_hitend) : (char_u *)_(e_patnotf); 5682 edit_submode_highl = HLF_E; 5683 /* remove N_ADDS flag, so next ^X<> won't try to go to ADDING mode, 5684 * because we couldn't expand anything at first place, but if we used 5685 * ^P, ^N, ^X^I or ^X^D we might want to add-expand a single-char-word 5686 * (such as M in M'exico) if not tried already. -- Acevedo */ 5687 if ( compl_length > 1 5688 || (compl_cont_status & CONT_ADDING) 5689 || (ctrl_x_mode != CTRL_X_NORMAL 5690 && ctrl_x_mode != CTRL_X_PATH_PATTERNS 5691 && ctrl_x_mode != CTRL_X_PATH_DEFINES)) 5692 compl_cont_status &= ~CONT_N_ADDS; 5693 } 5694 5695 if (compl_curr_match->cp_flags & CONT_S_IPOS) 5696 compl_cont_status |= CONT_S_IPOS; 5697 else 5698 compl_cont_status &= ~CONT_S_IPOS; 5699 5700 if (edit_submode_extra == NULL) 5701 { 5702 if (compl_curr_match->cp_flags & ORIGINAL_TEXT) 5703 { 5704 edit_submode_extra = (char_u *)_("Back at original"); 5705 edit_submode_highl = HLF_W; 5706 } 5707 else if (compl_cont_status & CONT_S_IPOS) 5708 { 5709 edit_submode_extra = (char_u *)_("Word from other line"); 5710 edit_submode_highl = HLF_COUNT; 5711 } 5712 else if (compl_curr_match->cp_next == compl_curr_match->cp_prev) 5713 { 5714 edit_submode_extra = (char_u *)_("The only match"); 5715 edit_submode_highl = HLF_COUNT; 5716 } 5717 else 5718 { 5719 /* Update completion sequence number when needed. */ 5720 if (compl_curr_match->cp_number == -1) 5721 { 5722 int number = 0; 5723 compl_T *match; 5724 5725 if (compl_direction == FORWARD) 5726 { 5727 /* search backwards for the first valid (!= -1) number. 5728 * This should normally succeed already at the first loop 5729 * cycle, so it's fast! */ 5730 for (match = compl_curr_match->cp_prev; match != NULL 5731 && match != compl_first_match; 5732 match = match->cp_prev) 5733 if (match->cp_number != -1) 5734 { 5735 number = match->cp_number; 5736 break; 5737 } 5738 if (match != NULL) 5739 /* go up and assign all numbers which are not assigned 5740 * yet */ 5741 for (match = match->cp_next; 5742 match != NULL && match->cp_number == -1; 5743 match = match->cp_next) 5744 match->cp_number = ++number; 5745 } 5746 else /* BACKWARD */ 5747 { 5748 /* search forwards (upwards) for the first valid (!= -1) 5749 * number. This should normally succeed already at the 5750 * first loop cycle, so it's fast! */ 5751 for (match = compl_curr_match->cp_next; match != NULL 5752 && match != compl_first_match; 5753 match = match->cp_next) 5754 if (match->cp_number != -1) 5755 { 5756 number = match->cp_number; 5757 break; 5758 } 5759 if (match != NULL) 5760 /* go down and assign all numbers which are not 5761 * assigned yet */ 5762 for (match = match->cp_prev; match 5763 && match->cp_number == -1; 5764 match = match->cp_prev) 5765 match->cp_number = ++number; 5766 } 5767 } 5768 5769 /* The match should always have a sequence number now, this is 5770 * just a safety check. */ 5771 if (compl_curr_match->cp_number != -1) 5772 { 5773 /* Space for 10 text chars. + 2x10-digit no.s = 31. 5774 * Translations may need more than twice that. */ 5775 static char_u match_ref[81]; 5776 5777 if (compl_matches > 0) 5778 vim_snprintf((char *)match_ref, sizeof(match_ref), 5779 _("match %d of %d"), 5780 compl_curr_match->cp_number, compl_matches); 5781 else 5782 vim_snprintf((char *)match_ref, sizeof(match_ref), 5783 _("match %d"), 5784 compl_curr_match->cp_number); 5785 edit_submode_extra = match_ref; 5786 edit_submode_highl = HLF_R; 5787 if (dollar_vcol >= 0) 5788 curs_columns(FALSE); 5789 } 5790 } 5791 } 5792 5793 // Show a message about what (completion) mode we're in. 5794 if (!compl_opt_suppress_empty) 5795 { 5796 showmode(); 5797 if (!shortmess(SHM_COMPLETIONMENU)) 5798 { 5799 if (edit_submode_extra != NULL) 5800 { 5801 if (!p_smd) 5802 msg_attr((char *)edit_submode_extra, 5803 edit_submode_highl < HLF_COUNT 5804 ? HL_ATTR(edit_submode_highl) : 0); 5805 } 5806 else 5807 msg_clr_cmdline(); // necessary for "noshowmode" 5808 } 5809 } 5810 5811 /* Show the popup menu, unless we got interrupted. */ 5812 if (enable_pum && !compl_interrupted) 5813 show_pum(save_w_wrow, save_w_leftcol); 5814 5815 compl_was_interrupted = compl_interrupted; 5816 compl_interrupted = FALSE; 5817 5818 return OK; 5819 } 5820 5821 static void 5822 show_pum(int prev_w_wrow, int prev_w_leftcol) 5823 { 5824 /* RedrawingDisabled may be set when invoked through complete(). */ 5825 int n = RedrawingDisabled; 5826 5827 RedrawingDisabled = 0; 5828 5829 /* If the cursor moved or the display scrolled we need to remove the pum 5830 * first. */ 5831 setcursor(); 5832 if (prev_w_wrow != curwin->w_wrow || prev_w_leftcol != curwin->w_leftcol) 5833 ins_compl_del_pum(); 5834 5835 ins_compl_show_pum(); 5836 setcursor(); 5837 RedrawingDisabled = n; 5838 } 5839 5840 /* 5841 * Looks in the first "len" chars. of "src" for search-metachars. 5842 * If dest is not NULL the chars. are copied there quoting (with 5843 * a backslash) the metachars, and dest would be NUL terminated. 5844 * Returns the length (needed) of dest 5845 */ 5846 static unsigned 5847 quote_meta(char_u *dest, char_u *src, int len) 5848 { 5849 unsigned m = (unsigned)len + 1; /* one extra for the NUL */ 5850 5851 for ( ; --len >= 0; src++) 5852 { 5853 switch (*src) 5854 { 5855 case '.': 5856 case '*': 5857 case '[': 5858 if (ctrl_x_mode == CTRL_X_DICTIONARY 5859 || ctrl_x_mode == CTRL_X_THESAURUS) 5860 break; 5861 /* FALLTHROUGH */ 5862 case '~': 5863 if (!p_magic) /* quote these only if magic is set */ 5864 break; 5865 /* FALLTHROUGH */ 5866 case '\\': 5867 if (ctrl_x_mode == CTRL_X_DICTIONARY 5868 || ctrl_x_mode == CTRL_X_THESAURUS) 5869 break; 5870 /* FALLTHROUGH */ 5871 case '^': /* currently it's not needed. */ 5872 case '$': 5873 m++; 5874 if (dest != NULL) 5875 *dest++ = '\\'; 5876 break; 5877 } 5878 if (dest != NULL) 5879 *dest++ = *src; 5880 /* Copy remaining bytes of a multibyte character. */ 5881 if (has_mbyte) 5882 { 5883 int i, mb_len; 5884 5885 mb_len = (*mb_ptr2len)(src) - 1; 5886 if (mb_len > 0 && len >= mb_len) 5887 for (i = 0; i < mb_len; ++i) 5888 { 5889 --len; 5890 ++src; 5891 if (dest != NULL) 5892 *dest++ = *src; 5893 } 5894 } 5895 } 5896 if (dest != NULL) 5897 *dest = NUL; 5898 5899 return m; 5900 } 5901 #endif /* FEAT_INS_EXPAND */ 5902 5903 /* 5904 * Next character is interpreted literally. 5905 * A one, two or three digit decimal number is interpreted as its byte value. 5906 * If one or two digits are entered, the next character is given to vungetc(). 5907 * For Unicode a character > 255 may be returned. 5908 */ 5909 int 5910 get_literal(void) 5911 { 5912 int cc; 5913 int nc; 5914 int i; 5915 int hex = FALSE; 5916 int octal = FALSE; 5917 int unicode = 0; 5918 5919 if (got_int) 5920 return Ctrl_C; 5921 5922 #ifdef FEAT_GUI 5923 /* 5924 * In GUI there is no point inserting the internal code for a special key. 5925 * It is more useful to insert the string "<KEY>" instead. This would 5926 * probably be useful in a text window too, but it would not be 5927 * vi-compatible (maybe there should be an option for it?) -- webb 5928 */ 5929 if (gui.in_use) 5930 ++allow_keys; 5931 #endif 5932 #ifdef USE_ON_FLY_SCROLL 5933 dont_scroll = TRUE; /* disallow scrolling here */ 5934 #endif 5935 ++no_mapping; /* don't map the next key hits */ 5936 cc = 0; 5937 i = 0; 5938 for (;;) 5939 { 5940 nc = plain_vgetc(); 5941 #ifdef FEAT_CMDL_INFO 5942 if (!(State & CMDLINE) && MB_BYTE2LEN_CHECK(nc) == 1) 5943 add_to_showcmd(nc); 5944 #endif 5945 if (nc == 'x' || nc == 'X') 5946 hex = TRUE; 5947 else if (nc == 'o' || nc == 'O') 5948 octal = TRUE; 5949 else if (nc == 'u' || nc == 'U') 5950 unicode = nc; 5951 else 5952 { 5953 if (hex || unicode != 0) 5954 { 5955 if (!vim_isxdigit(nc)) 5956 break; 5957 cc = cc * 16 + hex2nr(nc); 5958 } 5959 else if (octal) 5960 { 5961 if (nc < '0' || nc > '7') 5962 break; 5963 cc = cc * 8 + nc - '0'; 5964 } 5965 else 5966 { 5967 if (!VIM_ISDIGIT(nc)) 5968 break; 5969 cc = cc * 10 + nc - '0'; 5970 } 5971 5972 ++i; 5973 } 5974 5975 if (cc > 255 && unicode == 0) 5976 cc = 255; /* limit range to 0-255 */ 5977 nc = 0; 5978 5979 if (hex) /* hex: up to two chars */ 5980 { 5981 if (i >= 2) 5982 break; 5983 } 5984 else if (unicode) /* Unicode: up to four or eight chars */ 5985 { 5986 if ((unicode == 'u' && i >= 4) || (unicode == 'U' && i >= 8)) 5987 break; 5988 } 5989 else if (i >= 3) /* decimal or octal: up to three chars */ 5990 break; 5991 } 5992 if (i == 0) /* no number entered */ 5993 { 5994 if (nc == K_ZERO) /* NUL is stored as NL */ 5995 { 5996 cc = '\n'; 5997 nc = 0; 5998 } 5999 else 6000 { 6001 cc = nc; 6002 nc = 0; 6003 } 6004 } 6005 6006 if (cc == 0) /* NUL is stored as NL */ 6007 cc = '\n'; 6008 if (enc_dbcs && (cc & 0xff) == 0) 6009 cc = '?'; /* don't accept an illegal DBCS char, the NUL in the 6010 second byte will cause trouble! */ 6011 6012 --no_mapping; 6013 #ifdef FEAT_GUI 6014 if (gui.in_use) 6015 --allow_keys; 6016 #endif 6017 if (nc) 6018 vungetc(nc); 6019 got_int = FALSE; /* CTRL-C typed after CTRL-V is not an interrupt */ 6020 return cc; 6021 } 6022 6023 /* 6024 * Insert character, taking care of special keys and mod_mask 6025 */ 6026 static void 6027 insert_special( 6028 int c, 6029 int allow_modmask, 6030 int ctrlv) /* c was typed after CTRL-V */ 6031 { 6032 char_u *p; 6033 int len; 6034 6035 /* 6036 * Special function key, translate into "<Key>". Up to the last '>' is 6037 * inserted with ins_str(), so as not to replace characters in replace 6038 * mode. 6039 * Only use mod_mask for special keys, to avoid things like <S-Space>, 6040 * unless 'allow_modmask' is TRUE. 6041 */ 6042 #ifdef MACOS_X 6043 /* Command-key never produces a normal key */ 6044 if (mod_mask & MOD_MASK_CMD) 6045 allow_modmask = TRUE; 6046 #endif 6047 if (IS_SPECIAL(c) || (mod_mask && allow_modmask)) 6048 { 6049 p = get_special_key_name(c, mod_mask); 6050 len = (int)STRLEN(p); 6051 c = p[len - 1]; 6052 if (len > 2) 6053 { 6054 if (stop_arrow() == FAIL) 6055 return; 6056 p[len - 1] = NUL; 6057 ins_str(p); 6058 AppendToRedobuffLit(p, -1); 6059 ctrlv = FALSE; 6060 } 6061 } 6062 if (stop_arrow() == OK) 6063 insertchar(c, ctrlv ? INSCHAR_CTRLV : 0, -1); 6064 } 6065 6066 /* 6067 * Special characters in this context are those that need processing other 6068 * than the simple insertion that can be performed here. This includes ESC 6069 * which terminates the insert, and CR/NL which need special processing to 6070 * open up a new line. This routine tries to optimize insertions performed by 6071 * the "redo", "undo" or "put" commands, so it needs to know when it should 6072 * stop and defer processing to the "normal" mechanism. 6073 * '0' and '^' are special, because they can be followed by CTRL-D. 6074 */ 6075 #ifdef EBCDIC 6076 # define ISSPECIAL(c) ((c) < ' ' || (c) == '0' || (c) == '^') 6077 #else 6078 # define ISSPECIAL(c) ((c) < ' ' || (c) >= DEL || (c) == '0' || (c) == '^') 6079 #endif 6080 6081 #define WHITECHAR(cc) (VIM_ISWHITE(cc) && (!enc_utf8 || !utf_iscomposing(utf_ptr2char(ml_get_cursor() + 1)))) 6082 6083 /* 6084 * "flags": INSCHAR_FORMAT - force formatting 6085 * INSCHAR_CTRLV - char typed just after CTRL-V 6086 * INSCHAR_NO_FEX - don't use 'formatexpr' 6087 * 6088 * NOTE: passes the flags value straight through to internal_format() which, 6089 * beside INSCHAR_FORMAT (above), is also looking for these: 6090 * INSCHAR_DO_COM - format comments 6091 * INSCHAR_COM_LIST - format comments with num list or 2nd line indent 6092 */ 6093 void 6094 insertchar( 6095 int c, /* character to insert or NUL */ 6096 int flags, /* INSCHAR_FORMAT, etc. */ 6097 int second_indent) /* indent for second line if >= 0 */ 6098 { 6099 int textwidth; 6100 #ifdef FEAT_COMMENTS 6101 char_u *p; 6102 #endif 6103 int fo_ins_blank; 6104 int force_format = flags & INSCHAR_FORMAT; 6105 6106 textwidth = comp_textwidth(force_format); 6107 fo_ins_blank = has_format_option(FO_INS_BLANK); 6108 6109 /* 6110 * Try to break the line in two or more pieces when: 6111 * - Always do this if we have been called to do formatting only. 6112 * - Always do this when 'formatoptions' has the 'a' flag and the line 6113 * ends in white space. 6114 * - Otherwise: 6115 * - Don't do this if inserting a blank 6116 * - Don't do this if an existing character is being replaced, unless 6117 * we're in VREPLACE mode. 6118 * - Do this if the cursor is not on the line where insert started 6119 * or - 'formatoptions' doesn't have 'l' or the line was not too long 6120 * before the insert. 6121 * - 'formatoptions' doesn't have 'b' or a blank was inserted at or 6122 * before 'textwidth' 6123 */ 6124 if (textwidth > 0 6125 && (force_format 6126 || (!VIM_ISWHITE(c) 6127 && !((State & REPLACE_FLAG) 6128 && !(State & VREPLACE_FLAG) 6129 && *ml_get_cursor() != NUL) 6130 && (curwin->w_cursor.lnum != Insstart.lnum 6131 || ((!has_format_option(FO_INS_LONG) 6132 || Insstart_textlen <= (colnr_T)textwidth) 6133 && (!fo_ins_blank 6134 || Insstart_blank_vcol <= (colnr_T)textwidth 6135 )))))) 6136 { 6137 /* Format with 'formatexpr' when it's set. Use internal formatting 6138 * when 'formatexpr' isn't set or it returns non-zero. */ 6139 #if defined(FEAT_EVAL) 6140 int do_internal = TRUE; 6141 colnr_T virtcol = get_nolist_virtcol() 6142 + char2cells(c != NUL ? c : gchar_cursor()); 6143 6144 if (*curbuf->b_p_fex != NUL && (flags & INSCHAR_NO_FEX) == 0 6145 && (force_format || virtcol > (colnr_T)textwidth)) 6146 { 6147 do_internal = (fex_format(curwin->w_cursor.lnum, 1L, c) != 0); 6148 /* It may be required to save for undo again, e.g. when setline() 6149 * was called. */ 6150 ins_need_undo = TRUE; 6151 } 6152 if (do_internal) 6153 #endif 6154 internal_format(textwidth, second_indent, flags, c == NUL, c); 6155 } 6156 6157 if (c == NUL) /* only formatting was wanted */ 6158 return; 6159 6160 #ifdef FEAT_COMMENTS 6161 /* Check whether this character should end a comment. */ 6162 if (did_ai && (int)c == end_comment_pending) 6163 { 6164 char_u *line; 6165 char_u lead_end[COM_MAX_LEN]; /* end-comment string */ 6166 int middle_len, end_len; 6167 int i; 6168 6169 /* 6170 * Need to remove existing (middle) comment leader and insert end 6171 * comment leader. First, check what comment leader we can find. 6172 */ 6173 i = get_leader_len(line = ml_get_curline(), &p, FALSE, TRUE); 6174 if (i > 0 && vim_strchr(p, COM_MIDDLE) != NULL) /* Just checking */ 6175 { 6176 /* Skip middle-comment string */ 6177 while (*p && p[-1] != ':') /* find end of middle flags */ 6178 ++p; 6179 middle_len = copy_option_part(&p, lead_end, COM_MAX_LEN, ","); 6180 /* Don't count trailing white space for middle_len */ 6181 while (middle_len > 0 && VIM_ISWHITE(lead_end[middle_len - 1])) 6182 --middle_len; 6183 6184 /* Find the end-comment string */ 6185 while (*p && p[-1] != ':') /* find end of end flags */ 6186 ++p; 6187 end_len = copy_option_part(&p, lead_end, COM_MAX_LEN, ","); 6188 6189 /* Skip white space before the cursor */ 6190 i = curwin->w_cursor.col; 6191 while (--i >= 0 && VIM_ISWHITE(line[i])) 6192 ; 6193 i++; 6194 6195 /* Skip to before the middle leader */ 6196 i -= middle_len; 6197 6198 /* Check some expected things before we go on */ 6199 if (i >= 0 && lead_end[end_len - 1] == end_comment_pending) 6200 { 6201 /* Backspace over all the stuff we want to replace */ 6202 backspace_until_column(i); 6203 6204 /* 6205 * Insert the end-comment string, except for the last 6206 * character, which will get inserted as normal later. 6207 */ 6208 ins_bytes_len(lead_end, end_len - 1); 6209 } 6210 } 6211 } 6212 end_comment_pending = NUL; 6213 #endif 6214 6215 did_ai = FALSE; 6216 #ifdef FEAT_SMARTINDENT 6217 did_si = FALSE; 6218 can_si = FALSE; 6219 can_si_back = FALSE; 6220 #endif 6221 6222 /* 6223 * If there's any pending input, grab up to INPUT_BUFLEN at once. 6224 * This speeds up normal text input considerably. 6225 * Don't do this when 'cindent' or 'indentexpr' is set, because we might 6226 * need to re-indent at a ':', or any other character (but not what 6227 * 'paste' is set).. 6228 * Don't do this when there an InsertCharPre autocommand is defined, 6229 * because we need to fire the event for every character. 6230 * Do the check for InsertCharPre before the call to vpeekc() because the 6231 * InsertCharPre autocommand could change the input buffer. 6232 */ 6233 #ifdef USE_ON_FLY_SCROLL 6234 dont_scroll = FALSE; /* allow scrolling here */ 6235 #endif 6236 6237 if ( !ISSPECIAL(c) 6238 && (!has_mbyte || (*mb_char2len)(c) == 1) 6239 && !has_insertcharpre() 6240 && vpeekc() != NUL 6241 && !(State & REPLACE_FLAG) 6242 #ifdef FEAT_CINDENT 6243 && !cindent_on() 6244 #endif 6245 #ifdef FEAT_RIGHTLEFT 6246 && !p_ri 6247 #endif 6248 ) 6249 { 6250 #define INPUT_BUFLEN 100 6251 char_u buf[INPUT_BUFLEN + 1]; 6252 int i; 6253 colnr_T virtcol = 0; 6254 6255 buf[0] = c; 6256 i = 1; 6257 if (textwidth > 0) 6258 virtcol = get_nolist_virtcol(); 6259 /* 6260 * Stop the string when: 6261 * - no more chars available 6262 * - finding a special character (command key) 6263 * - buffer is full 6264 * - running into the 'textwidth' boundary 6265 * - need to check for abbreviation: A non-word char after a word-char 6266 */ 6267 while ( (c = vpeekc()) != NUL 6268 && !ISSPECIAL(c) 6269 && (!has_mbyte || MB_BYTE2LEN_CHECK(c) == 1) 6270 && i < INPUT_BUFLEN 6271 && (textwidth == 0 6272 || (virtcol += byte2cells(buf[i - 1])) < (colnr_T)textwidth) 6273 && !(!no_abbr && !vim_iswordc(c) && vim_iswordc(buf[i - 1]))) 6274 { 6275 #ifdef FEAT_RIGHTLEFT 6276 c = vgetc(); 6277 if (p_hkmap && KeyTyped) 6278 c = hkmap(c); /* Hebrew mode mapping */ 6279 buf[i++] = c; 6280 #else 6281 buf[i++] = vgetc(); 6282 #endif 6283 } 6284 6285 #ifdef FEAT_DIGRAPHS 6286 do_digraph(-1); /* clear digraphs */ 6287 do_digraph(buf[i-1]); /* may be the start of a digraph */ 6288 #endif 6289 buf[i] = NUL; 6290 ins_str(buf); 6291 if (flags & INSCHAR_CTRLV) 6292 { 6293 redo_literal(*buf); 6294 i = 1; 6295 } 6296 else 6297 i = 0; 6298 if (buf[i] != NUL) 6299 AppendToRedobuffLit(buf + i, -1); 6300 } 6301 else 6302 { 6303 int cc; 6304 6305 if (has_mbyte && (cc = (*mb_char2len)(c)) > 1) 6306 { 6307 char_u buf[MB_MAXBYTES + 1]; 6308 6309 (*mb_char2bytes)(c, buf); 6310 buf[cc] = NUL; 6311 ins_char_bytes(buf, cc); 6312 AppendCharToRedobuff(c); 6313 } 6314 else 6315 { 6316 ins_char(c); 6317 if (flags & INSCHAR_CTRLV) 6318 redo_literal(c); 6319 else 6320 AppendCharToRedobuff(c); 6321 } 6322 } 6323 } 6324 6325 /* 6326 * Format text at the current insert position. 6327 * 6328 * If the INSCHAR_COM_LIST flag is present, then the value of second_indent 6329 * will be the comment leader length sent to open_line(). 6330 */ 6331 static void 6332 internal_format( 6333 int textwidth, 6334 int second_indent, 6335 int flags, 6336 int format_only, 6337 int c) /* character to be inserted (can be NUL) */ 6338 { 6339 int cc; 6340 int save_char = NUL; 6341 int haveto_redraw = FALSE; 6342 int fo_ins_blank = has_format_option(FO_INS_BLANK); 6343 int fo_multibyte = has_format_option(FO_MBYTE_BREAK); 6344 int fo_white_par = has_format_option(FO_WHITE_PAR); 6345 int first_line = TRUE; 6346 #ifdef FEAT_COMMENTS 6347 colnr_T leader_len; 6348 int no_leader = FALSE; 6349 int do_comments = (flags & INSCHAR_DO_COM); 6350 #endif 6351 #ifdef FEAT_LINEBREAK 6352 int has_lbr = curwin->w_p_lbr; 6353 6354 /* make sure win_lbr_chartabsize() counts correctly */ 6355 curwin->w_p_lbr = FALSE; 6356 #endif 6357 6358 /* 6359 * When 'ai' is off we don't want a space under the cursor to be 6360 * deleted. Replace it with an 'x' temporarily. 6361 */ 6362 if (!curbuf->b_p_ai && !(State & VREPLACE_FLAG)) 6363 { 6364 cc = gchar_cursor(); 6365 if (VIM_ISWHITE(cc)) 6366 { 6367 save_char = cc; 6368 pchar_cursor('x'); 6369 } 6370 } 6371 6372 /* 6373 * Repeat breaking lines, until the current line is not too long. 6374 */ 6375 while (!got_int) 6376 { 6377 int startcol; /* Cursor column at entry */ 6378 int wantcol; /* column at textwidth border */ 6379 int foundcol; /* column for start of spaces */ 6380 int end_foundcol = 0; /* column for start of word */ 6381 colnr_T len; 6382 colnr_T virtcol; 6383 int orig_col = 0; 6384 char_u *saved_text = NULL; 6385 colnr_T col; 6386 colnr_T end_col; 6387 int wcc; // counter for whitespace chars 6388 6389 virtcol = get_nolist_virtcol() 6390 + char2cells(c != NUL ? c : gchar_cursor()); 6391 if (virtcol <= (colnr_T)textwidth) 6392 break; 6393 6394 #ifdef FEAT_COMMENTS 6395 if (no_leader) 6396 do_comments = FALSE; 6397 else if (!(flags & INSCHAR_FORMAT) 6398 && has_format_option(FO_WRAP_COMS)) 6399 do_comments = TRUE; 6400 6401 /* Don't break until after the comment leader */ 6402 if (do_comments) 6403 leader_len = get_leader_len(ml_get_curline(), NULL, FALSE, TRUE); 6404 else 6405 leader_len = 0; 6406 6407 /* If the line doesn't start with a comment leader, then don't 6408 * start one in a following broken line. Avoids that a %word 6409 * moved to the start of the next line causes all following lines 6410 * to start with %. */ 6411 if (leader_len == 0) 6412 no_leader = TRUE; 6413 #endif 6414 if (!(flags & INSCHAR_FORMAT) 6415 #ifdef FEAT_COMMENTS 6416 && leader_len == 0 6417 #endif 6418 && !has_format_option(FO_WRAP)) 6419 6420 break; 6421 if ((startcol = curwin->w_cursor.col) == 0) 6422 break; 6423 6424 /* find column of textwidth border */ 6425 coladvance((colnr_T)textwidth); 6426 wantcol = curwin->w_cursor.col; 6427 6428 curwin->w_cursor.col = startcol; 6429 foundcol = 0; 6430 6431 /* 6432 * Find position to break at. 6433 * Stop at first entered white when 'formatoptions' has 'v' 6434 */ 6435 while ((!fo_ins_blank && !has_format_option(FO_INS_VI)) 6436 || (flags & INSCHAR_FORMAT) 6437 || curwin->w_cursor.lnum != Insstart.lnum 6438 || curwin->w_cursor.col >= Insstart.col) 6439 { 6440 if (curwin->w_cursor.col == startcol && c != NUL) 6441 cc = c; 6442 else 6443 cc = gchar_cursor(); 6444 if (WHITECHAR(cc)) 6445 { 6446 /* remember position of blank just before text */ 6447 end_col = curwin->w_cursor.col; 6448 6449 // find start of sequence of blanks 6450 wcc = 0; 6451 while (curwin->w_cursor.col > 0 && WHITECHAR(cc)) 6452 { 6453 dec_cursor(); 6454 cc = gchar_cursor(); 6455 6456 // Increment count of how many whitespace chars in this 6457 // group; we only need to know if it's more than one. 6458 if (wcc < 2) 6459 wcc++; 6460 } 6461 if (curwin->w_cursor.col == 0 && WHITECHAR(cc)) 6462 break; /* only spaces in front of text */ 6463 6464 // Don't break after a period when 'formatoptions' has 'p' and 6465 // there are less than two spaces. 6466 if (has_format_option(FO_PERIOD_ABBR) && cc == '.' && wcc < 2) 6467 continue; 6468 6469 #ifdef FEAT_COMMENTS 6470 /* Don't break until after the comment leader */ 6471 if (curwin->w_cursor.col < leader_len) 6472 break; 6473 #endif 6474 if (has_format_option(FO_ONE_LETTER)) 6475 { 6476 /* do not break after one-letter words */ 6477 if (curwin->w_cursor.col == 0) 6478 break; /* one-letter word at begin */ 6479 #ifdef FEAT_COMMENTS 6480 /* do not break "#a b" when 'tw' is 2 */ 6481 if (curwin->w_cursor.col <= leader_len) 6482 break; 6483 #endif 6484 col = curwin->w_cursor.col; 6485 dec_cursor(); 6486 cc = gchar_cursor(); 6487 6488 if (WHITECHAR(cc)) 6489 continue; /* one-letter, continue */ 6490 curwin->w_cursor.col = col; 6491 } 6492 6493 inc_cursor(); 6494 6495 end_foundcol = end_col + 1; 6496 foundcol = curwin->w_cursor.col; 6497 if (curwin->w_cursor.col <= (colnr_T)wantcol) 6498 break; 6499 } 6500 else if (cc >= 0x100 && fo_multibyte) 6501 { 6502 /* Break after or before a multi-byte character. */ 6503 if (curwin->w_cursor.col != startcol) 6504 { 6505 #ifdef FEAT_COMMENTS 6506 /* Don't break until after the comment leader */ 6507 if (curwin->w_cursor.col < leader_len) 6508 break; 6509 #endif 6510 col = curwin->w_cursor.col; 6511 inc_cursor(); 6512 /* Don't change end_foundcol if already set. */ 6513 if (foundcol != curwin->w_cursor.col) 6514 { 6515 foundcol = curwin->w_cursor.col; 6516 end_foundcol = foundcol; 6517 if (curwin->w_cursor.col <= (colnr_T)wantcol) 6518 break; 6519 } 6520 curwin->w_cursor.col = col; 6521 } 6522 6523 if (curwin->w_cursor.col == 0) 6524 break; 6525 6526 col = curwin->w_cursor.col; 6527 6528 dec_cursor(); 6529 cc = gchar_cursor(); 6530 6531 if (WHITECHAR(cc)) 6532 continue; /* break with space */ 6533 #ifdef FEAT_COMMENTS 6534 /* Don't break until after the comment leader */ 6535 if (curwin->w_cursor.col < leader_len) 6536 break; 6537 #endif 6538 6539 curwin->w_cursor.col = col; 6540 6541 foundcol = curwin->w_cursor.col; 6542 end_foundcol = foundcol; 6543 if (curwin->w_cursor.col <= (colnr_T)wantcol) 6544 break; 6545 } 6546 if (curwin->w_cursor.col == 0) 6547 break; 6548 dec_cursor(); 6549 } 6550 6551 if (foundcol == 0) /* no spaces, cannot break line */ 6552 { 6553 curwin->w_cursor.col = startcol; 6554 break; 6555 } 6556 6557 /* Going to break the line, remove any "$" now. */ 6558 undisplay_dollar(); 6559 6560 /* 6561 * Offset between cursor position and line break is used by replace 6562 * stack functions. VREPLACE does not use this, and backspaces 6563 * over the text instead. 6564 */ 6565 if (State & VREPLACE_FLAG) 6566 orig_col = startcol; /* Will start backspacing from here */ 6567 else 6568 replace_offset = startcol - end_foundcol; 6569 6570 /* 6571 * adjust startcol for spaces that will be deleted and 6572 * characters that will remain on top line 6573 */ 6574 curwin->w_cursor.col = foundcol; 6575 while ((cc = gchar_cursor(), WHITECHAR(cc)) 6576 && (!fo_white_par || curwin->w_cursor.col < startcol)) 6577 inc_cursor(); 6578 startcol -= curwin->w_cursor.col; 6579 if (startcol < 0) 6580 startcol = 0; 6581 6582 if (State & VREPLACE_FLAG) 6583 { 6584 /* 6585 * In VREPLACE mode, we will backspace over the text to be 6586 * wrapped, so save a copy now to put on the next line. 6587 */ 6588 saved_text = vim_strsave(ml_get_cursor()); 6589 curwin->w_cursor.col = orig_col; 6590 if (saved_text == NULL) 6591 break; /* Can't do it, out of memory */ 6592 saved_text[startcol] = NUL; 6593 6594 /* Backspace over characters that will move to the next line */ 6595 if (!fo_white_par) 6596 backspace_until_column(foundcol); 6597 } 6598 else 6599 { 6600 /* put cursor after pos. to break line */ 6601 if (!fo_white_par) 6602 curwin->w_cursor.col = foundcol; 6603 } 6604 6605 /* 6606 * Split the line just before the margin. 6607 * Only insert/delete lines, but don't really redraw the window. 6608 */ 6609 open_line(FORWARD, OPENLINE_DELSPACES + OPENLINE_MARKFIX 6610 + (fo_white_par ? OPENLINE_KEEPTRAIL : 0) 6611 #ifdef FEAT_COMMENTS 6612 + (do_comments ? OPENLINE_DO_COM : 0) 6613 + ((flags & INSCHAR_COM_LIST) ? OPENLINE_COM_LIST : 0) 6614 #endif 6615 , ((flags & INSCHAR_COM_LIST) ? second_indent : old_indent)); 6616 if (!(flags & INSCHAR_COM_LIST)) 6617 old_indent = 0; 6618 6619 replace_offset = 0; 6620 if (first_line) 6621 { 6622 if (!(flags & INSCHAR_COM_LIST)) 6623 { 6624 /* 6625 * This section is for auto-wrap of numeric lists. When not 6626 * in insert mode (i.e. format_lines()), the INSCHAR_COM_LIST 6627 * flag will be set and open_line() will handle it (as seen 6628 * above). The code here (and in get_number_indent()) will 6629 * recognize comments if needed... 6630 */ 6631 if (second_indent < 0 && has_format_option(FO_Q_NUMBER)) 6632 second_indent = 6633 get_number_indent(curwin->w_cursor.lnum - 1); 6634 if (second_indent >= 0) 6635 { 6636 if (State & VREPLACE_FLAG) 6637 change_indent(INDENT_SET, second_indent, 6638 FALSE, NUL, TRUE); 6639 else 6640 #ifdef FEAT_COMMENTS 6641 if (leader_len > 0 && second_indent - leader_len > 0) 6642 { 6643 int i; 6644 int padding = second_indent - leader_len; 6645 6646 /* We started at the first_line of a numbered list 6647 * that has a comment. the open_line() function has 6648 * inserted the proper comment leader and positioned 6649 * the cursor at the end of the split line. Now we 6650 * add the additional whitespace needed after the 6651 * comment leader for the numbered list. */ 6652 for (i = 0; i < padding; i++) 6653 ins_str((char_u *)" "); 6654 } 6655 else 6656 { 6657 #endif 6658 (void)set_indent(second_indent, SIN_CHANGED); 6659 #ifdef FEAT_COMMENTS 6660 } 6661 #endif 6662 } 6663 } 6664 first_line = FALSE; 6665 } 6666 6667 if (State & VREPLACE_FLAG) 6668 { 6669 /* 6670 * In VREPLACE mode we have backspaced over the text to be 6671 * moved, now we re-insert it into the new line. 6672 */ 6673 ins_bytes(saved_text); 6674 vim_free(saved_text); 6675 } 6676 else 6677 { 6678 /* 6679 * Check if cursor is not past the NUL off the line, cindent 6680 * may have added or removed indent. 6681 */ 6682 curwin->w_cursor.col += startcol; 6683 len = (colnr_T)STRLEN(ml_get_curline()); 6684 if (curwin->w_cursor.col > len) 6685 curwin->w_cursor.col = len; 6686 } 6687 6688 haveto_redraw = TRUE; 6689 #ifdef FEAT_CINDENT 6690 can_cindent = TRUE; 6691 #endif 6692 /* moved the cursor, don't autoindent or cindent now */ 6693 did_ai = FALSE; 6694 #ifdef FEAT_SMARTINDENT 6695 did_si = FALSE; 6696 can_si = FALSE; 6697 can_si_back = FALSE; 6698 #endif 6699 line_breakcheck(); 6700 } 6701 6702 if (save_char != NUL) /* put back space after cursor */ 6703 pchar_cursor(save_char); 6704 6705 #ifdef FEAT_LINEBREAK 6706 curwin->w_p_lbr = has_lbr; 6707 #endif 6708 if (!format_only && haveto_redraw) 6709 { 6710 update_topline(); 6711 redraw_curbuf_later(VALID); 6712 } 6713 } 6714 6715 /* 6716 * Called after inserting or deleting text: When 'formatoptions' includes the 6717 * 'a' flag format from the current line until the end of the paragraph. 6718 * Keep the cursor at the same position relative to the text. 6719 * The caller must have saved the cursor line for undo, following ones will be 6720 * saved here. 6721 */ 6722 void 6723 auto_format( 6724 int trailblank, /* when TRUE also format with trailing blank */ 6725 int prev_line) /* may start in previous line */ 6726 { 6727 pos_T pos; 6728 colnr_T len; 6729 char_u *old; 6730 char_u *new, *pnew; 6731 int wasatend; 6732 int cc; 6733 6734 if (!has_format_option(FO_AUTO)) 6735 return; 6736 6737 pos = curwin->w_cursor; 6738 old = ml_get_curline(); 6739 6740 /* may remove added space */ 6741 check_auto_format(FALSE); 6742 6743 /* Don't format in Insert mode when the cursor is on a trailing blank, the 6744 * user might insert normal text next. Also skip formatting when "1" is 6745 * in 'formatoptions' and there is a single character before the cursor. 6746 * Otherwise the line would be broken and when typing another non-white 6747 * next they are not joined back together. */ 6748 wasatend = (pos.col == (colnr_T)STRLEN(old)); 6749 if (*old != NUL && !trailblank && wasatend) 6750 { 6751 dec_cursor(); 6752 cc = gchar_cursor(); 6753 if (!WHITECHAR(cc) && curwin->w_cursor.col > 0 6754 && has_format_option(FO_ONE_LETTER)) 6755 dec_cursor(); 6756 cc = gchar_cursor(); 6757 if (WHITECHAR(cc)) 6758 { 6759 curwin->w_cursor = pos; 6760 return; 6761 } 6762 curwin->w_cursor = pos; 6763 } 6764 6765 #ifdef FEAT_COMMENTS 6766 /* With the 'c' flag in 'formatoptions' and 't' missing: only format 6767 * comments. */ 6768 if (has_format_option(FO_WRAP_COMS) && !has_format_option(FO_WRAP) 6769 && get_leader_len(old, NULL, FALSE, TRUE) == 0) 6770 return; 6771 #endif 6772 6773 /* 6774 * May start formatting in a previous line, so that after "x" a word is 6775 * moved to the previous line if it fits there now. Only when this is not 6776 * the start of a paragraph. 6777 */ 6778 if (prev_line && !paragraph_start(curwin->w_cursor.lnum)) 6779 { 6780 --curwin->w_cursor.lnum; 6781 if (u_save_cursor() == FAIL) 6782 return; 6783 } 6784 6785 /* 6786 * Do the formatting and restore the cursor position. "saved_cursor" will 6787 * be adjusted for the text formatting. 6788 */ 6789 saved_cursor = pos; 6790 format_lines((linenr_T)-1, FALSE); 6791 curwin->w_cursor = saved_cursor; 6792 saved_cursor.lnum = 0; 6793 6794 if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) 6795 { 6796 /* "cannot happen" */ 6797 curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; 6798 coladvance((colnr_T)MAXCOL); 6799 } 6800 else 6801 check_cursor_col(); 6802 6803 /* Insert mode: If the cursor is now after the end of the line while it 6804 * previously wasn't, the line was broken. Because of the rule above we 6805 * need to add a space when 'w' is in 'formatoptions' to keep a paragraph 6806 * formatted. */ 6807 if (!wasatend && has_format_option(FO_WHITE_PAR)) 6808 { 6809 new = ml_get_curline(); 6810 len = (colnr_T)STRLEN(new); 6811 if (curwin->w_cursor.col == len) 6812 { 6813 pnew = vim_strnsave(new, len + 2); 6814 pnew[len] = ' '; 6815 pnew[len + 1] = NUL; 6816 ml_replace(curwin->w_cursor.lnum, pnew, FALSE); 6817 /* remove the space later */ 6818 did_add_space = TRUE; 6819 } 6820 else 6821 /* may remove added space */ 6822 check_auto_format(FALSE); 6823 } 6824 6825 check_cursor(); 6826 } 6827 6828 /* 6829 * When an extra space was added to continue a paragraph for auto-formatting, 6830 * delete it now. The space must be under the cursor, just after the insert 6831 * position. 6832 */ 6833 static void 6834 check_auto_format( 6835 int end_insert) /* TRUE when ending Insert mode */ 6836 { 6837 int c = ' '; 6838 int cc; 6839 6840 if (did_add_space) 6841 { 6842 cc = gchar_cursor(); 6843 if (!WHITECHAR(cc)) 6844 /* Somehow the space was removed already. */ 6845 did_add_space = FALSE; 6846 else 6847 { 6848 if (!end_insert) 6849 { 6850 inc_cursor(); 6851 c = gchar_cursor(); 6852 dec_cursor(); 6853 } 6854 if (c != NUL) 6855 { 6856 /* The space is no longer at the end of the line, delete it. */ 6857 del_char(FALSE); 6858 did_add_space = FALSE; 6859 } 6860 } 6861 } 6862 } 6863 6864 /* 6865 * Find out textwidth to be used for formatting: 6866 * if 'textwidth' option is set, use it 6867 * else if 'wrapmargin' option is set, use curwin->w_width - 'wrapmargin' 6868 * if invalid value, use 0. 6869 * Set default to window width (maximum 79) for "gq" operator. 6870 */ 6871 int 6872 comp_textwidth( 6873 int ff) /* force formatting (for "gq" command) */ 6874 { 6875 int textwidth; 6876 6877 textwidth = curbuf->b_p_tw; 6878 if (textwidth == 0 && curbuf->b_p_wm) 6879 { 6880 /* The width is the window width minus 'wrapmargin' minus all the 6881 * things that add to the margin. */ 6882 textwidth = curwin->w_width - curbuf->b_p_wm; 6883 #ifdef FEAT_CMDWIN 6884 if (cmdwin_type != 0) 6885 textwidth -= 1; 6886 #endif 6887 #ifdef FEAT_FOLDING 6888 textwidth -= curwin->w_p_fdc; 6889 #endif 6890 #ifdef FEAT_SIGNS 6891 if (signcolumn_on(curwin)) 6892 textwidth -= 1; 6893 #endif 6894 if (curwin->w_p_nu || curwin->w_p_rnu) 6895 textwidth -= 8; 6896 } 6897 if (textwidth < 0) 6898 textwidth = 0; 6899 if (ff && textwidth == 0) 6900 { 6901 textwidth = curwin->w_width - 1; 6902 if (textwidth > 79) 6903 textwidth = 79; 6904 } 6905 return textwidth; 6906 } 6907 6908 /* 6909 * Put a character in the redo buffer, for when just after a CTRL-V. 6910 */ 6911 static void 6912 redo_literal(int c) 6913 { 6914 char_u buf[10]; 6915 6916 /* Only digits need special treatment. Translate them into a string of 6917 * three digits. */ 6918 if (VIM_ISDIGIT(c)) 6919 { 6920 vim_snprintf((char *)buf, sizeof(buf), "%03d", c); 6921 AppendToRedobuff(buf); 6922 } 6923 else 6924 AppendCharToRedobuff(c); 6925 } 6926 6927 /* 6928 * start_arrow() is called when an arrow key is used in insert mode. 6929 * For undo/redo it resembles hitting the <ESC> key. 6930 */ 6931 static void 6932 start_arrow( 6933 pos_T *end_insert_pos) /* can be NULL */ 6934 { 6935 start_arrow_common(end_insert_pos, TRUE); 6936 } 6937 6938 /* 6939 * Like start_arrow() but with end_change argument. 6940 * Will prepare for redo of CTRL-G U if "end_change" is FALSE. 6941 */ 6942 static void 6943 start_arrow_with_change( 6944 pos_T *end_insert_pos, /* can be NULL */ 6945 int end_change) /* end undoable change */ 6946 { 6947 start_arrow_common(end_insert_pos, end_change); 6948 if (!end_change) 6949 { 6950 AppendCharToRedobuff(Ctrl_G); 6951 AppendCharToRedobuff('U'); 6952 } 6953 } 6954 6955 static void 6956 start_arrow_common( 6957 pos_T *end_insert_pos, /* can be NULL */ 6958 int end_change) /* end undoable change */ 6959 { 6960 if (!arrow_used && end_change) /* something has been inserted */ 6961 { 6962 AppendToRedobuff(ESC_STR); 6963 stop_insert(end_insert_pos, FALSE, FALSE); 6964 arrow_used = TRUE; /* this means we stopped the current insert */ 6965 } 6966 #ifdef FEAT_SPELL 6967 check_spell_redraw(); 6968 #endif 6969 } 6970 6971 #ifdef FEAT_SPELL 6972 /* 6973 * If we skipped highlighting word at cursor, do it now. 6974 * It may be skipped again, thus reset spell_redraw_lnum first. 6975 */ 6976 static void 6977 check_spell_redraw(void) 6978 { 6979 if (spell_redraw_lnum != 0) 6980 { 6981 linenr_T lnum = spell_redraw_lnum; 6982 6983 spell_redraw_lnum = 0; 6984 redrawWinline(curwin, lnum); 6985 } 6986 } 6987 6988 /* 6989 * Called when starting CTRL_X_SPELL mode: Move backwards to a previous badly 6990 * spelled word, if there is one. 6991 */ 6992 static void 6993 spell_back_to_badword(void) 6994 { 6995 pos_T tpos = curwin->w_cursor; 6996 6997 spell_bad_len = spell_move_to(curwin, BACKWARD, TRUE, TRUE, NULL); 6998 if (curwin->w_cursor.col != tpos.col) 6999 start_arrow(&tpos); 7000 } 7001 #endif 7002 7003 /* 7004 * stop_arrow() is called before a change is made in insert mode. 7005 * If an arrow key has been used, start a new insertion. 7006 * Returns FAIL if undo is impossible, shouldn't insert then. 7007 */ 7008 int 7009 stop_arrow(void) 7010 { 7011 if (arrow_used) 7012 { 7013 Insstart = curwin->w_cursor; /* new insertion starts here */ 7014 if (Insstart.col > Insstart_orig.col && !ins_need_undo) 7015 /* Don't update the original insert position when moved to the 7016 * right, except when nothing was inserted yet. */ 7017 update_Insstart_orig = FALSE; 7018 Insstart_textlen = (colnr_T)linetabsize(ml_get_curline()); 7019 7020 if (u_save_cursor() == OK) 7021 { 7022 arrow_used = FALSE; 7023 ins_need_undo = FALSE; 7024 } 7025 7026 ai_col = 0; 7027 if (State & VREPLACE_FLAG) 7028 { 7029 orig_line_count = curbuf->b_ml.ml_line_count; 7030 vr_lines_changed = 1; 7031 } 7032 ResetRedobuff(); 7033 AppendToRedobuff((char_u *)"1i"); /* pretend we start an insertion */ 7034 new_insert_skip = 2; 7035 } 7036 else if (ins_need_undo) 7037 { 7038 if (u_save_cursor() == OK) 7039 ins_need_undo = FALSE; 7040 } 7041 7042 #ifdef FEAT_FOLDING 7043 /* Always open fold at the cursor line when inserting something. */ 7044 foldOpenCursor(); 7045 #endif 7046 7047 return (arrow_used || ins_need_undo ? FAIL : OK); 7048 } 7049 7050 /* 7051 * Do a few things to stop inserting. 7052 * "end_insert_pos" is where insert ended. It is NULL when we already jumped 7053 * to another window/buffer. 7054 */ 7055 static void 7056 stop_insert( 7057 pos_T *end_insert_pos, 7058 int esc, /* called by ins_esc() */ 7059 int nomove) /* <c-\><c-o>, don't move cursor */ 7060 { 7061 int cc; 7062 char_u *ptr; 7063 7064 stop_redo_ins(); 7065 replace_flush(); /* abandon replace stack */ 7066 7067 /* 7068 * Save the inserted text for later redo with ^@ and CTRL-A. 7069 * Don't do it when "restart_edit" was set and nothing was inserted, 7070 * otherwise CTRL-O w and then <Left> will clear "last_insert". 7071 */ 7072 ptr = get_inserted(); 7073 if (did_restart_edit == 0 || (ptr != NULL 7074 && (int)STRLEN(ptr) > new_insert_skip)) 7075 { 7076 vim_free(last_insert); 7077 last_insert = ptr; 7078 last_insert_skip = new_insert_skip; 7079 } 7080 else 7081 vim_free(ptr); 7082 7083 if (!arrow_used && end_insert_pos != NULL) 7084 { 7085 /* Auto-format now. It may seem strange to do this when stopping an 7086 * insertion (or moving the cursor), but it's required when appending 7087 * a line and having it end in a space. But only do it when something 7088 * was actually inserted, otherwise undo won't work. */ 7089 if (!ins_need_undo && has_format_option(FO_AUTO)) 7090 { 7091 pos_T tpos = curwin->w_cursor; 7092 7093 /* When the cursor is at the end of the line after a space the 7094 * formatting will move it to the following word. Avoid that by 7095 * moving the cursor onto the space. */ 7096 cc = 'x'; 7097 if (curwin->w_cursor.col > 0 && gchar_cursor() == NUL) 7098 { 7099 dec_cursor(); 7100 cc = gchar_cursor(); 7101 if (!VIM_ISWHITE(cc)) 7102 curwin->w_cursor = tpos; 7103 } 7104 7105 auto_format(TRUE, FALSE); 7106 7107 if (VIM_ISWHITE(cc)) 7108 { 7109 if (gchar_cursor() != NUL) 7110 inc_cursor(); 7111 // If the cursor is still at the same character, also keep 7112 // the "coladd". 7113 if (gchar_cursor() == NUL 7114 && curwin->w_cursor.lnum == tpos.lnum 7115 && curwin->w_cursor.col == tpos.col) 7116 curwin->w_cursor.coladd = tpos.coladd; 7117 } 7118 } 7119 7120 /* If a space was inserted for auto-formatting, remove it now. */ 7121 check_auto_format(TRUE); 7122 7123 /* If we just did an auto-indent, remove the white space from the end 7124 * of the line, and put the cursor back. 7125 * Do this when ESC was used or moving the cursor up/down. 7126 * Check for the old position still being valid, just in case the text 7127 * got changed unexpectedly. */ 7128 if (!nomove && did_ai && (esc || (vim_strchr(p_cpo, CPO_INDENT) == NULL 7129 && curwin->w_cursor.lnum != end_insert_pos->lnum)) 7130 && end_insert_pos->lnum <= curbuf->b_ml.ml_line_count) 7131 { 7132 pos_T tpos = curwin->w_cursor; 7133 7134 curwin->w_cursor = *end_insert_pos; 7135 check_cursor_col(); /* make sure it is not past the line */ 7136 for (;;) 7137 { 7138 if (gchar_cursor() == NUL && curwin->w_cursor.col > 0) 7139 --curwin->w_cursor.col; 7140 cc = gchar_cursor(); 7141 if (!VIM_ISWHITE(cc)) 7142 break; 7143 if (del_char(TRUE) == FAIL) 7144 break; /* should not happen */ 7145 } 7146 if (curwin->w_cursor.lnum != tpos.lnum) 7147 curwin->w_cursor = tpos; 7148 else 7149 { 7150 /* reset tpos, could have been invalidated in the loop above */ 7151 tpos = curwin->w_cursor; 7152 tpos.col++; 7153 if (cc != NUL && gchar_pos(&tpos) == NUL) 7154 ++curwin->w_cursor.col; /* put cursor back on the NUL */ 7155 } 7156 7157 /* <C-S-Right> may have started Visual mode, adjust the position for 7158 * deleted characters. */ 7159 if (VIsual_active && VIsual.lnum == curwin->w_cursor.lnum) 7160 { 7161 int len = (int)STRLEN(ml_get_curline()); 7162 7163 if (VIsual.col > len) 7164 { 7165 VIsual.col = len; 7166 VIsual.coladd = 0; 7167 } 7168 } 7169 } 7170 } 7171 did_ai = FALSE; 7172 #ifdef FEAT_SMARTINDENT 7173 did_si = FALSE; 7174 can_si = FALSE; 7175 can_si_back = FALSE; 7176 #endif 7177 7178 /* Set '[ and '] to the inserted text. When end_insert_pos is NULL we are 7179 * now in a different buffer. */ 7180 if (end_insert_pos != NULL) 7181 { 7182 curbuf->b_op_start = Insstart; 7183 curbuf->b_op_start_orig = Insstart_orig; 7184 curbuf->b_op_end = *end_insert_pos; 7185 } 7186 } 7187 7188 /* 7189 * Set the last inserted text to a single character. 7190 * Used for the replace command. 7191 */ 7192 void 7193 set_last_insert(int c) 7194 { 7195 char_u *s; 7196 7197 vim_free(last_insert); 7198 last_insert = alloc(MB_MAXBYTES * 3 + 5); 7199 if (last_insert != NULL) 7200 { 7201 s = last_insert; 7202 /* Use the CTRL-V only when entering a special char */ 7203 if (c < ' ' || c == DEL) 7204 *s++ = Ctrl_V; 7205 s = add_char2buf(c, s); 7206 *s++ = ESC; 7207 *s++ = NUL; 7208 last_insert_skip = 0; 7209 } 7210 } 7211 7212 #if defined(EXITFREE) || defined(PROTO) 7213 void 7214 free_last_insert(void) 7215 { 7216 VIM_CLEAR(last_insert); 7217 # ifdef FEAT_INS_EXPAND 7218 VIM_CLEAR(compl_orig_text); 7219 # endif 7220 } 7221 #endif 7222 7223 /* 7224 * Add character "c" to buffer "s". Escape the special meaning of K_SPECIAL 7225 * and CSI. Handle multi-byte characters. 7226 * Returns a pointer to after the added bytes. 7227 */ 7228 char_u * 7229 add_char2buf(int c, char_u *s) 7230 { 7231 char_u temp[MB_MAXBYTES + 1]; 7232 int i; 7233 int len; 7234 7235 len = (*mb_char2bytes)(c, temp); 7236 for (i = 0; i < len; ++i) 7237 { 7238 c = temp[i]; 7239 /* Need to escape K_SPECIAL and CSI like in the typeahead buffer. */ 7240 if (c == K_SPECIAL) 7241 { 7242 *s++ = K_SPECIAL; 7243 *s++ = KS_SPECIAL; 7244 *s++ = KE_FILLER; 7245 } 7246 #ifdef FEAT_GUI 7247 else if (c == CSI) 7248 { 7249 *s++ = CSI; 7250 *s++ = KS_EXTRA; 7251 *s++ = (int)KE_CSI; 7252 } 7253 #endif 7254 else 7255 *s++ = c; 7256 } 7257 return s; 7258 } 7259 7260 /* 7261 * move cursor to start of line 7262 * if flags & BL_WHITE move to first non-white 7263 * if flags & BL_SOL move to first non-white if startofline is set, 7264 * otherwise keep "curswant" column 7265 * if flags & BL_FIX don't leave the cursor on a NUL. 7266 */ 7267 void 7268 beginline(int flags) 7269 { 7270 if ((flags & BL_SOL) && !p_sol) 7271 coladvance(curwin->w_curswant); 7272 else 7273 { 7274 curwin->w_cursor.col = 0; 7275 curwin->w_cursor.coladd = 0; 7276 7277 if (flags & (BL_WHITE | BL_SOL)) 7278 { 7279 char_u *ptr; 7280 7281 for (ptr = ml_get_curline(); VIM_ISWHITE(*ptr) 7282 && !((flags & BL_FIX) && ptr[1] == NUL); ++ptr) 7283 ++curwin->w_cursor.col; 7284 } 7285 curwin->w_set_curswant = TRUE; 7286 } 7287 } 7288 7289 /* 7290 * oneright oneleft cursor_down cursor_up 7291 * 7292 * Move one char {right,left,down,up}. 7293 * Doesn't move onto the NUL past the end of the line, unless it is allowed. 7294 * Return OK when successful, FAIL when we hit a line of file boundary. 7295 */ 7296 7297 int 7298 oneright(void) 7299 { 7300 char_u *ptr; 7301 int l; 7302 7303 if (virtual_active()) 7304 { 7305 pos_T prevpos = curwin->w_cursor; 7306 7307 /* Adjust for multi-wide char (excluding TAB) */ 7308 ptr = ml_get_cursor(); 7309 coladvance(getviscol() + ((*ptr != TAB 7310 && vim_isprintc((*mb_ptr2char)(ptr))) 7311 ? ptr2cells(ptr) : 1)); 7312 curwin->w_set_curswant = TRUE; 7313 /* Return OK if the cursor moved, FAIL otherwise (at window edge). */ 7314 return (prevpos.col != curwin->w_cursor.col 7315 || prevpos.coladd != curwin->w_cursor.coladd) ? OK : FAIL; 7316 } 7317 7318 ptr = ml_get_cursor(); 7319 if (*ptr == NUL) 7320 return FAIL; /* already at the very end */ 7321 7322 if (has_mbyte) 7323 l = (*mb_ptr2len)(ptr); 7324 else 7325 l = 1; 7326 7327 /* move "l" bytes right, but don't end up on the NUL, unless 'virtualedit' 7328 * contains "onemore". */ 7329 if (ptr[l] == NUL && (ve_flags & VE_ONEMORE) == 0) 7330 return FAIL; 7331 curwin->w_cursor.col += l; 7332 7333 curwin->w_set_curswant = TRUE; 7334 return OK; 7335 } 7336 7337 int 7338 oneleft(void) 7339 { 7340 if (virtual_active()) 7341 { 7342 #ifdef FEAT_LINEBREAK 7343 int width; 7344 #endif 7345 int v = getviscol(); 7346 7347 if (v == 0) 7348 return FAIL; 7349 7350 #ifdef FEAT_LINEBREAK 7351 /* We might get stuck on 'showbreak', skip over it. */ 7352 width = 1; 7353 for (;;) 7354 { 7355 coladvance(v - width); 7356 /* getviscol() is slow, skip it when 'showbreak' is empty, 7357 * 'breakindent' is not set and there are no multi-byte 7358 * characters */ 7359 if ((*p_sbr == NUL && !curwin->w_p_bri 7360 && !has_mbyte) || getviscol() < v) 7361 break; 7362 ++width; 7363 } 7364 #else 7365 coladvance(v - 1); 7366 #endif 7367 7368 if (curwin->w_cursor.coladd == 1) 7369 { 7370 char_u *ptr; 7371 7372 /* Adjust for multi-wide char (not a TAB) */ 7373 ptr = ml_get_cursor(); 7374 if (*ptr != TAB && vim_isprintc((*mb_ptr2char)(ptr)) 7375 && ptr2cells(ptr) > 1) 7376 curwin->w_cursor.coladd = 0; 7377 } 7378 7379 curwin->w_set_curswant = TRUE; 7380 return OK; 7381 } 7382 7383 if (curwin->w_cursor.col == 0) 7384 return FAIL; 7385 7386 curwin->w_set_curswant = TRUE; 7387 --curwin->w_cursor.col; 7388 7389 /* if the character on the left of the current cursor is a multi-byte 7390 * character, move to its first byte */ 7391 if (has_mbyte) 7392 mb_adjust_cursor(); 7393 return OK; 7394 } 7395 7396 int 7397 cursor_up( 7398 long n, 7399 int upd_topline) /* When TRUE: update topline */ 7400 { 7401 linenr_T lnum; 7402 7403 if (n > 0) 7404 { 7405 lnum = curwin->w_cursor.lnum; 7406 /* This fails if the cursor is already in the first line or the count 7407 * is larger than the line number and '-' is in 'cpoptions' */ 7408 if (lnum <= 1 || (n >= lnum && vim_strchr(p_cpo, CPO_MINUS) != NULL)) 7409 return FAIL; 7410 if (n >= lnum) 7411 lnum = 1; 7412 else 7413 #ifdef FEAT_FOLDING 7414 if (hasAnyFolding(curwin)) 7415 { 7416 /* 7417 * Count each sequence of folded lines as one logical line. 7418 */ 7419 /* go to the start of the current fold */ 7420 (void)hasFolding(lnum, &lnum, NULL); 7421 7422 while (n--) 7423 { 7424 /* move up one line */ 7425 --lnum; 7426 if (lnum <= 1) 7427 break; 7428 /* If we entered a fold, move to the beginning, unless in 7429 * Insert mode or when 'foldopen' contains "all": it will open 7430 * in a moment. */ 7431 if (n > 0 || !((State & INSERT) || (fdo_flags & FDO_ALL))) 7432 (void)hasFolding(lnum, &lnum, NULL); 7433 } 7434 if (lnum < 1) 7435 lnum = 1; 7436 } 7437 else 7438 #endif 7439 lnum -= n; 7440 curwin->w_cursor.lnum = lnum; 7441 } 7442 7443 /* try to advance to the column we want to be at */ 7444 coladvance(curwin->w_curswant); 7445 7446 if (upd_topline) 7447 update_topline(); /* make sure curwin->w_topline is valid */ 7448 7449 return OK; 7450 } 7451 7452 /* 7453 * Cursor down a number of logical lines. 7454 */ 7455 int 7456 cursor_down( 7457 long n, 7458 int upd_topline) /* When TRUE: update topline */ 7459 { 7460 linenr_T lnum; 7461 7462 if (n > 0) 7463 { 7464 lnum = curwin->w_cursor.lnum; 7465 #ifdef FEAT_FOLDING 7466 /* Move to last line of fold, will fail if it's the end-of-file. */ 7467 (void)hasFolding(lnum, NULL, &lnum); 7468 #endif 7469 /* This fails if the cursor is already in the last line or would move 7470 * beyond the last line and '-' is in 'cpoptions' */ 7471 if (lnum >= curbuf->b_ml.ml_line_count 7472 || (lnum + n > curbuf->b_ml.ml_line_count 7473 && vim_strchr(p_cpo, CPO_MINUS) != NULL)) 7474 return FAIL; 7475 if (lnum + n >= curbuf->b_ml.ml_line_count) 7476 lnum = curbuf->b_ml.ml_line_count; 7477 else 7478 #ifdef FEAT_FOLDING 7479 if (hasAnyFolding(curwin)) 7480 { 7481 linenr_T last; 7482 7483 /* count each sequence of folded lines as one logical line */ 7484 while (n--) 7485 { 7486 if (hasFolding(lnum, NULL, &last)) 7487 lnum = last + 1; 7488 else 7489 ++lnum; 7490 if (lnum >= curbuf->b_ml.ml_line_count) 7491 break; 7492 } 7493 if (lnum > curbuf->b_ml.ml_line_count) 7494 lnum = curbuf->b_ml.ml_line_count; 7495 } 7496 else 7497 #endif 7498 lnum += n; 7499 curwin->w_cursor.lnum = lnum; 7500 } 7501 7502 /* try to advance to the column we want to be at */ 7503 coladvance(curwin->w_curswant); 7504 7505 if (upd_topline) 7506 update_topline(); /* make sure curwin->w_topline is valid */ 7507 7508 return OK; 7509 } 7510 7511 /* 7512 * Stuff the last inserted text in the read buffer. 7513 * Last_insert actually is a copy of the redo buffer, so we 7514 * first have to remove the command. 7515 */ 7516 int 7517 stuff_inserted( 7518 int c, /* Command character to be inserted */ 7519 long count, /* Repeat this many times */ 7520 int no_esc) /* Don't add an ESC at the end */ 7521 { 7522 char_u *esc_ptr; 7523 char_u *ptr; 7524 char_u *last_ptr; 7525 char_u last = NUL; 7526 7527 ptr = get_last_insert(); 7528 if (ptr == NULL) 7529 { 7530 emsg(_(e_noinstext)); 7531 return FAIL; 7532 } 7533 7534 /* may want to stuff the command character, to start Insert mode */ 7535 if (c != NUL) 7536 stuffcharReadbuff(c); 7537 if ((esc_ptr = (char_u *)vim_strrchr(ptr, ESC)) != NULL) 7538 *esc_ptr = NUL; /* remove the ESC */ 7539 7540 /* when the last char is either "0" or "^" it will be quoted if no ESC 7541 * comes after it OR if it will inserted more than once and "ptr" 7542 * starts with ^D. -- Acevedo 7543 */ 7544 last_ptr = (esc_ptr ? esc_ptr : ptr + STRLEN(ptr)) - 1; 7545 if (last_ptr >= ptr && (*last_ptr == '0' || *last_ptr == '^') 7546 && (no_esc || (*ptr == Ctrl_D && count > 1))) 7547 { 7548 last = *last_ptr; 7549 *last_ptr = NUL; 7550 } 7551 7552 do 7553 { 7554 stuffReadbuff(ptr); 7555 /* a trailing "0" is inserted as "<C-V>048", "^" as "<C-V>^" */ 7556 if (last) 7557 stuffReadbuff((char_u *)(last == '0' 7558 ? IF_EB("\026\060\064\070", CTRL_V_STR "xf0") 7559 : IF_EB("\026^", CTRL_V_STR "^"))); 7560 } 7561 while (--count > 0); 7562 7563 if (last) 7564 *last_ptr = last; 7565 7566 if (esc_ptr != NULL) 7567 *esc_ptr = ESC; /* put the ESC back */ 7568 7569 /* may want to stuff a trailing ESC, to get out of Insert mode */ 7570 if (!no_esc) 7571 stuffcharReadbuff(ESC); 7572 7573 return OK; 7574 } 7575 7576 char_u * 7577 get_last_insert(void) 7578 { 7579 if (last_insert == NULL) 7580 return NULL; 7581 return last_insert + last_insert_skip; 7582 } 7583 7584 /* 7585 * Get last inserted string, and remove trailing <Esc>. 7586 * Returns pointer to allocated memory (must be freed) or NULL. 7587 */ 7588 char_u * 7589 get_last_insert_save(void) 7590 { 7591 char_u *s; 7592 int len; 7593 7594 if (last_insert == NULL) 7595 return NULL; 7596 s = vim_strsave(last_insert + last_insert_skip); 7597 if (s != NULL) 7598 { 7599 len = (int)STRLEN(s); 7600 if (len > 0 && s[len - 1] == ESC) /* remove trailing ESC */ 7601 s[len - 1] = NUL; 7602 } 7603 return s; 7604 } 7605 7606 /* 7607 * Check the word in front of the cursor for an abbreviation. 7608 * Called when the non-id character "c" has been entered. 7609 * When an abbreviation is recognized it is removed from the text and 7610 * the replacement string is inserted in typebuf.tb_buf[], followed by "c". 7611 */ 7612 static int 7613 echeck_abbr(int c) 7614 { 7615 /* Don't check for abbreviation in paste mode, when disabled and just 7616 * after moving around with cursor keys. */ 7617 if (p_paste || no_abbr || arrow_used) 7618 return FALSE; 7619 7620 return check_abbr(c, ml_get_curline(), curwin->w_cursor.col, 7621 curwin->w_cursor.lnum == Insstart.lnum ? Insstart.col : 0); 7622 } 7623 7624 /* 7625 * replace-stack functions 7626 * 7627 * When replacing characters, the replaced characters are remembered for each 7628 * new character. This is used to re-insert the old text when backspacing. 7629 * 7630 * There is a NUL headed list of characters for each character that is 7631 * currently in the file after the insertion point. When BS is used, one NUL 7632 * headed list is put back for the deleted character. 7633 * 7634 * For a newline, there are two NUL headed lists. One contains the characters 7635 * that the NL replaced. The extra one stores the characters after the cursor 7636 * that were deleted (always white space). 7637 * 7638 * Replace_offset is normally 0, in which case replace_push will add a new 7639 * character at the end of the stack. If replace_offset is not 0, that many 7640 * characters will be left on the stack above the newly inserted character. 7641 */ 7642 7643 static char_u *replace_stack = NULL; 7644 static long replace_stack_nr = 0; /* next entry in replace stack */ 7645 static long replace_stack_len = 0; /* max. number of entries */ 7646 7647 void 7648 replace_push( 7649 int c) /* character that is replaced (NUL is none) */ 7650 { 7651 char_u *p; 7652 7653 if (replace_stack_nr < replace_offset) /* nothing to do */ 7654 return; 7655 if (replace_stack_len <= replace_stack_nr) 7656 { 7657 replace_stack_len += 50; 7658 p = lalloc(sizeof(char_u) * replace_stack_len, TRUE); 7659 if (p == NULL) /* out of memory */ 7660 { 7661 replace_stack_len -= 50; 7662 return; 7663 } 7664 if (replace_stack != NULL) 7665 { 7666 mch_memmove(p, replace_stack, 7667 (size_t)(replace_stack_nr * sizeof(char_u))); 7668 vim_free(replace_stack); 7669 } 7670 replace_stack = p; 7671 } 7672 p = replace_stack + replace_stack_nr - replace_offset; 7673 if (replace_offset) 7674 mch_memmove(p + 1, p, (size_t)(replace_offset * sizeof(char_u))); 7675 *p = c; 7676 ++replace_stack_nr; 7677 } 7678 7679 /* 7680 * Push a character onto the replace stack. Handles a multi-byte character in 7681 * reverse byte order, so that the first byte is popped off first. 7682 * Return the number of bytes done (includes composing characters). 7683 */ 7684 int 7685 replace_push_mb(char_u *p) 7686 { 7687 int l = (*mb_ptr2len)(p); 7688 int j; 7689 7690 for (j = l - 1; j >= 0; --j) 7691 replace_push(p[j]); 7692 return l; 7693 } 7694 7695 /* 7696 * Pop one item from the replace stack. 7697 * return -1 if stack empty 7698 * return replaced character or NUL otherwise 7699 */ 7700 static int 7701 replace_pop(void) 7702 { 7703 if (replace_stack_nr == 0) 7704 return -1; 7705 return (int)replace_stack[--replace_stack_nr]; 7706 } 7707 7708 /* 7709 * Join the top two items on the replace stack. This removes to "off"'th NUL 7710 * encountered. 7711 */ 7712 static void 7713 replace_join( 7714 int off) /* offset for which NUL to remove */ 7715 { 7716 int i; 7717 7718 for (i = replace_stack_nr; --i >= 0; ) 7719 if (replace_stack[i] == NUL && off-- <= 0) 7720 { 7721 --replace_stack_nr; 7722 mch_memmove(replace_stack + i, replace_stack + i + 1, 7723 (size_t)(replace_stack_nr - i)); 7724 return; 7725 } 7726 } 7727 7728 /* 7729 * Pop bytes from the replace stack until a NUL is found, and insert them 7730 * before the cursor. Can only be used in REPLACE or VREPLACE mode. 7731 */ 7732 static void 7733 replace_pop_ins(void) 7734 { 7735 int cc; 7736 int oldState = State; 7737 7738 State = NORMAL; /* don't want REPLACE here */ 7739 while ((cc = replace_pop()) > 0) 7740 { 7741 mb_replace_pop_ins(cc); 7742 dec_cursor(); 7743 } 7744 State = oldState; 7745 } 7746 7747 /* 7748 * Insert bytes popped from the replace stack. "cc" is the first byte. If it 7749 * indicates a multi-byte char, pop the other bytes too. 7750 */ 7751 static void 7752 mb_replace_pop_ins(int cc) 7753 { 7754 int n; 7755 char_u buf[MB_MAXBYTES + 1]; 7756 int i; 7757 int c; 7758 7759 if (has_mbyte && (n = MB_BYTE2LEN(cc)) > 1) 7760 { 7761 buf[0] = cc; 7762 for (i = 1; i < n; ++i) 7763 buf[i] = replace_pop(); 7764 ins_bytes_len(buf, n); 7765 } 7766 else 7767 ins_char(cc); 7768 7769 if (enc_utf8) 7770 /* Handle composing chars. */ 7771 for (;;) 7772 { 7773 c = replace_pop(); 7774 if (c == -1) /* stack empty */ 7775 break; 7776 if ((n = MB_BYTE2LEN(c)) == 1) 7777 { 7778 /* Not a multi-byte char, put it back. */ 7779 replace_push(c); 7780 break; 7781 } 7782 else 7783 { 7784 buf[0] = c; 7785 for (i = 1; i < n; ++i) 7786 buf[i] = replace_pop(); 7787 if (utf_iscomposing(utf_ptr2char(buf))) 7788 ins_bytes_len(buf, n); 7789 else 7790 { 7791 /* Not a composing char, put it back. */ 7792 for (i = n - 1; i >= 0; --i) 7793 replace_push(buf[i]); 7794 break; 7795 } 7796 } 7797 } 7798 } 7799 7800 /* 7801 * make the replace stack empty 7802 * (called when exiting replace mode) 7803 */ 7804 static void 7805 replace_flush(void) 7806 { 7807 VIM_CLEAR(replace_stack); 7808 replace_stack_len = 0; 7809 replace_stack_nr = 0; 7810 } 7811 7812 /* 7813 * Handle doing a BS for one character. 7814 * cc < 0: replace stack empty, just move cursor 7815 * cc == 0: character was inserted, delete it 7816 * cc > 0: character was replaced, put cc (first byte of original char) back 7817 * and check for more characters to be put back 7818 * When "limit_col" is >= 0, don't delete before this column. Matters when 7819 * using composing characters, use del_char_after_col() instead of del_char(). 7820 */ 7821 static void 7822 replace_do_bs(int limit_col) 7823 { 7824 int cc; 7825 int orig_len = 0; 7826 int ins_len; 7827 int orig_vcols = 0; 7828 colnr_T start_vcol; 7829 char_u *p; 7830 int i; 7831 int vcol; 7832 7833 cc = replace_pop(); 7834 if (cc > 0) 7835 { 7836 #ifdef FEAT_TEXT_PROP 7837 size_t len_before = 0; // init to shut up GCC 7838 7839 if (curbuf->b_has_textprop) 7840 { 7841 // Do not adjust text properties for individual delete and insert 7842 // operations, do it afterwards on the resulting text. 7843 len_before = STRLEN(ml_get_curline()); 7844 ++text_prop_frozen; 7845 } 7846 #endif 7847 if (State & VREPLACE_FLAG) 7848 { 7849 /* Get the number of screen cells used by the character we are 7850 * going to delete. */ 7851 getvcol(curwin, &curwin->w_cursor, NULL, &start_vcol, NULL); 7852 orig_vcols = chartabsize(ml_get_cursor(), start_vcol); 7853 } 7854 if (has_mbyte) 7855 { 7856 (void)del_char_after_col(limit_col); 7857 if (State & VREPLACE_FLAG) 7858 orig_len = (int)STRLEN(ml_get_cursor()); 7859 replace_push(cc); 7860 } 7861 else 7862 { 7863 pchar_cursor(cc); 7864 if (State & VREPLACE_FLAG) 7865 orig_len = (int)STRLEN(ml_get_cursor()) - 1; 7866 } 7867 replace_pop_ins(); 7868 7869 if (State & VREPLACE_FLAG) 7870 { 7871 /* Get the number of screen cells used by the inserted characters */ 7872 p = ml_get_cursor(); 7873 ins_len = (int)STRLEN(p) - orig_len; 7874 vcol = start_vcol; 7875 for (i = 0; i < ins_len; ++i) 7876 { 7877 vcol += chartabsize(p + i, vcol); 7878 i += (*mb_ptr2len)(p) - 1; 7879 } 7880 vcol -= start_vcol; 7881 7882 /* Delete spaces that were inserted after the cursor to keep the 7883 * text aligned. */ 7884 curwin->w_cursor.col += ins_len; 7885 while (vcol > orig_vcols && gchar_cursor() == ' ') 7886 { 7887 del_char(FALSE); 7888 ++orig_vcols; 7889 } 7890 curwin->w_cursor.col -= ins_len; 7891 } 7892 7893 // mark the buffer as changed and prepare for displaying 7894 changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col); 7895 7896 #ifdef FEAT_TEXT_PROP 7897 if (curbuf->b_has_textprop) 7898 { 7899 size_t len_now = STRLEN(ml_get_curline()); 7900 7901 --text_prop_frozen; 7902 adjust_prop_columns(curwin->w_cursor.lnum, curwin->w_cursor.col, 7903 (int)(len_now - len_before)); 7904 } 7905 #endif 7906 } 7907 else if (cc == 0) 7908 (void)del_char_after_col(limit_col); 7909 } 7910 7911 #if defined(FEAT_RIGHTLEFT) || defined(PROTO) 7912 /* 7913 * Map Hebrew keyboard when in hkmap mode. 7914 */ 7915 int 7916 hkmap(int c) 7917 { 7918 if (p_hkmapp) /* phonetic mapping, by Ilya Dogolazky */ 7919 { 7920 enum {hALEF=0, BET, GIMEL, DALET, HEI, VAV, ZAIN, HET, TET, IUD, 7921 KAFsofit, hKAF, LAMED, MEMsofit, MEM, NUNsofit, NUN, SAMEH, AIN, 7922 PEIsofit, PEI, ZADIsofit, ZADI, KOF, RESH, hSHIN, TAV}; 7923 static char_u map[26] = 7924 {(char_u)hALEF/*a*/, (char_u)BET /*b*/, (char_u)hKAF /*c*/, 7925 (char_u)DALET/*d*/, (char_u)-1 /*e*/, (char_u)PEIsofit/*f*/, 7926 (char_u)GIMEL/*g*/, (char_u)HEI /*h*/, (char_u)IUD /*i*/, 7927 (char_u)HET /*j*/, (char_u)KOF /*k*/, (char_u)LAMED /*l*/, 7928 (char_u)MEM /*m*/, (char_u)NUN /*n*/, (char_u)SAMEH /*o*/, 7929 (char_u)PEI /*p*/, (char_u)-1 /*q*/, (char_u)RESH /*r*/, 7930 (char_u)ZAIN /*s*/, (char_u)TAV /*t*/, (char_u)TET /*u*/, 7931 (char_u)VAV /*v*/, (char_u)hSHIN/*w*/, (char_u)-1 /*x*/, 7932 (char_u)AIN /*y*/, (char_u)ZADI /*z*/}; 7933 7934 if (c == 'N' || c == 'M' || c == 'P' || c == 'C' || c == 'Z') 7935 return (int)(map[CharOrd(c)] - 1 + p_aleph); 7936 /* '-1'='sofit' */ 7937 else if (c == 'x') 7938 return 'X'; 7939 else if (c == 'q') 7940 return '\''; /* {geresh}={'} */ 7941 else if (c == 246) 7942 return ' '; /* \"o --> ' ' for a german keyboard */ 7943 else if (c == 228) 7944 return ' '; /* \"a --> ' ' -- / -- */ 7945 else if (c == 252) 7946 return ' '; /* \"u --> ' ' -- / -- */ 7947 #ifdef EBCDIC 7948 else if (islower(c)) 7949 #else 7950 /* NOTE: islower() does not do the right thing for us on Linux so we 7951 * do this the same was as 5.7 and previous, so it works correctly on 7952 * all systems. Specifically, the e.g. Delete and Arrow keys are 7953 * munged and won't work if e.g. searching for Hebrew text. 7954 */ 7955 else if (c >= 'a' && c <= 'z') 7956 #endif 7957 return (int)(map[CharOrdLow(c)] + p_aleph); 7958 else 7959 return c; 7960 } 7961 else 7962 { 7963 switch (c) 7964 { 7965 case '`': return ';'; 7966 case '/': return '.'; 7967 case '\'': return ','; 7968 case 'q': return '/'; 7969 case 'w': return '\''; 7970 7971 /* Hebrew letters - set offset from 'a' */ 7972 case ',': c = '{'; break; 7973 case '.': c = 'v'; break; 7974 case ';': c = 't'; break; 7975 default: { 7976 static char str[] = "zqbcxlsjphmkwonu ydafe rig"; 7977 7978 #ifdef EBCDIC 7979 /* see note about islower() above */ 7980 if (!islower(c)) 7981 #else 7982 if (c < 'a' || c > 'z') 7983 #endif 7984 return c; 7985 c = str[CharOrdLow(c)]; 7986 break; 7987 } 7988 } 7989 7990 return (int)(CharOrdLow(c) + p_aleph); 7991 } 7992 } 7993 #endif 7994 7995 static void 7996 ins_reg(void) 7997 { 7998 int need_redraw = FALSE; 7999 int regname; 8000 int literally = 0; 8001 int vis_active = VIsual_active; 8002 8003 /* 8004 * If we are going to wait for a character, show a '"'. 8005 */ 8006 pc_status = PC_STATUS_UNSET; 8007 if (redrawing() && !char_avail()) 8008 { 8009 /* may need to redraw when no more chars available now */ 8010 ins_redraw(FALSE); 8011 8012 edit_putchar('"', TRUE); 8013 #ifdef FEAT_CMDL_INFO 8014 add_to_showcmd_c(Ctrl_R); 8015 #endif 8016 } 8017 8018 #ifdef USE_ON_FLY_SCROLL 8019 dont_scroll = TRUE; /* disallow scrolling here */ 8020 #endif 8021 8022 /* 8023 * Don't map the register name. This also prevents the mode message to be 8024 * deleted when ESC is hit. 8025 */ 8026 ++no_mapping; 8027 regname = plain_vgetc(); 8028 LANGMAP_ADJUST(regname, TRUE); 8029 if (regname == Ctrl_R || regname == Ctrl_O || regname == Ctrl_P) 8030 { 8031 /* Get a third key for literal register insertion */ 8032 literally = regname; 8033 #ifdef FEAT_CMDL_INFO 8034 add_to_showcmd_c(literally); 8035 #endif 8036 regname = plain_vgetc(); 8037 LANGMAP_ADJUST(regname, TRUE); 8038 } 8039 --no_mapping; 8040 8041 #ifdef FEAT_EVAL 8042 /* Don't call u_sync() while typing the expression or giving an error 8043 * message for it. Only call it explicitly. */ 8044 ++no_u_sync; 8045 if (regname == '=') 8046 { 8047 pos_T curpos = curwin->w_cursor; 8048 # ifdef HAVE_INPUT_METHOD 8049 int im_on = im_get_status(); 8050 # endif 8051 /* Sync undo when evaluating the expression calls setline() or 8052 * append(), so that it can be undone separately. */ 8053 u_sync_once = 2; 8054 8055 regname = get_expr_register(); 8056 8057 // Cursor may be moved back a column. 8058 curwin->w_cursor = curpos; 8059 check_cursor(); 8060 # ifdef HAVE_INPUT_METHOD 8061 // Restore the Input Method. 8062 if (im_on) 8063 im_set_active(TRUE); 8064 # endif 8065 } 8066 if (regname == NUL || !valid_yank_reg(regname, FALSE)) 8067 { 8068 vim_beep(BO_REG); 8069 need_redraw = TRUE; /* remove the '"' */ 8070 } 8071 else 8072 { 8073 #endif 8074 if (literally == Ctrl_O || literally == Ctrl_P) 8075 { 8076 /* Append the command to the redo buffer. */ 8077 AppendCharToRedobuff(Ctrl_R); 8078 AppendCharToRedobuff(literally); 8079 AppendCharToRedobuff(regname); 8080 8081 do_put(regname, BACKWARD, 1L, 8082 (literally == Ctrl_P ? PUT_FIXINDENT : 0) | PUT_CURSEND); 8083 } 8084 else if (insert_reg(regname, literally) == FAIL) 8085 { 8086 vim_beep(BO_REG); 8087 need_redraw = TRUE; /* remove the '"' */ 8088 } 8089 else if (stop_insert_mode) 8090 /* When the '=' register was used and a function was invoked that 8091 * did ":stopinsert" then stuff_empty() returns FALSE but we won't 8092 * insert anything, need to remove the '"' */ 8093 need_redraw = TRUE; 8094 8095 #ifdef FEAT_EVAL 8096 } 8097 --no_u_sync; 8098 if (u_sync_once == 1) 8099 ins_need_undo = TRUE; 8100 u_sync_once = 0; 8101 #endif 8102 #ifdef FEAT_CMDL_INFO 8103 clear_showcmd(); 8104 #endif 8105 8106 /* If the inserted register is empty, we need to remove the '"' */ 8107 if (need_redraw || stuff_empty()) 8108 edit_unputchar(); 8109 8110 /* Disallow starting Visual mode here, would get a weird mode. */ 8111 if (!vis_active && VIsual_active) 8112 end_visual_mode(); 8113 } 8114 8115 /* 8116 * CTRL-G commands in Insert mode. 8117 */ 8118 static void 8119 ins_ctrl_g(void) 8120 { 8121 int c; 8122 8123 #ifdef FEAT_INS_EXPAND 8124 /* Right after CTRL-X the cursor will be after the ruler. */ 8125 setcursor(); 8126 #endif 8127 8128 /* 8129 * Don't map the second key. This also prevents the mode message to be 8130 * deleted when ESC is hit. 8131 */ 8132 ++no_mapping; 8133 c = plain_vgetc(); 8134 --no_mapping; 8135 switch (c) 8136 { 8137 /* CTRL-G k and CTRL-G <Up>: cursor up to Insstart.col */ 8138 case K_UP: 8139 case Ctrl_K: 8140 case 'k': ins_up(TRUE); 8141 break; 8142 8143 /* CTRL-G j and CTRL-G <Down>: cursor down to Insstart.col */ 8144 case K_DOWN: 8145 case Ctrl_J: 8146 case 'j': ins_down(TRUE); 8147 break; 8148 8149 /* CTRL-G u: start new undoable edit */ 8150 case 'u': u_sync(TRUE); 8151 ins_need_undo = TRUE; 8152 8153 /* Need to reset Insstart, esp. because a BS that joins 8154 * a line to the previous one must save for undo. */ 8155 update_Insstart_orig = FALSE; 8156 Insstart = curwin->w_cursor; 8157 break; 8158 8159 /* CTRL-G U: do not break undo with the next char */ 8160 case 'U': 8161 /* Allow one left/right cursor movement with the next char, 8162 * without breaking undo. */ 8163 dont_sync_undo = MAYBE; 8164 break; 8165 8166 /* Unknown CTRL-G command, reserved for future expansion. */ 8167 default: vim_beep(BO_CTRLG); 8168 } 8169 } 8170 8171 /* 8172 * CTRL-^ in Insert mode. 8173 */ 8174 static void 8175 ins_ctrl_hat(void) 8176 { 8177 if (map_to_exists_mode((char_u *)"", LANGMAP, FALSE)) 8178 { 8179 /* ":lmap" mappings exists, Toggle use of ":lmap" mappings. */ 8180 if (State & LANGMAP) 8181 { 8182 curbuf->b_p_iminsert = B_IMODE_NONE; 8183 State &= ~LANGMAP; 8184 } 8185 else 8186 { 8187 curbuf->b_p_iminsert = B_IMODE_LMAP; 8188 State |= LANGMAP; 8189 #ifdef HAVE_INPUT_METHOD 8190 im_set_active(FALSE); 8191 #endif 8192 } 8193 } 8194 #ifdef HAVE_INPUT_METHOD 8195 else 8196 { 8197 /* There are no ":lmap" mappings, toggle IM */ 8198 if (im_get_status()) 8199 { 8200 curbuf->b_p_iminsert = B_IMODE_NONE; 8201 im_set_active(FALSE); 8202 } 8203 else 8204 { 8205 curbuf->b_p_iminsert = B_IMODE_IM; 8206 State &= ~LANGMAP; 8207 im_set_active(TRUE); 8208 } 8209 } 8210 #endif 8211 set_iminsert_global(); 8212 showmode(); 8213 #ifdef FEAT_GUI 8214 /* may show different cursor shape or color */ 8215 if (gui.in_use) 8216 gui_update_cursor(TRUE, FALSE); 8217 #endif 8218 #if defined(FEAT_KEYMAP) 8219 /* Show/unshow value of 'keymap' in status lines. */ 8220 status_redraw_curbuf(); 8221 #endif 8222 } 8223 8224 /* 8225 * Handle ESC in insert mode. 8226 * Returns TRUE when leaving insert mode, FALSE when going to repeat the 8227 * insert. 8228 */ 8229 static int 8230 ins_esc( 8231 long *count, 8232 int cmdchar, 8233 int nomove) /* don't move cursor */ 8234 { 8235 int temp; 8236 static int disabled_redraw = FALSE; 8237 8238 #ifdef FEAT_SPELL 8239 check_spell_redraw(); 8240 #endif 8241 #if defined(FEAT_HANGULIN) 8242 # if defined(ESC_CHG_TO_ENG_MODE) 8243 hangul_input_state_set(0); 8244 # endif 8245 if (composing_hangul) 8246 { 8247 push_raw_key(composing_hangul_buffer, 2); 8248 composing_hangul = 0; 8249 } 8250 #endif 8251 8252 temp = curwin->w_cursor.col; 8253 if (disabled_redraw) 8254 { 8255 --RedrawingDisabled; 8256 disabled_redraw = FALSE; 8257 } 8258 if (!arrow_used) 8259 { 8260 /* 8261 * Don't append the ESC for "r<CR>" and "grx". 8262 * When 'insertmode' is set only CTRL-L stops Insert mode. Needed for 8263 * when "count" is non-zero. 8264 */ 8265 if (cmdchar != 'r' && cmdchar != 'v') 8266 AppendToRedobuff(p_im ? (char_u *)"\014" : ESC_STR); 8267 8268 /* 8269 * Repeating insert may take a long time. Check for 8270 * interrupt now and then. 8271 */ 8272 if (*count > 0) 8273 { 8274 line_breakcheck(); 8275 if (got_int) 8276 *count = 0; 8277 } 8278 8279 if (--*count > 0) /* repeat what was typed */ 8280 { 8281 /* Vi repeats the insert without replacing characters. */ 8282 if (vim_strchr(p_cpo, CPO_REPLCNT) != NULL) 8283 State &= ~REPLACE_FLAG; 8284 8285 (void)start_redo_ins(); 8286 if (cmdchar == 'r' || cmdchar == 'v') 8287 stuffRedoReadbuff(ESC_STR); /* no ESC in redo buffer */ 8288 ++RedrawingDisabled; 8289 disabled_redraw = TRUE; 8290 return FALSE; /* repeat the insert */ 8291 } 8292 stop_insert(&curwin->w_cursor, TRUE, nomove); 8293 undisplay_dollar(); 8294 } 8295 8296 /* When an autoindent was removed, curswant stays after the 8297 * indent */ 8298 if (restart_edit == NUL && (colnr_T)temp == curwin->w_cursor.col) 8299 curwin->w_set_curswant = TRUE; 8300 8301 /* Remember the last Insert position in the '^ mark. */ 8302 if (!cmdmod.keepjumps) 8303 curbuf->b_last_insert = curwin->w_cursor; 8304 8305 /* 8306 * The cursor should end up on the last inserted character. 8307 * Don't do it for CTRL-O, unless past the end of the line. 8308 */ 8309 if (!nomove 8310 && (curwin->w_cursor.col != 0 8311 || curwin->w_cursor.coladd > 0) 8312 && (restart_edit == NUL 8313 || (gchar_cursor() == NUL && !VIsual_active)) 8314 #ifdef FEAT_RIGHTLEFT 8315 && !revins_on 8316 #endif 8317 ) 8318 { 8319 if (curwin->w_cursor.coladd > 0 || ve_flags == VE_ALL) 8320 { 8321 oneleft(); 8322 if (restart_edit != NUL) 8323 ++curwin->w_cursor.coladd; 8324 } 8325 else 8326 { 8327 --curwin->w_cursor.col; 8328 /* Correct cursor for multi-byte character. */ 8329 if (has_mbyte) 8330 mb_adjust_cursor(); 8331 } 8332 } 8333 8334 #ifdef HAVE_INPUT_METHOD 8335 /* Disable IM to allow typing English directly for Normal mode commands. 8336 * When ":lmap" is enabled don't change 'iminsert' (IM can be enabled as 8337 * well). */ 8338 if (!(State & LANGMAP)) 8339 im_save_status(&curbuf->b_p_iminsert); 8340 im_set_active(FALSE); 8341 #endif 8342 8343 State = NORMAL; 8344 /* need to position cursor again (e.g. when on a TAB ) */ 8345 changed_cline_bef_curs(); 8346 8347 #ifdef FEAT_MOUSE 8348 setmouse(); 8349 #endif 8350 #ifdef CURSOR_SHAPE 8351 ui_cursor_shape(); /* may show different cursor shape */ 8352 #endif 8353 if (!p_ek) 8354 /* Re-enable bracketed paste mode. */ 8355 out_str(T_BE); 8356 8357 /* 8358 * When recording or for CTRL-O, need to display the new mode. 8359 * Otherwise remove the mode message. 8360 */ 8361 if (reg_recording != 0 || restart_edit != NUL) 8362 showmode(); 8363 else if (p_smd && !skip_showmode()) 8364 msg(""); 8365 8366 return TRUE; /* exit Insert mode */ 8367 } 8368 8369 #ifdef FEAT_RIGHTLEFT 8370 /* 8371 * Toggle language: hkmap and revins_on. 8372 * Move to end of reverse inserted text. 8373 */ 8374 static void 8375 ins_ctrl_(void) 8376 { 8377 if (revins_on && revins_chars && revins_scol >= 0) 8378 { 8379 while (gchar_cursor() != NUL && revins_chars--) 8380 ++curwin->w_cursor.col; 8381 } 8382 p_ri = !p_ri; 8383 revins_on = (State == INSERT && p_ri); 8384 if (revins_on) 8385 { 8386 revins_scol = curwin->w_cursor.col; 8387 revins_legal++; 8388 revins_chars = 0; 8389 undisplay_dollar(); 8390 } 8391 else 8392 revins_scol = -1; 8393 p_hkmap = curwin->w_p_rl ^ p_ri; // be consistent! 8394 showmode(); 8395 } 8396 #endif 8397 8398 /* 8399 * If 'keymodel' contains "startsel", may start selection. 8400 * Returns TRUE when a CTRL-O and other keys stuffed. 8401 */ 8402 static int 8403 ins_start_select(int c) 8404 { 8405 if (km_startsel) 8406 switch (c) 8407 { 8408 case K_KHOME: 8409 case K_KEND: 8410 case K_PAGEUP: 8411 case K_KPAGEUP: 8412 case K_PAGEDOWN: 8413 case K_KPAGEDOWN: 8414 # ifdef MACOS_X 8415 case K_LEFT: 8416 case K_RIGHT: 8417 case K_UP: 8418 case K_DOWN: 8419 case K_END: 8420 case K_HOME: 8421 # endif 8422 if (!(mod_mask & MOD_MASK_SHIFT)) 8423 break; 8424 /* FALLTHROUGH */ 8425 case K_S_LEFT: 8426 case K_S_RIGHT: 8427 case K_S_UP: 8428 case K_S_DOWN: 8429 case K_S_END: 8430 case K_S_HOME: 8431 /* Start selection right away, the cursor can move with 8432 * CTRL-O when beyond the end of the line. */ 8433 start_selection(); 8434 8435 /* Execute the key in (insert) Select mode. */ 8436 stuffcharReadbuff(Ctrl_O); 8437 if (mod_mask) 8438 { 8439 char_u buf[4]; 8440 8441 buf[0] = K_SPECIAL; 8442 buf[1] = KS_MODIFIER; 8443 buf[2] = mod_mask; 8444 buf[3] = NUL; 8445 stuffReadbuff(buf); 8446 } 8447 stuffcharReadbuff(c); 8448 return TRUE; 8449 } 8450 return FALSE; 8451 } 8452 8453 /* 8454 * <Insert> key in Insert mode: toggle insert/replace mode. 8455 */ 8456 static void 8457 ins_insert(int replaceState) 8458 { 8459 #ifdef FEAT_EVAL 8460 set_vim_var_string(VV_INSERTMODE, 8461 (char_u *)((State & REPLACE_FLAG) ? "i" 8462 : replaceState == VREPLACE ? "v" 8463 : "r"), 1); 8464 #endif 8465 ins_apply_autocmds(EVENT_INSERTCHANGE); 8466 if (State & REPLACE_FLAG) 8467 State = INSERT | (State & LANGMAP); 8468 else 8469 State = replaceState | (State & LANGMAP); 8470 AppendCharToRedobuff(K_INS); 8471 showmode(); 8472 #ifdef CURSOR_SHAPE 8473 ui_cursor_shape(); /* may show different cursor shape */ 8474 #endif 8475 } 8476 8477 /* 8478 * Pressed CTRL-O in Insert mode. 8479 */ 8480 static void 8481 ins_ctrl_o(void) 8482 { 8483 if (State & VREPLACE_FLAG) 8484 restart_edit = 'V'; 8485 else 8486 if (State & REPLACE_FLAG) 8487 restart_edit = 'R'; 8488 else 8489 restart_edit = 'I'; 8490 if (virtual_active()) 8491 ins_at_eol = FALSE; /* cursor always keeps its column */ 8492 else 8493 ins_at_eol = (gchar_cursor() == NUL); 8494 } 8495 8496 /* 8497 * If the cursor is on an indent, ^T/^D insert/delete one 8498 * shiftwidth. Otherwise ^T/^D behave like a "<<" or ">>". 8499 * Always round the indent to 'shiftwidth', this is compatible 8500 * with vi. But vi only supports ^T and ^D after an 8501 * autoindent, we support it everywhere. 8502 */ 8503 static void 8504 ins_shift(int c, int lastc) 8505 { 8506 if (stop_arrow() == FAIL) 8507 return; 8508 AppendCharToRedobuff(c); 8509 8510 /* 8511 * 0^D and ^^D: remove all indent. 8512 */ 8513 if (c == Ctrl_D && (lastc == '0' || lastc == '^') 8514 && curwin->w_cursor.col > 0) 8515 { 8516 --curwin->w_cursor.col; 8517 (void)del_char(FALSE); /* delete the '^' or '0' */ 8518 /* In Replace mode, restore the characters that '^' or '0' replaced. */ 8519 if (State & REPLACE_FLAG) 8520 replace_pop_ins(); 8521 if (lastc == '^') 8522 old_indent = get_indent(); /* remember curr. indent */ 8523 change_indent(INDENT_SET, 0, TRUE, 0, TRUE); 8524 } 8525 else 8526 change_indent(c == Ctrl_D ? INDENT_DEC : INDENT_INC, 0, TRUE, 0, TRUE); 8527 8528 if (did_ai && *skipwhite(ml_get_curline()) != NUL) 8529 did_ai = FALSE; 8530 #ifdef FEAT_SMARTINDENT 8531 did_si = FALSE; 8532 can_si = FALSE; 8533 can_si_back = FALSE; 8534 #endif 8535 #ifdef FEAT_CINDENT 8536 can_cindent = FALSE; /* no cindenting after ^D or ^T */ 8537 #endif 8538 } 8539 8540 static void 8541 ins_del(void) 8542 { 8543 int temp; 8544 8545 if (stop_arrow() == FAIL) 8546 return; 8547 if (gchar_cursor() == NUL) /* delete newline */ 8548 { 8549 temp = curwin->w_cursor.col; 8550 if (!can_bs(BS_EOL) /* only if "eol" included */ 8551 || do_join(2, FALSE, TRUE, FALSE, FALSE) == FAIL) 8552 vim_beep(BO_BS); 8553 else 8554 { 8555 curwin->w_cursor.col = temp; 8556 /* Adjust orig_line_count in case more lines have been deleted than 8557 * have been added. That makes sure, that open_line() later 8558 * can access all buffer lines correctly */ 8559 if (State & VREPLACE_FLAG && 8560 orig_line_count > curbuf->b_ml.ml_line_count) 8561 orig_line_count = curbuf->b_ml.ml_line_count; 8562 } 8563 } 8564 else if (del_char(FALSE) == FAIL) /* delete char under cursor */ 8565 vim_beep(BO_BS); 8566 did_ai = FALSE; 8567 #ifdef FEAT_SMARTINDENT 8568 did_si = FALSE; 8569 can_si = FALSE; 8570 can_si_back = FALSE; 8571 #endif 8572 AppendCharToRedobuff(K_DEL); 8573 } 8574 8575 /* 8576 * Delete one character for ins_bs(). 8577 */ 8578 static void 8579 ins_bs_one(colnr_T *vcolp) 8580 { 8581 dec_cursor(); 8582 getvcol(curwin, &curwin->w_cursor, vcolp, NULL, NULL); 8583 if (State & REPLACE_FLAG) 8584 { 8585 /* Don't delete characters before the insert point when in 8586 * Replace mode */ 8587 if (curwin->w_cursor.lnum != Insstart.lnum 8588 || curwin->w_cursor.col >= Insstart.col) 8589 replace_do_bs(-1); 8590 } 8591 else 8592 (void)del_char(FALSE); 8593 } 8594 8595 /* 8596 * Handle Backspace, delete-word and delete-line in Insert mode. 8597 * Return TRUE when backspace was actually used. 8598 */ 8599 static int 8600 ins_bs( 8601 int c, 8602 int mode, 8603 int *inserted_space_p) 8604 { 8605 linenr_T lnum; 8606 int cc; 8607 int temp = 0; /* init for GCC */ 8608 colnr_T save_col; 8609 colnr_T mincol; 8610 int did_backspace = FALSE; 8611 int in_indent; 8612 int oldState; 8613 int cpc[MAX_MCO]; /* composing characters */ 8614 8615 /* 8616 * can't delete anything in an empty file 8617 * can't backup past first character in buffer 8618 * can't backup past starting point unless 'backspace' > 1 8619 * can backup to a previous line if 'backspace' == 0 8620 */ 8621 if ( BUFEMPTY() 8622 || ( 8623 #ifdef FEAT_RIGHTLEFT 8624 !revins_on && 8625 #endif 8626 ((curwin->w_cursor.lnum == 1 && curwin->w_cursor.col == 0) 8627 || (!can_bs(BS_START) 8628 && (arrow_used 8629 || (curwin->w_cursor.lnum == Insstart_orig.lnum 8630 && curwin->w_cursor.col <= Insstart_orig.col))) 8631 || (!can_bs(BS_INDENT) && !arrow_used && ai_col > 0 8632 && curwin->w_cursor.col <= ai_col) 8633 || (!can_bs(BS_EOL) && curwin->w_cursor.col == 0)))) 8634 { 8635 vim_beep(BO_BS); 8636 return FALSE; 8637 } 8638 8639 if (stop_arrow() == FAIL) 8640 return FALSE; 8641 in_indent = inindent(0); 8642 #ifdef FEAT_CINDENT 8643 if (in_indent) 8644 can_cindent = FALSE; 8645 #endif 8646 #ifdef FEAT_COMMENTS 8647 end_comment_pending = NUL; /* After BS, don't auto-end comment */ 8648 #endif 8649 #ifdef FEAT_RIGHTLEFT 8650 if (revins_on) /* put cursor after last inserted char */ 8651 inc_cursor(); 8652 #endif 8653 8654 /* Virtualedit: 8655 * BACKSPACE_CHAR eats a virtual space 8656 * BACKSPACE_WORD eats all coladd 8657 * BACKSPACE_LINE eats all coladd and keeps going 8658 */ 8659 if (curwin->w_cursor.coladd > 0) 8660 { 8661 if (mode == BACKSPACE_CHAR) 8662 { 8663 --curwin->w_cursor.coladd; 8664 return TRUE; 8665 } 8666 if (mode == BACKSPACE_WORD) 8667 { 8668 curwin->w_cursor.coladd = 0; 8669 return TRUE; 8670 } 8671 curwin->w_cursor.coladd = 0; 8672 } 8673 8674 /* 8675 * Delete newline! 8676 */ 8677 if (curwin->w_cursor.col == 0) 8678 { 8679 lnum = Insstart.lnum; 8680 if (curwin->w_cursor.lnum == lnum 8681 #ifdef FEAT_RIGHTLEFT 8682 || revins_on 8683 #endif 8684 ) 8685 { 8686 if (u_save((linenr_T)(curwin->w_cursor.lnum - 2), 8687 (linenr_T)(curwin->w_cursor.lnum + 1)) == FAIL) 8688 return FALSE; 8689 --Insstart.lnum; 8690 Insstart.col = (colnr_T)STRLEN(ml_get(Insstart.lnum)); 8691 } 8692 /* 8693 * In replace mode: 8694 * cc < 0: NL was inserted, delete it 8695 * cc >= 0: NL was replaced, put original characters back 8696 */ 8697 cc = -1; 8698 if (State & REPLACE_FLAG) 8699 cc = replace_pop(); /* returns -1 if NL was inserted */ 8700 /* 8701 * In replace mode, in the line we started replacing, we only move the 8702 * cursor. 8703 */ 8704 if ((State & REPLACE_FLAG) && curwin->w_cursor.lnum <= lnum) 8705 { 8706 dec_cursor(); 8707 } 8708 else 8709 { 8710 if (!(State & VREPLACE_FLAG) 8711 || curwin->w_cursor.lnum > orig_line_count) 8712 { 8713 temp = gchar_cursor(); /* remember current char */ 8714 --curwin->w_cursor.lnum; 8715 8716 /* When "aw" is in 'formatoptions' we must delete the space at 8717 * the end of the line, otherwise the line will be broken 8718 * again when auto-formatting. */ 8719 if (has_format_option(FO_AUTO) 8720 && has_format_option(FO_WHITE_PAR)) 8721 { 8722 char_u *ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, 8723 TRUE); 8724 int len; 8725 8726 len = (int)STRLEN(ptr); 8727 if (len > 0 && ptr[len - 1] == ' ') 8728 ptr[len - 1] = NUL; 8729 } 8730 8731 (void)do_join(2, FALSE, FALSE, FALSE, FALSE); 8732 if (temp == NUL && gchar_cursor() != NUL) 8733 inc_cursor(); 8734 } 8735 else 8736 dec_cursor(); 8737 8738 /* 8739 * In REPLACE mode we have to put back the text that was replaced 8740 * by the NL. On the replace stack is first a NUL-terminated 8741 * sequence of characters that were deleted and then the 8742 * characters that NL replaced. 8743 */ 8744 if (State & REPLACE_FLAG) 8745 { 8746 /* 8747 * Do the next ins_char() in NORMAL state, to 8748 * prevent ins_char() from replacing characters and 8749 * avoiding showmatch(). 8750 */ 8751 oldState = State; 8752 State = NORMAL; 8753 /* 8754 * restore characters (blanks) deleted after cursor 8755 */ 8756 while (cc > 0) 8757 { 8758 save_col = curwin->w_cursor.col; 8759 mb_replace_pop_ins(cc); 8760 curwin->w_cursor.col = save_col; 8761 cc = replace_pop(); 8762 } 8763 /* restore the characters that NL replaced */ 8764 replace_pop_ins(); 8765 State = oldState; 8766 } 8767 } 8768 did_ai = FALSE; 8769 } 8770 else 8771 { 8772 /* 8773 * Delete character(s) before the cursor. 8774 */ 8775 #ifdef FEAT_RIGHTLEFT 8776 if (revins_on) /* put cursor on last inserted char */ 8777 dec_cursor(); 8778 #endif 8779 mincol = 0; 8780 /* keep indent */ 8781 if (mode == BACKSPACE_LINE 8782 && (curbuf->b_p_ai 8783 #ifdef FEAT_CINDENT 8784 || cindent_on() 8785 #endif 8786 ) 8787 #ifdef FEAT_RIGHTLEFT 8788 && !revins_on 8789 #endif 8790 ) 8791 { 8792 save_col = curwin->w_cursor.col; 8793 beginline(BL_WHITE); 8794 if (curwin->w_cursor.col < save_col) 8795 mincol = curwin->w_cursor.col; 8796 curwin->w_cursor.col = save_col; 8797 } 8798 8799 /* 8800 * Handle deleting one 'shiftwidth' or 'softtabstop'. 8801 */ 8802 if ( mode == BACKSPACE_CHAR 8803 && ((p_sta && in_indent) 8804 || ((get_sts_value() != 0 8805 #ifdef FEAT_VARTABS 8806 || tabstop_count(curbuf->b_p_vsts_array) 8807 #endif 8808 ) 8809 && curwin->w_cursor.col > 0 8810 && (*(ml_get_cursor() - 1) == TAB 8811 || (*(ml_get_cursor() - 1) == ' ' 8812 && (!*inserted_space_p 8813 || arrow_used)))))) 8814 { 8815 int ts; 8816 colnr_T vcol; 8817 colnr_T want_vcol; 8818 colnr_T start_vcol; 8819 8820 *inserted_space_p = FALSE; 8821 /* Compute the virtual column where we want to be. Since 8822 * 'showbreak' may get in the way, need to get the last column of 8823 * the previous character. */ 8824 getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL); 8825 start_vcol = vcol; 8826 dec_cursor(); 8827 getvcol(curwin, &curwin->w_cursor, NULL, NULL, &want_vcol); 8828 inc_cursor(); 8829 #ifdef FEAT_VARTABS 8830 if (p_sta && in_indent) 8831 { 8832 ts = (int)get_sw_value(curbuf); 8833 want_vcol = (want_vcol / ts) * ts; 8834 } 8835 else 8836 want_vcol = tabstop_start(want_vcol, get_sts_value(), 8837 curbuf->b_p_vsts_array); 8838 #else 8839 if (p_sta && in_indent) 8840 ts = (int)get_sw_value(curbuf); 8841 else 8842 ts = (int)get_sts_value(); 8843 want_vcol = (want_vcol / ts) * ts; 8844 #endif 8845 8846 /* delete characters until we are at or before want_vcol */ 8847 while (vcol > want_vcol 8848 && (cc = *(ml_get_cursor() - 1), VIM_ISWHITE(cc))) 8849 ins_bs_one(&vcol); 8850 8851 /* insert extra spaces until we are at want_vcol */ 8852 while (vcol < want_vcol) 8853 { 8854 /* Remember the first char we inserted */ 8855 if (curwin->w_cursor.lnum == Insstart_orig.lnum 8856 && curwin->w_cursor.col < Insstart_orig.col) 8857 Insstart_orig.col = curwin->w_cursor.col; 8858 8859 if (State & VREPLACE_FLAG) 8860 ins_char(' '); 8861 else 8862 { 8863 ins_str((char_u *)" "); 8864 if ((State & REPLACE_FLAG)) 8865 replace_push(NUL); 8866 } 8867 getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL); 8868 } 8869 8870 /* If we are now back where we started delete one character. Can 8871 * happen when using 'sts' and 'linebreak'. */ 8872 if (vcol >= start_vcol) 8873 ins_bs_one(&vcol); 8874 } 8875 8876 /* 8877 * Delete upto starting point, start of line or previous word. 8878 */ 8879 else 8880 { 8881 int cclass = 0, prev_cclass = 0; 8882 8883 if (has_mbyte) 8884 cclass = mb_get_class(ml_get_cursor()); 8885 do 8886 { 8887 #ifdef FEAT_RIGHTLEFT 8888 if (!revins_on) /* put cursor on char to be deleted */ 8889 #endif 8890 dec_cursor(); 8891 8892 cc = gchar_cursor(); 8893 /* look multi-byte character class */ 8894 if (has_mbyte) 8895 { 8896 prev_cclass = cclass; 8897 cclass = mb_get_class(ml_get_cursor()); 8898 } 8899 8900 /* start of word? */ 8901 if (mode == BACKSPACE_WORD && !vim_isspace(cc)) 8902 { 8903 mode = BACKSPACE_WORD_NOT_SPACE; 8904 temp = vim_iswordc(cc); 8905 } 8906 /* end of word? */ 8907 else if (mode == BACKSPACE_WORD_NOT_SPACE 8908 && ((vim_isspace(cc) || vim_iswordc(cc) != temp) 8909 || prev_cclass != cclass)) 8910 { 8911 #ifdef FEAT_RIGHTLEFT 8912 if (!revins_on) 8913 #endif 8914 inc_cursor(); 8915 #ifdef FEAT_RIGHTLEFT 8916 else if (State & REPLACE_FLAG) 8917 dec_cursor(); 8918 #endif 8919 break; 8920 } 8921 if (State & REPLACE_FLAG) 8922 replace_do_bs(-1); 8923 else 8924 { 8925 if (enc_utf8 && p_deco) 8926 (void)utfc_ptr2char(ml_get_cursor(), cpc); 8927 (void)del_char(FALSE); 8928 /* 8929 * If there are combining characters and 'delcombine' is set 8930 * move the cursor back. Don't back up before the base 8931 * character. 8932 */ 8933 if (enc_utf8 && p_deco && cpc[0] != NUL) 8934 inc_cursor(); 8935 #ifdef FEAT_RIGHTLEFT 8936 if (revins_chars) 8937 { 8938 revins_chars--; 8939 revins_legal++; 8940 } 8941 if (revins_on && gchar_cursor() == NUL) 8942 break; 8943 #endif 8944 } 8945 /* Just a single backspace?: */ 8946 if (mode == BACKSPACE_CHAR) 8947 break; 8948 } while ( 8949 #ifdef FEAT_RIGHTLEFT 8950 revins_on || 8951 #endif 8952 (curwin->w_cursor.col > mincol 8953 && (curwin->w_cursor.lnum != Insstart_orig.lnum 8954 || curwin->w_cursor.col != Insstart_orig.col))); 8955 } 8956 did_backspace = TRUE; 8957 } 8958 #ifdef FEAT_SMARTINDENT 8959 did_si = FALSE; 8960 can_si = FALSE; 8961 can_si_back = FALSE; 8962 #endif 8963 if (curwin->w_cursor.col <= 1) 8964 did_ai = FALSE; 8965 /* 8966 * It's a little strange to put backspaces into the redo 8967 * buffer, but it makes auto-indent a lot easier to deal 8968 * with. 8969 */ 8970 AppendCharToRedobuff(c); 8971 8972 /* If deleted before the insertion point, adjust it */ 8973 if (curwin->w_cursor.lnum == Insstart_orig.lnum 8974 && curwin->w_cursor.col < Insstart_orig.col) 8975 Insstart_orig.col = curwin->w_cursor.col; 8976 8977 /* vi behaviour: the cursor moves backward but the character that 8978 * was there remains visible 8979 * Vim behaviour: the cursor moves backward and the character that 8980 * was there is erased from the screen. 8981 * We can emulate the vi behaviour by pretending there is a dollar 8982 * displayed even when there isn't. 8983 * --pkv Sun Jan 19 01:56:40 EST 2003 */ 8984 if (vim_strchr(p_cpo, CPO_BACKSPACE) != NULL && dollar_vcol == -1) 8985 dollar_vcol = curwin->w_virtcol; 8986 8987 #ifdef FEAT_FOLDING 8988 /* When deleting a char the cursor line must never be in a closed fold. 8989 * E.g., when 'foldmethod' is indent and deleting the first non-white 8990 * char before a Tab. */ 8991 if (did_backspace) 8992 foldOpenCursor(); 8993 #endif 8994 8995 return did_backspace; 8996 } 8997 8998 #ifdef FEAT_MOUSE 8999 static void 9000 ins_mouse(int c) 9001 { 9002 pos_T tpos; 9003 win_T *old_curwin = curwin; 9004 9005 # ifdef FEAT_GUI 9006 /* When GUI is active, also move/paste when 'mouse' is empty */ 9007 if (!gui.in_use) 9008 # endif 9009 if (!mouse_has(MOUSE_INSERT)) 9010 return; 9011 9012 undisplay_dollar(); 9013 tpos = curwin->w_cursor; 9014 if (do_mouse(NULL, c, BACKWARD, 1L, 0)) 9015 { 9016 win_T *new_curwin = curwin; 9017 9018 if (curwin != old_curwin && win_valid(old_curwin)) 9019 { 9020 /* Mouse took us to another window. We need to go back to the 9021 * previous one to stop insert there properly. */ 9022 curwin = old_curwin; 9023 curbuf = curwin->w_buffer; 9024 #ifdef FEAT_JOB_CHANNEL 9025 if (bt_prompt(curbuf)) 9026 // Restart Insert mode when re-entering the prompt buffer. 9027 curbuf->b_prompt_insert = 'A'; 9028 #endif 9029 } 9030 start_arrow(curwin == old_curwin ? &tpos : NULL); 9031 if (curwin != new_curwin && win_valid(new_curwin)) 9032 { 9033 curwin = new_curwin; 9034 curbuf = curwin->w_buffer; 9035 } 9036 # ifdef FEAT_CINDENT 9037 can_cindent = TRUE; 9038 # endif 9039 } 9040 9041 /* redraw status lines (in case another window became active) */ 9042 redraw_statuslines(); 9043 } 9044 9045 static void 9046 ins_mousescroll(int dir) 9047 { 9048 pos_T tpos; 9049 win_T *old_curwin = curwin, *wp; 9050 # ifdef FEAT_INS_EXPAND 9051 int did_scroll = FALSE; 9052 # endif 9053 9054 tpos = curwin->w_cursor; 9055 9056 if (mouse_row >= 0 && mouse_col >= 0) 9057 { 9058 int row, col; 9059 9060 row = mouse_row; 9061 col = mouse_col; 9062 9063 /* find the window at the pointer coordinates */ 9064 wp = mouse_find_win(&row, &col); 9065 if (wp == NULL) 9066 return; 9067 curwin = wp; 9068 curbuf = curwin->w_buffer; 9069 } 9070 if (curwin == old_curwin) 9071 undisplay_dollar(); 9072 9073 # ifdef FEAT_INS_EXPAND 9074 /* Don't scroll the window in which completion is being done. */ 9075 if (!pum_visible() || curwin != old_curwin) 9076 # endif 9077 { 9078 if (dir == MSCR_DOWN || dir == MSCR_UP) 9079 { 9080 if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) 9081 scroll_redraw(dir, 9082 (long)(curwin->w_botline - curwin->w_topline)); 9083 else 9084 scroll_redraw(dir, 3L); 9085 } 9086 #ifdef FEAT_GUI 9087 else 9088 { 9089 int val, step = 6; 9090 9091 if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) 9092 step = curwin->w_width; 9093 val = curwin->w_leftcol + (dir == MSCR_RIGHT ? -step : step); 9094 if (val < 0) 9095 val = 0; 9096 gui_do_horiz_scroll(val, TRUE); 9097 } 9098 #endif 9099 # ifdef FEAT_INS_EXPAND 9100 did_scroll = TRUE; 9101 # endif 9102 } 9103 9104 curwin->w_redr_status = TRUE; 9105 9106 curwin = old_curwin; 9107 curbuf = curwin->w_buffer; 9108 9109 # ifdef FEAT_INS_EXPAND 9110 /* The popup menu may overlay the window, need to redraw it. 9111 * TODO: Would be more efficient to only redraw the windows that are 9112 * overlapped by the popup menu. */ 9113 if (pum_visible() && did_scroll) 9114 { 9115 redraw_all_later(NOT_VALID); 9116 ins_compl_show_pum(); 9117 } 9118 # endif 9119 9120 if (!EQUAL_POS(curwin->w_cursor, tpos)) 9121 { 9122 start_arrow(&tpos); 9123 # ifdef FEAT_CINDENT 9124 can_cindent = TRUE; 9125 # endif 9126 } 9127 } 9128 #endif 9129 9130 /* 9131 * Handle receiving P_PS: start paste mode. Inserts the following text up to 9132 * P_PE literally. 9133 * When "drop" is TRUE then consume the text and drop it. 9134 */ 9135 int 9136 bracketed_paste(paste_mode_T mode, int drop, garray_T *gap) 9137 { 9138 int c; 9139 char_u buf[NUMBUFLEN + MB_MAXBYTES]; 9140 int idx = 0; 9141 char_u *end = find_termcode((char_u *)"PE"); 9142 int ret_char = -1; 9143 int save_allow_keys = allow_keys; 9144 int save_paste = p_paste; 9145 9146 /* If the end code is too long we can't detect it, read everything. */ 9147 if (STRLEN(end) >= NUMBUFLEN) 9148 end = NULL; 9149 ++no_mapping; 9150 allow_keys = 0; 9151 if (!p_paste) 9152 // Also have the side effects of setting 'paste' to make it work much 9153 // faster. 9154 set_option_value((char_u *)"paste", TRUE, NULL, 0); 9155 9156 for (;;) 9157 { 9158 // When the end is not defined read everything there is. 9159 if (end == NULL && vpeekc() == NUL) 9160 break; 9161 do 9162 { 9163 c = vgetc(); 9164 } while (c == K_IGNORE || c == K_VER_SCROLLBAR || c == K_HOR_SCROLLBAR); 9165 if (c == NUL || got_int) 9166 // When CTRL-C was encountered the typeahead will be flushed and we 9167 // won't get the end sequence. 9168 break; 9169 9170 if (has_mbyte) 9171 idx += (*mb_char2bytes)(c, buf + idx); 9172 else 9173 buf[idx++] = c; 9174 buf[idx] = NUL; 9175 if (end != NULL && STRNCMP(buf, end, idx) == 0) 9176 { 9177 if (end[idx] == NUL) 9178 break; /* Found the end of paste code. */ 9179 continue; 9180 } 9181 if (!drop) 9182 { 9183 switch (mode) 9184 { 9185 case PASTE_CMDLINE: 9186 put_on_cmdline(buf, idx, TRUE); 9187 break; 9188 9189 case PASTE_EX: 9190 if (gap != NULL && ga_grow(gap, idx) == OK) 9191 { 9192 mch_memmove((char *)gap->ga_data + gap->ga_len, 9193 buf, (size_t)idx); 9194 gap->ga_len += idx; 9195 } 9196 break; 9197 9198 case PASTE_INSERT: 9199 if (stop_arrow() == OK) 9200 { 9201 c = buf[0]; 9202 if (idx == 1 && (c == CAR || c == K_KENTER || c == NL)) 9203 ins_eol(c); 9204 else 9205 { 9206 ins_char_bytes(buf, idx); 9207 AppendToRedobuffLit(buf, idx); 9208 } 9209 } 9210 break; 9211 9212 case PASTE_ONE_CHAR: 9213 if (ret_char == -1) 9214 { 9215 if (has_mbyte) 9216 ret_char = (*mb_ptr2char)(buf); 9217 else 9218 ret_char = buf[0]; 9219 } 9220 break; 9221 } 9222 } 9223 idx = 0; 9224 } 9225 9226 --no_mapping; 9227 allow_keys = save_allow_keys; 9228 if (!save_paste) 9229 set_option_value((char_u *)"paste", FALSE, NULL, 0); 9230 9231 return ret_char; 9232 } 9233 9234 #if defined(FEAT_GUI_TABLINE) || defined(PROTO) 9235 static void 9236 ins_tabline(int c) 9237 { 9238 /* We will be leaving the current window, unless closing another tab. */ 9239 if (c != K_TABMENU || current_tabmenu != TABLINE_MENU_CLOSE 9240 || (current_tab != 0 && current_tab != tabpage_index(curtab))) 9241 { 9242 undisplay_dollar(); 9243 start_arrow(&curwin->w_cursor); 9244 # ifdef FEAT_CINDENT 9245 can_cindent = TRUE; 9246 # endif 9247 } 9248 9249 if (c == K_TABLINE) 9250 goto_tabpage(current_tab); 9251 else 9252 { 9253 handle_tabmenu(); 9254 redraw_statuslines(); /* will redraw the tabline when needed */ 9255 } 9256 } 9257 #endif 9258 9259 #if defined(FEAT_GUI) || defined(PROTO) 9260 void 9261 ins_scroll(void) 9262 { 9263 pos_T tpos; 9264 9265 undisplay_dollar(); 9266 tpos = curwin->w_cursor; 9267 if (gui_do_scroll()) 9268 { 9269 start_arrow(&tpos); 9270 # ifdef FEAT_CINDENT 9271 can_cindent = TRUE; 9272 # endif 9273 } 9274 } 9275 9276 void 9277 ins_horscroll(void) 9278 { 9279 pos_T tpos; 9280 9281 undisplay_dollar(); 9282 tpos = curwin->w_cursor; 9283 if (gui_do_horiz_scroll(scrollbar_value, FALSE)) 9284 { 9285 start_arrow(&tpos); 9286 # ifdef FEAT_CINDENT 9287 can_cindent = TRUE; 9288 # endif 9289 } 9290 } 9291 #endif 9292 9293 static void 9294 ins_left( 9295 int end_change) /* end undoable change */ 9296 { 9297 pos_T tpos; 9298 9299 #ifdef FEAT_FOLDING 9300 if ((fdo_flags & FDO_HOR) && KeyTyped) 9301 foldOpenCursor(); 9302 #endif 9303 undisplay_dollar(); 9304 tpos = curwin->w_cursor; 9305 if (oneleft() == OK) 9306 { 9307 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) 9308 /* Only call start_arrow() when not busy with preediting, it will 9309 * break undo. K_LEFT is inserted in im_correct_cursor(). */ 9310 if (p_imst == IM_OVER_THE_SPOT || !im_is_preediting()) 9311 #endif 9312 { 9313 start_arrow_with_change(&tpos, end_change); 9314 if (!end_change) 9315 AppendCharToRedobuff(K_LEFT); 9316 } 9317 #ifdef FEAT_RIGHTLEFT 9318 /* If exit reversed string, position is fixed */ 9319 if (revins_scol != -1 && (int)curwin->w_cursor.col >= revins_scol) 9320 revins_legal++; 9321 revins_chars++; 9322 #endif 9323 } 9324 9325 /* 9326 * if 'whichwrap' set for cursor in insert mode may go to 9327 * previous line 9328 */ 9329 else if (vim_strchr(p_ww, '[') != NULL && curwin->w_cursor.lnum > 1) 9330 { 9331 /* always break undo when moving upwards/downwards, else undo may break */ 9332 start_arrow(&tpos); 9333 --(curwin->w_cursor.lnum); 9334 coladvance((colnr_T)MAXCOL); 9335 curwin->w_set_curswant = TRUE; /* so we stay at the end */ 9336 } 9337 else 9338 vim_beep(BO_CRSR); 9339 dont_sync_undo = FALSE; 9340 } 9341 9342 static void 9343 ins_home(int c) 9344 { 9345 pos_T tpos; 9346 9347 #ifdef FEAT_FOLDING 9348 if ((fdo_flags & FDO_HOR) && KeyTyped) 9349 foldOpenCursor(); 9350 #endif 9351 undisplay_dollar(); 9352 tpos = curwin->w_cursor; 9353 if (c == K_C_HOME) 9354 curwin->w_cursor.lnum = 1; 9355 curwin->w_cursor.col = 0; 9356 curwin->w_cursor.coladd = 0; 9357 curwin->w_curswant = 0; 9358 start_arrow(&tpos); 9359 } 9360 9361 static void 9362 ins_end(int c) 9363 { 9364 pos_T tpos; 9365 9366 #ifdef FEAT_FOLDING 9367 if ((fdo_flags & FDO_HOR) && KeyTyped) 9368 foldOpenCursor(); 9369 #endif 9370 undisplay_dollar(); 9371 tpos = curwin->w_cursor; 9372 if (c == K_C_END) 9373 curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; 9374 coladvance((colnr_T)MAXCOL); 9375 curwin->w_curswant = MAXCOL; 9376 9377 start_arrow(&tpos); 9378 } 9379 9380 static void 9381 ins_s_left(void) 9382 { 9383 #ifdef FEAT_FOLDING 9384 if ((fdo_flags & FDO_HOR) && KeyTyped) 9385 foldOpenCursor(); 9386 #endif 9387 undisplay_dollar(); 9388 if (curwin->w_cursor.lnum > 1 || curwin->w_cursor.col > 0) 9389 { 9390 start_arrow(&curwin->w_cursor); 9391 (void)bck_word(1L, FALSE, FALSE); 9392 curwin->w_set_curswant = TRUE; 9393 } 9394 else 9395 vim_beep(BO_CRSR); 9396 } 9397 9398 static void 9399 ins_right( 9400 int end_change) /* end undoable change */ 9401 { 9402 #ifdef FEAT_FOLDING 9403 if ((fdo_flags & FDO_HOR) && KeyTyped) 9404 foldOpenCursor(); 9405 #endif 9406 undisplay_dollar(); 9407 if (gchar_cursor() != NUL || virtual_active()) 9408 { 9409 start_arrow_with_change(&curwin->w_cursor, end_change); 9410 if (!end_change) 9411 AppendCharToRedobuff(K_RIGHT); 9412 curwin->w_set_curswant = TRUE; 9413 if (virtual_active()) 9414 oneright(); 9415 else 9416 { 9417 if (has_mbyte) 9418 curwin->w_cursor.col += (*mb_ptr2len)(ml_get_cursor()); 9419 else 9420 ++curwin->w_cursor.col; 9421 } 9422 9423 #ifdef FEAT_RIGHTLEFT 9424 revins_legal++; 9425 if (revins_chars) 9426 revins_chars--; 9427 #endif 9428 } 9429 /* if 'whichwrap' set for cursor in insert mode, may move the 9430 * cursor to the next line */ 9431 else if (vim_strchr(p_ww, ']') != NULL 9432 && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) 9433 { 9434 start_arrow(&curwin->w_cursor); 9435 curwin->w_set_curswant = TRUE; 9436 ++curwin->w_cursor.lnum; 9437 curwin->w_cursor.col = 0; 9438 } 9439 else 9440 vim_beep(BO_CRSR); 9441 dont_sync_undo = FALSE; 9442 } 9443 9444 static void 9445 ins_s_right(void) 9446 { 9447 #ifdef FEAT_FOLDING 9448 if ((fdo_flags & FDO_HOR) && KeyTyped) 9449 foldOpenCursor(); 9450 #endif 9451 undisplay_dollar(); 9452 if (curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count 9453 || gchar_cursor() != NUL) 9454 { 9455 start_arrow(&curwin->w_cursor); 9456 (void)fwd_word(1L, FALSE, 0); 9457 curwin->w_set_curswant = TRUE; 9458 } 9459 else 9460 vim_beep(BO_CRSR); 9461 } 9462 9463 static void 9464 ins_up( 9465 int startcol) /* when TRUE move to Insstart.col */ 9466 { 9467 pos_T tpos; 9468 linenr_T old_topline = curwin->w_topline; 9469 #ifdef FEAT_DIFF 9470 int old_topfill = curwin->w_topfill; 9471 #endif 9472 9473 undisplay_dollar(); 9474 tpos = curwin->w_cursor; 9475 if (cursor_up(1L, TRUE) == OK) 9476 { 9477 if (startcol) 9478 coladvance(getvcol_nolist(&Insstart)); 9479 if (old_topline != curwin->w_topline 9480 #ifdef FEAT_DIFF 9481 || old_topfill != curwin->w_topfill 9482 #endif 9483 ) 9484 redraw_later(VALID); 9485 start_arrow(&tpos); 9486 #ifdef FEAT_CINDENT 9487 can_cindent = TRUE; 9488 #endif 9489 } 9490 else 9491 vim_beep(BO_CRSR); 9492 } 9493 9494 static void 9495 ins_pageup(void) 9496 { 9497 pos_T tpos; 9498 9499 undisplay_dollar(); 9500 9501 if (mod_mask & MOD_MASK_CTRL) 9502 { 9503 /* <C-PageUp>: tab page back */ 9504 if (first_tabpage->tp_next != NULL) 9505 { 9506 start_arrow(&curwin->w_cursor); 9507 goto_tabpage(-1); 9508 } 9509 return; 9510 } 9511 9512 tpos = curwin->w_cursor; 9513 if (onepage(BACKWARD, 1L) == OK) 9514 { 9515 start_arrow(&tpos); 9516 #ifdef FEAT_CINDENT 9517 can_cindent = TRUE; 9518 #endif 9519 } 9520 else 9521 vim_beep(BO_CRSR); 9522 } 9523 9524 static void 9525 ins_down( 9526 int startcol) /* when TRUE move to Insstart.col */ 9527 { 9528 pos_T tpos; 9529 linenr_T old_topline = curwin->w_topline; 9530 #ifdef FEAT_DIFF 9531 int old_topfill = curwin->w_topfill; 9532 #endif 9533 9534 undisplay_dollar(); 9535 tpos = curwin->w_cursor; 9536 if (cursor_down(1L, TRUE) == OK) 9537 { 9538 if (startcol) 9539 coladvance(getvcol_nolist(&Insstart)); 9540 if (old_topline != curwin->w_topline 9541 #ifdef FEAT_DIFF 9542 || old_topfill != curwin->w_topfill 9543 #endif 9544 ) 9545 redraw_later(VALID); 9546 start_arrow(&tpos); 9547 #ifdef FEAT_CINDENT 9548 can_cindent = TRUE; 9549 #endif 9550 } 9551 else 9552 vim_beep(BO_CRSR); 9553 } 9554 9555 static void 9556 ins_pagedown(void) 9557 { 9558 pos_T tpos; 9559 9560 undisplay_dollar(); 9561 9562 if (mod_mask & MOD_MASK_CTRL) 9563 { 9564 /* <C-PageDown>: tab page forward */ 9565 if (first_tabpage->tp_next != NULL) 9566 { 9567 start_arrow(&curwin->w_cursor); 9568 goto_tabpage(0); 9569 } 9570 return; 9571 } 9572 9573 tpos = curwin->w_cursor; 9574 if (onepage(FORWARD, 1L) == OK) 9575 { 9576 start_arrow(&tpos); 9577 #ifdef FEAT_CINDENT 9578 can_cindent = TRUE; 9579 #endif 9580 } 9581 else 9582 vim_beep(BO_CRSR); 9583 } 9584 9585 #ifdef FEAT_DND 9586 static void 9587 ins_drop(void) 9588 { 9589 do_put('~', BACKWARD, 1L, PUT_CURSEND); 9590 } 9591 #endif 9592 9593 /* 9594 * Handle TAB in Insert or Replace mode. 9595 * Return TRUE when the TAB needs to be inserted like a normal character. 9596 */ 9597 static int 9598 ins_tab(void) 9599 { 9600 int ind; 9601 int i; 9602 int temp; 9603 9604 if (Insstart_blank_vcol == MAXCOL && curwin->w_cursor.lnum == Insstart.lnum) 9605 Insstart_blank_vcol = get_nolist_virtcol(); 9606 if (echeck_abbr(TAB + ABBR_OFF)) 9607 return FALSE; 9608 9609 ind = inindent(0); 9610 #ifdef FEAT_CINDENT 9611 if (ind) 9612 can_cindent = FALSE; 9613 #endif 9614 9615 /* 9616 * When nothing special, insert TAB like a normal character. 9617 */ 9618 if (!curbuf->b_p_et 9619 #ifdef FEAT_VARTABS 9620 && !(p_sta && ind 9621 /* These five lines mean 'tabstop' != 'shiftwidth' */ 9622 && ((tabstop_count(curbuf->b_p_vts_array) > 1) 9623 || (tabstop_count(curbuf->b_p_vts_array) == 1 9624 && tabstop_first(curbuf->b_p_vts_array) 9625 != get_sw_value(curbuf)) 9626 || (tabstop_count(curbuf->b_p_vts_array) == 0 9627 && curbuf->b_p_ts != get_sw_value(curbuf)))) 9628 && tabstop_count(curbuf->b_p_vsts_array) == 0 9629 #else 9630 && !(p_sta && ind && curbuf->b_p_ts != get_sw_value(curbuf)) 9631 #endif 9632 && get_sts_value() == 0) 9633 return TRUE; 9634 9635 if (stop_arrow() == FAIL) 9636 return TRUE; 9637 9638 did_ai = FALSE; 9639 #ifdef FEAT_SMARTINDENT 9640 did_si = FALSE; 9641 can_si = FALSE; 9642 can_si_back = FALSE; 9643 #endif 9644 AppendToRedobuff((char_u *)"\t"); 9645 9646 #ifdef FEAT_VARTABS 9647 if (p_sta && ind) /* insert tab in indent, use 'shiftwidth' */ 9648 { 9649 temp = (int)get_sw_value(curbuf); 9650 temp -= get_nolist_virtcol() % temp; 9651 } 9652 else if (tabstop_count(curbuf->b_p_vsts_array) > 0 || curbuf->b_p_sts != 0) 9653 /* use 'softtabstop' when set */ 9654 temp = tabstop_padding(get_nolist_virtcol(), get_sts_value(), 9655 curbuf->b_p_vsts_array); 9656 else /* otherwise use 'tabstop' */ 9657 temp = tabstop_padding(get_nolist_virtcol(), curbuf->b_p_ts, 9658 curbuf->b_p_vts_array); 9659 #else 9660 if (p_sta && ind) /* insert tab in indent, use 'shiftwidth' */ 9661 temp = (int)get_sw_value(curbuf); 9662 else if (curbuf->b_p_sts != 0) /* use 'softtabstop' when set */ 9663 temp = (int)get_sts_value(); 9664 else /* otherwise use 'tabstop' */ 9665 temp = (int)curbuf->b_p_ts; 9666 temp -= get_nolist_virtcol() % temp; 9667 #endif 9668 9669 /* 9670 * Insert the first space with ins_char(). It will delete one char in 9671 * replace mode. Insert the rest with ins_str(); it will not delete any 9672 * chars. For VREPLACE mode, we use ins_char() for all characters. 9673 */ 9674 ins_char(' '); 9675 while (--temp > 0) 9676 { 9677 if (State & VREPLACE_FLAG) 9678 ins_char(' '); 9679 else 9680 { 9681 ins_str((char_u *)" "); 9682 if (State & REPLACE_FLAG) /* no char replaced */ 9683 replace_push(NUL); 9684 } 9685 } 9686 9687 /* 9688 * When 'expandtab' not set: Replace spaces by TABs where possible. 9689 */ 9690 #ifdef FEAT_VARTABS 9691 if (!curbuf->b_p_et && (tabstop_count(curbuf->b_p_vsts_array) > 0 9692 || get_sts_value() > 0 9693 || (p_sta && ind))) 9694 #else 9695 if (!curbuf->b_p_et && (get_sts_value() || (p_sta && ind))) 9696 #endif 9697 { 9698 char_u *ptr; 9699 char_u *saved_line = NULL; /* init for GCC */ 9700 pos_T pos; 9701 pos_T fpos; 9702 pos_T *cursor; 9703 colnr_T want_vcol, vcol; 9704 int change_col = -1; 9705 int save_list = curwin->w_p_list; 9706 9707 /* 9708 * Get the current line. For VREPLACE mode, don't make real changes 9709 * yet, just work on a copy of the line. 9710 */ 9711 if (State & VREPLACE_FLAG) 9712 { 9713 pos = curwin->w_cursor; 9714 cursor = &pos; 9715 saved_line = vim_strsave(ml_get_curline()); 9716 if (saved_line == NULL) 9717 return FALSE; 9718 ptr = saved_line + pos.col; 9719 } 9720 else 9721 { 9722 ptr = ml_get_cursor(); 9723 cursor = &curwin->w_cursor; 9724 } 9725 9726 /* When 'L' is not in 'cpoptions' a tab always takes up 'ts' spaces. */ 9727 if (vim_strchr(p_cpo, CPO_LISTWM) == NULL) 9728 curwin->w_p_list = FALSE; 9729 9730 /* Find first white before the cursor */ 9731 fpos = curwin->w_cursor; 9732 while (fpos.col > 0 && VIM_ISWHITE(ptr[-1])) 9733 { 9734 --fpos.col; 9735 --ptr; 9736 } 9737 9738 /* In Replace mode, don't change characters before the insert point. */ 9739 if ((State & REPLACE_FLAG) 9740 && fpos.lnum == Insstart.lnum 9741 && fpos.col < Insstart.col) 9742 { 9743 ptr += Insstart.col - fpos.col; 9744 fpos.col = Insstart.col; 9745 } 9746 9747 /* compute virtual column numbers of first white and cursor */ 9748 getvcol(curwin, &fpos, &vcol, NULL, NULL); 9749 getvcol(curwin, cursor, &want_vcol, NULL, NULL); 9750 9751 /* Use as many TABs as possible. Beware of 'breakindent', 'showbreak' 9752 * and 'linebreak' adding extra virtual columns. */ 9753 while (VIM_ISWHITE(*ptr)) 9754 { 9755 i = lbr_chartabsize(NULL, (char_u *)"\t", vcol); 9756 if (vcol + i > want_vcol) 9757 break; 9758 if (*ptr != TAB) 9759 { 9760 *ptr = TAB; 9761 if (change_col < 0) 9762 { 9763 change_col = fpos.col; /* Column of first change */ 9764 /* May have to adjust Insstart */ 9765 if (fpos.lnum == Insstart.lnum && fpos.col < Insstart.col) 9766 Insstart.col = fpos.col; 9767 } 9768 } 9769 ++fpos.col; 9770 ++ptr; 9771 vcol += i; 9772 } 9773 9774 if (change_col >= 0) 9775 { 9776 int repl_off = 0; 9777 char_u *line = ptr; 9778 9779 /* Skip over the spaces we need. */ 9780 while (vcol < want_vcol && *ptr == ' ') 9781 { 9782 vcol += lbr_chartabsize(line, ptr, vcol); 9783 ++ptr; 9784 ++repl_off; 9785 } 9786 if (vcol > want_vcol) 9787 { 9788 /* Must have a char with 'showbreak' just before it. */ 9789 --ptr; 9790 --repl_off; 9791 } 9792 fpos.col += repl_off; 9793 9794 /* Delete following spaces. */ 9795 i = cursor->col - fpos.col; 9796 if (i > 0) 9797 { 9798 STRMOVE(ptr, ptr + i); 9799 /* correct replace stack. */ 9800 if ((State & REPLACE_FLAG) && !(State & VREPLACE_FLAG)) 9801 for (temp = i; --temp >= 0; ) 9802 replace_join(repl_off); 9803 #ifdef FEAT_TEXT_PROP 9804 curbuf->b_ml.ml_line_len -= i; 9805 #endif 9806 } 9807 #ifdef FEAT_NETBEANS_INTG 9808 if (netbeans_active()) 9809 { 9810 netbeans_removed(curbuf, fpos.lnum, cursor->col, (long)(i + 1)); 9811 netbeans_inserted(curbuf, fpos.lnum, cursor->col, 9812 (char_u *)"\t", 1); 9813 } 9814 #endif 9815 cursor->col -= i; 9816 9817 /* 9818 * In VREPLACE mode, we haven't changed anything yet. Do it now by 9819 * backspacing over the changed spacing and then inserting the new 9820 * spacing. 9821 */ 9822 if (State & VREPLACE_FLAG) 9823 { 9824 /* Backspace from real cursor to change_col */ 9825 backspace_until_column(change_col); 9826 9827 /* Insert each char in saved_line from changed_col to 9828 * ptr-cursor */ 9829 ins_bytes_len(saved_line + change_col, 9830 cursor->col - change_col); 9831 } 9832 } 9833 9834 if (State & VREPLACE_FLAG) 9835 vim_free(saved_line); 9836 curwin->w_p_list = save_list; 9837 } 9838 9839 return FALSE; 9840 } 9841 9842 /* 9843 * Handle CR or NL in insert mode. 9844 * Return FAIL when out of memory or can't undo. 9845 */ 9846 static int 9847 ins_eol(int c) 9848 { 9849 int i; 9850 9851 if (echeck_abbr(c + ABBR_OFF)) 9852 return OK; 9853 if (stop_arrow() == FAIL) 9854 return FAIL; 9855 undisplay_dollar(); 9856 9857 /* 9858 * Strange Vi behaviour: In Replace mode, typing a NL will not delete the 9859 * character under the cursor. Only push a NUL on the replace stack, 9860 * nothing to put back when the NL is deleted. 9861 */ 9862 if ((State & REPLACE_FLAG) && !(State & VREPLACE_FLAG)) 9863 replace_push(NUL); 9864 9865 /* 9866 * In VREPLACE mode, a NL replaces the rest of the line, and starts 9867 * replacing the next line, so we push all of the characters left on the 9868 * line onto the replace stack. This is not done here though, it is done 9869 * in open_line(). 9870 */ 9871 9872 /* Put cursor on NUL if on the last char and coladd is 1 (happens after 9873 * CTRL-O). */ 9874 if (virtual_active() && curwin->w_cursor.coladd > 0) 9875 coladvance(getviscol()); 9876 9877 #ifdef FEAT_RIGHTLEFT 9878 /* NL in reverse insert will always start in the end of 9879 * current line. */ 9880 if (revins_on) 9881 curwin->w_cursor.col += (colnr_T)STRLEN(ml_get_cursor()); 9882 #endif 9883 9884 AppendToRedobuff(NL_STR); 9885 i = open_line(FORWARD, 9886 #ifdef FEAT_COMMENTS 9887 has_format_option(FO_RET_COMS) ? OPENLINE_DO_COM : 9888 #endif 9889 0, old_indent); 9890 old_indent = 0; 9891 #ifdef FEAT_CINDENT 9892 can_cindent = TRUE; 9893 #endif 9894 #ifdef FEAT_FOLDING 9895 /* When inserting a line the cursor line must never be in a closed fold. */ 9896 foldOpenCursor(); 9897 #endif 9898 9899 return i; 9900 } 9901 9902 #ifdef FEAT_DIGRAPHS 9903 /* 9904 * Handle digraph in insert mode. 9905 * Returns character still to be inserted, or NUL when nothing remaining to be 9906 * done. 9907 */ 9908 static int 9909 ins_digraph(void) 9910 { 9911 int c; 9912 int cc; 9913 int did_putchar = FALSE; 9914 9915 pc_status = PC_STATUS_UNSET; 9916 if (redrawing() && !char_avail()) 9917 { 9918 /* may need to redraw when no more chars available now */ 9919 ins_redraw(FALSE); 9920 9921 edit_putchar('?', TRUE); 9922 did_putchar = TRUE; 9923 #ifdef FEAT_CMDL_INFO 9924 add_to_showcmd_c(Ctrl_K); 9925 #endif 9926 } 9927 9928 #ifdef USE_ON_FLY_SCROLL 9929 dont_scroll = TRUE; /* disallow scrolling here */ 9930 #endif 9931 9932 /* don't map the digraph chars. This also prevents the 9933 * mode message to be deleted when ESC is hit */ 9934 ++no_mapping; 9935 ++allow_keys; 9936 c = plain_vgetc(); 9937 --no_mapping; 9938 --allow_keys; 9939 if (did_putchar) 9940 /* when the line fits in 'columns' the '?' is at the start of the next 9941 * line and will not be removed by the redraw */ 9942 edit_unputchar(); 9943 9944 if (IS_SPECIAL(c) || mod_mask) /* special key */ 9945 { 9946 #ifdef FEAT_CMDL_INFO 9947 clear_showcmd(); 9948 #endif 9949 insert_special(c, TRUE, FALSE); 9950 return NUL; 9951 } 9952 if (c != ESC) 9953 { 9954 did_putchar = FALSE; 9955 if (redrawing() && !char_avail()) 9956 { 9957 /* may need to redraw when no more chars available now */ 9958 ins_redraw(FALSE); 9959 9960 if (char2cells(c) == 1) 9961 { 9962 ins_redraw(FALSE); 9963 edit_putchar(c, TRUE); 9964 did_putchar = TRUE; 9965 } 9966 #ifdef FEAT_CMDL_INFO 9967 add_to_showcmd_c(c); 9968 #endif 9969 } 9970 ++no_mapping; 9971 ++allow_keys; 9972 cc = plain_vgetc(); 9973 --no_mapping; 9974 --allow_keys; 9975 if (did_putchar) 9976 /* when the line fits in 'columns' the '?' is at the start of the 9977 * next line and will not be removed by a redraw */ 9978 edit_unputchar(); 9979 if (cc != ESC) 9980 { 9981 AppendToRedobuff((char_u *)CTRL_V_STR); 9982 c = getdigraph(c, cc, TRUE); 9983 #ifdef FEAT_CMDL_INFO 9984 clear_showcmd(); 9985 #endif 9986 return c; 9987 } 9988 } 9989 #ifdef FEAT_CMDL_INFO 9990 clear_showcmd(); 9991 #endif 9992 return NUL; 9993 } 9994 #endif 9995 9996 /* 9997 * Handle CTRL-E and CTRL-Y in Insert mode: copy char from other line. 9998 * Returns the char to be inserted, or NUL if none found. 9999 */ 10000 int 10001 ins_copychar(linenr_T lnum) 10002 { 10003 int c; 10004 int temp; 10005 char_u *ptr, *prev_ptr; 10006 char_u *line; 10007 10008 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 10009 { 10010 vim_beep(BO_COPY); 10011 return NUL; 10012 } 10013 10014 /* try to advance to the cursor column */ 10015 temp = 0; 10016 line = ptr = ml_get(lnum); 10017 prev_ptr = ptr; 10018 validate_virtcol(); 10019 while ((colnr_T)temp < curwin->w_virtcol && *ptr != NUL) 10020 { 10021 prev_ptr = ptr; 10022 temp += lbr_chartabsize_adv(line, &ptr, (colnr_T)temp); 10023 } 10024 if ((colnr_T)temp > curwin->w_virtcol) 10025 ptr = prev_ptr; 10026 10027 c = (*mb_ptr2char)(ptr); 10028 if (c == NUL) 10029 vim_beep(BO_COPY); 10030 return c; 10031 } 10032 10033 /* 10034 * CTRL-Y or CTRL-E typed in Insert mode. 10035 */ 10036 static int 10037 ins_ctrl_ey(int tc) 10038 { 10039 int c = tc; 10040 10041 #ifdef FEAT_INS_EXPAND 10042 if (ctrl_x_mode == CTRL_X_SCROLL) 10043 { 10044 if (c == Ctrl_Y) 10045 scrolldown_clamp(); 10046 else 10047 scrollup_clamp(); 10048 redraw_later(VALID); 10049 } 10050 else 10051 #endif 10052 { 10053 c = ins_copychar(curwin->w_cursor.lnum + (c == Ctrl_Y ? -1 : 1)); 10054 if (c != NUL) 10055 { 10056 long tw_save; 10057 10058 /* The character must be taken literally, insert like it 10059 * was typed after a CTRL-V, and pretend 'textwidth' 10060 * wasn't set. Digits, 'o' and 'x' are special after a 10061 * CTRL-V, don't use it for these. */ 10062 if (c < 256 && !isalnum(c)) 10063 AppendToRedobuff((char_u *)CTRL_V_STR); /* CTRL-V */ 10064 tw_save = curbuf->b_p_tw; 10065 curbuf->b_p_tw = -1; 10066 insert_special(c, TRUE, FALSE); 10067 curbuf->b_p_tw = tw_save; 10068 #ifdef FEAT_RIGHTLEFT 10069 revins_chars++; 10070 revins_legal++; 10071 #endif 10072 c = Ctrl_V; /* pretend CTRL-V is last character */ 10073 auto_format(FALSE, TRUE); 10074 } 10075 } 10076 return c; 10077 } 10078 10079 #ifdef FEAT_SMARTINDENT 10080 /* 10081 * Try to do some very smart auto-indenting. 10082 * Used when inserting a "normal" character. 10083 */ 10084 static void 10085 ins_try_si(int c) 10086 { 10087 pos_T *pos, old_pos; 10088 char_u *ptr; 10089 int i; 10090 int temp; 10091 10092 /* 10093 * do some very smart indenting when entering '{' or '}' 10094 */ 10095 if (((did_si || can_si_back) && c == '{') || (can_si && c == '}')) 10096 { 10097 /* 10098 * for '}' set indent equal to indent of line containing matching '{' 10099 */ 10100 if (c == '}' && (pos = findmatch(NULL, '{')) != NULL) 10101 { 10102 old_pos = curwin->w_cursor; 10103 /* 10104 * If the matching '{' has a ')' immediately before it (ignoring 10105 * white-space), then line up with the start of the line 10106 * containing the matching '(' if there is one. This handles the 10107 * case where an "if (..\n..) {" statement continues over multiple 10108 * lines -- webb 10109 */ 10110 ptr = ml_get(pos->lnum); 10111 i = pos->col; 10112 if (i > 0) /* skip blanks before '{' */ 10113 while (--i > 0 && VIM_ISWHITE(ptr[i])) 10114 ; 10115 curwin->w_cursor.lnum = pos->lnum; 10116 curwin->w_cursor.col = i; 10117 if (ptr[i] == ')' && (pos = findmatch(NULL, '(')) != NULL) 10118 curwin->w_cursor = *pos; 10119 i = get_indent(); 10120 curwin->w_cursor = old_pos; 10121 if (State & VREPLACE_FLAG) 10122 change_indent(INDENT_SET, i, FALSE, NUL, TRUE); 10123 else 10124 (void)set_indent(i, SIN_CHANGED); 10125 } 10126 else if (curwin->w_cursor.col > 0) 10127 { 10128 /* 10129 * when inserting '{' after "O" reduce indent, but not 10130 * more than indent of previous line 10131 */ 10132 temp = TRUE; 10133 if (c == '{' && can_si_back && curwin->w_cursor.lnum > 1) 10134 { 10135 old_pos = curwin->w_cursor; 10136 i = get_indent(); 10137 while (curwin->w_cursor.lnum > 1) 10138 { 10139 ptr = skipwhite(ml_get(--(curwin->w_cursor.lnum))); 10140 10141 /* ignore empty lines and lines starting with '#'. */ 10142 if (*ptr != '#' && *ptr != NUL) 10143 break; 10144 } 10145 if (get_indent() >= i) 10146 temp = FALSE; 10147 curwin->w_cursor = old_pos; 10148 } 10149 if (temp) 10150 shift_line(TRUE, FALSE, 1, TRUE); 10151 } 10152 } 10153 10154 /* 10155 * set indent of '#' always to 0 10156 */ 10157 if (curwin->w_cursor.col > 0 && can_si && c == '#') 10158 { 10159 /* remember current indent for next line */ 10160 old_indent = get_indent(); 10161 (void)set_indent(0, SIN_CHANGED); 10162 } 10163 10164 /* Adjust ai_col, the char at this position can be deleted. */ 10165 if (ai_col > curwin->w_cursor.col) 10166 ai_col = curwin->w_cursor.col; 10167 } 10168 #endif 10169 10170 /* 10171 * Get the value that w_virtcol would have when 'list' is off. 10172 * Unless 'cpo' contains the 'L' flag. 10173 */ 10174 colnr_T 10175 get_nolist_virtcol(void) 10176 { 10177 // check validity of cursor in current buffer 10178 if (curwin->w_buffer == NULL 10179 || curwin->w_buffer->b_ml.ml_mfp == NULL 10180 || curwin->w_cursor.lnum > curwin->w_buffer->b_ml.ml_line_count) 10181 return 0; 10182 if (curwin->w_p_list && vim_strchr(p_cpo, CPO_LISTWM) == NULL) 10183 return getvcol_nolist(&curwin->w_cursor); 10184 validate_virtcol(); 10185 return curwin->w_virtcol; 10186 } 10187 10188 #if defined(FEAT_EVAL) 10189 /* 10190 * Handle the InsertCharPre autocommand. 10191 * "c" is the character that was typed. 10192 * Return a pointer to allocated memory with the replacement string. 10193 * Return NULL to continue inserting "c". 10194 */ 10195 static char_u * 10196 do_insert_char_pre(int c) 10197 { 10198 char_u *res; 10199 char_u buf[MB_MAXBYTES + 1]; 10200 int save_State = State; 10201 10202 /* Return quickly when there is nothing to do. */ 10203 if (!has_insertcharpre()) 10204 return NULL; 10205 10206 if (has_mbyte) 10207 buf[(*mb_char2bytes)(c, buf)] = NUL; 10208 else 10209 { 10210 buf[0] = c; 10211 buf[1] = NUL; 10212 } 10213 10214 /* Lock the text to avoid weird things from happening. */ 10215 ++textlock; 10216 set_vim_var_string(VV_CHAR, buf, -1); /* set v:char */ 10217 10218 res = NULL; 10219 if (ins_apply_autocmds(EVENT_INSERTCHARPRE)) 10220 { 10221 /* Get the value of v:char. It may be empty or more than one 10222 * character. Only use it when changed, otherwise continue with the 10223 * original character to avoid breaking autoindent. */ 10224 if (STRCMP(buf, get_vim_var_str(VV_CHAR)) != 0) 10225 res = vim_strsave(get_vim_var_str(VV_CHAR)); 10226 } 10227 10228 set_vim_var_string(VV_CHAR, NULL, -1); /* clear v:char */ 10229 --textlock; 10230 10231 // Restore the State, it may have been changed. 10232 State = save_State; 10233 10234 return res; 10235 } 10236 #endif 10237 10238 /* 10239 * Trigger "event" and take care of fixing undo. 10240 */ 10241 static int 10242 ins_apply_autocmds(event_T event) 10243 { 10244 varnumber_T tick = CHANGEDTICK(curbuf); 10245 int r; 10246 10247 r = apply_autocmds(event, NULL, NULL, FALSE, curbuf); 10248 10249 // If u_savesub() was called then we are not prepared to start 10250 // a new line. Call u_save() with no contents to fix that. 10251 if (tick != CHANGEDTICK(curbuf)) 10252 u_save(curwin->w_cursor.lnum, (linenr_T)(curwin->w_cursor.lnum + 1)); 10253 10254 return r; 10255 } 10256