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