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