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