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