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