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