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