edit.c
上传用户:gddssl
上传日期:2007-01-06
资源大小:1003k
文件大小:128k
源码类别:

编辑器/阅读器

开发平台:

DOS

  1. /* vi:set ts=8 sts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  */
  8. /*
  9.  * edit.c: functions for Insert mode
  10.  */
  11. #include "vim.h"
  12. #ifdef INSERT_EXPAND
  13. /*
  14.  * definitions used for CTRL-X submode
  15.  */
  16. #define CTRL_X_WANT_IDENT 0x100
  17. #define CTRL_X_NOT_DEFINED_YET (1)
  18. #define CTRL_X_SCROLL (2)
  19. #define CTRL_X_WHOLE_LINE (3)
  20. #define CTRL_X_FILES (4)
  21. #define CTRL_X_TAGS (5 + CTRL_X_WANT_IDENT)
  22. #define CTRL_X_PATH_PATTERNS (6 + CTRL_X_WANT_IDENT)
  23. #define CTRL_X_PATH_DEFINES (7 + CTRL_X_WANT_IDENT)
  24. #define CTRL_X_FINISHED (8)
  25. #define CTRL_X_DICTIONARY (9 + CTRL_X_WANT_IDENT)
  26. #define C_X_SKIP (7) /* length of " Adding" */
  27. char *ctrl_x_msgs[] =
  28. {
  29.     " Adding Keyword completion (^N/^P)", /* ctrl_x_mode == 0, ^P/^N compl. */
  30.     " ^X mode (^E/^Y/^L/^]/^F/^I/^K/^D/^N/^P)",
  31.     /* Scroll has it's own msgs, in it's place there is the msg for local
  32.      * ctrl_x_mode = 0 (eg continue_status & CONT_LOCAL)  -- Acevedo */
  33.     " Adding Keyword Local completion (^N/^P)",
  34.     " Adding Whole line completion (^L/^N/^P)",
  35.     " Adding File name completion (^F/^N/^P)",
  36.     " Adding Tag completion (^]/^N/^P)",
  37.     " Adding Path pattern completion (^N/^P)",
  38.     " Adding Definition completion (^D/^N/^P)",
  39.     NULL,
  40.     " Adding Dictionary completion (^K/^N/^P)"
  41. };
  42. char_u e_hitend[] = "Hit end of paragraph";
  43. char_u e_hitend_f[] = "Hit end of paragraph (forward)";
  44. char_u e_hitend_b[] = "Hit end of paragraph (backward)";
  45. char_u e_patnotf_f[] = "Pattern not found (forward)";
  46. char_u e_patnotf_b[] = "Pattern not found (backward)";
  47. /*
  48.  * Structure used to store one match for insert completion.
  49.  */
  50. struct Completion
  51. {
  52.     struct Completion *next;
  53.     struct Completion *prev;
  54.     char_u *str;   /* matched text */
  55.     char_u *fname;   /* file containing the match */
  56.     int original; /* ORIGINAL_TEXT, CONT_S_IPOS or FREE_FNAME */
  57. };
  58. /* the original text when the expansion begun */
  59. #define ORIGINAL_TEXT (1)
  60. #define FREE_FNAME (2)
  61. /*
  62.  * All the current matches are stored in a list.
  63.  * "first_match" points to the start of the list.
  64.  * "curr_match" points to the currently selected entry.
  65.  */
  66. static struct Completion    *first_match = NULL;
  67. static struct Completion    *curr_match = NULL;
  68. static int     started_completion;
  69. static char_u     *complete_pat;
  70. static int     save_sm;
  71. static char_u     *original_text = NULL;  /* text before completion */
  72. static int     continue_mode = 0;
  73. static int  add_completion __ARGS((char_u *str, int len, char_u *, int dir, int reuse));
  74. static int  make_cyclic __ARGS((void));
  75. static void complete_dictionaries __ARGS((char_u *dict, char_u *pat, int dir, int flags));
  76. static void free_completions __ARGS((void));
  77. static void clear_insexp __ARGS((void));
  78. static int  ins_expand_pre __ARGS((int c));
  79. static BUF  *next_buf __ARGS((BUF *buf, int flag));
  80. static int  get_expansion __ARGS((FPOS *ini, int dir));
  81. static int  ins_complete __ARGS((int c));
  82. static int  quote_meta __ARGS((char_u *dest, char_u *str, int len));
  83. #endif /* INSERT_EXPAND */
  84. #define BACKSPACE_CHAR     1
  85. #define BACKSPACE_WORD     2
  86. #define BACKSPACE_WORD_NOT_SPACE    3
  87. #define BACKSPACE_LINE     4
  88. static void edit_putchar __ARGS((int c, int highlight));
  89. static void undisplay_dollar __ARGS((void));
  90. static void change_indent __ARGS((int type, int amount, int round, int replaced));
  91. static void insert_special __ARGS((int, int, int));
  92. static void redo_literal __ARGS((int c));
  93. static void start_arrow __ARGS((FPOS *end_insert_pos));
  94. static void stop_insert __ARGS((FPOS *end_insert_pos));
  95. static int  echeck_abbr __ARGS((int));
  96. static void replace_push_off __ARGS((int c));
  97. static int  replace_pop __ARGS((void));
  98. static void replace_join __ARGS((int off));
  99. static void replace_pop_ins __ARGS((void));
  100. static void replace_flush __ARGS((void));
  101. static void replace_do_bs __ARGS((void));
  102. static int  ins_reg __ARGS((void));
  103. static int  ins_esc __ARGS((long *count, int need_redraw, int cmdchar));
  104. #ifdef RIGHTLEFT
  105. static void ins_ctrl_ __ARGS((void));
  106. #endif
  107. static void ins_shift __ARGS((int c, int lastc));
  108. static void ins_del __ARGS((void));
  109. static int  ins_bs __ARGS((int c, int mode, int *inserted_space_p));
  110. #ifdef USE_MOUSE
  111. static void ins_mouse __ARGS((int c));
  112. #endif
  113. static void ins_left __ARGS((void));
  114. static void ins_home __ARGS((void));
  115. static void ins_end __ARGS((void));
  116. static void ins_s_left __ARGS((void));
  117. static void ins_right __ARGS((void));
  118. static void ins_s_right __ARGS((void));
  119. static void ins_up __ARGS((void));
  120. static void ins_pageup __ARGS((void));
  121. static void ins_down __ARGS((void));
  122. static void ins_pagedown __ARGS((void));
  123. static int  ins_tab __ARGS((void));
  124. static int  ins_eol __ARGS((int c));
  125. #ifdef DIGRAPHS
  126. static int  ins_digraph __ARGS((void));
  127. #endif
  128. static int  ins_copychar __ARGS((linenr_t lnum));
  129. #ifdef SMARTINDENT
  130. static void ins_try_si __ARGS((int c));
  131. #endif
  132. static colnr_t get_nolist_virtcol __ARGS((void));
  133. static FPOS Insstart; /* This is where the latest
  134.  * insert/append mode started. */
  135. static colnr_t Insstart_textlen; /* length of line when insert started */
  136. static colnr_t Insstart_blank_vcol; /* vcol for first inserted blank */
  137. static char_u *last_insert = NULL; /* the text of the previous insert */
  138. static int last_insert_skip; /* nr of chars in front of previous insert */
  139. static int new_insert_skip;  /* nr of chars in front of current insert */
  140. #ifdef CINDENT
  141. static int can_cindent; /* may do cindenting on this line */
  142. #endif
  143. static int old_indent = 0; /* for ^^D command in insert mode */
  144. #ifdef RIGHTLEFT
  145. int     revins_on;     /* reverse insert mode on */
  146. int     revins_chars;     /* how much to skip after edit */
  147. int     revins_legal;     /* was the last char 'legal'? */
  148. int     revins_scol;     /* start column of revins session */
  149. #endif
  150. /*
  151.  * edit(): Start insering text.
  152.  *
  153.  * "cmdchar" can be:
  154.  * 'i' normal insert command
  155.  * 'a' normal append command
  156.  * 'R' replace command
  157.  * 'r' "r<CR>" command: insert one <CR>.  Note: count can be > 1, for redo,
  158.  * but still only one <CR> is inserted.  The <Esc> is not used for redo.
  159.  * 'g' "gI" command.
  160.  *
  161.  * This function is not called recursively.  For CTRL-O commands, it returns
  162.  * and lets the caller handle the Normal-mode command.
  163.  *
  164.  * Return TRUE if a CTRL-O command caused the return (insert mode pending).
  165.  */
  166.     int
  167. edit(cmdchar, startln, count)
  168.     int cmdchar;
  169.     int startln; /* if set, insert at start of line */
  170.     long count;
  171. {
  172.     int  c = 0;
  173.     char_u *ptr;
  174.     int  lastc;
  175.     colnr_t  mincol;
  176.     static linenr_t o_lnum = 0;
  177.     static int  o_eol = FALSE;
  178.     int  need_redraw = FALSE;
  179.     int  i;
  180.     int  did_backspace = TRUE;     /* previous char was backspace */
  181. #ifdef CINDENT
  182.     int  line_is_white = FALSE;     /* line is empty before insert */
  183. #endif
  184.     linenr_t  old_topline = 0;     /* topline before insertion */
  185.     int  inserted_space = FALSE;    /* just inserted a space */
  186.     int  has_startsel;     /* may start selection */
  187.     /* sleep before redrawing, needed for "CTRL-O :" that results in an
  188.      * error message */
  189.     check_for_delay(TRUE);
  190. #ifdef INSERT_EXPAND
  191.     clear_insexp();     /* clear stuff for ctrl-x mode */
  192. #endif
  193. #ifdef USE_MOUSE
  194.     /*
  195.      * When doing a paste with the middle mouse button, Insstart is set to
  196.      * where the paste started.
  197.      */
  198.     if (where_paste_started.lnum != 0)
  199. Insstart = where_paste_started;
  200.     else
  201. #endif
  202.     {
  203. Insstart = curwin->w_cursor;
  204. if (startln)
  205.     Insstart.col = 0;
  206.     }
  207.     Insstart_textlen = linetabsize(ml_get_curline());
  208.     Insstart_blank_vcol = MAXCOL;
  209.     if (cmdchar != NUL && !restart_edit)
  210.     {
  211. ResetRedobuff();
  212. AppendNumberToRedobuff(count);
  213. AppendCharToRedobuff(cmdchar);
  214. if (cmdchar == 'g')     /* "gI" command */
  215.     AppendCharToRedobuff('I');
  216. else if (cmdchar == 'r')     /* "r<CR>" command */
  217.     count = 1;     /* insert only one <CR> */
  218.     }
  219.     if (cmdchar == 'R')
  220.     {
  221. #ifdef FKMAP
  222. if (p_fkmap && p_ri)
  223. {
  224.     beep_flush();
  225.     EMSG(farsi_text_3);     /* encoded in Farsi */
  226.     State = INSERT;
  227. }
  228. else
  229. #endif
  230. State = REPLACE;
  231.     }
  232.     else
  233. State = INSERT;
  234. #if defined(USE_GUI_WIN32) && defined(MULTI_BYTE_IME)
  235.     ImeSetOriginMode();
  236. #endif
  237.     /*
  238.      * Need to recompute the cursor position, it might move when the cursor is
  239.      * on a TAB or special character.
  240.      */
  241.     curs_columns(TRUE);
  242. #ifdef USE_MOUSE
  243.     setmouse();
  244. #endif
  245. #ifdef SHOWCMD
  246.     clear_showcmd();
  247. #endif
  248. #ifdef RIGHTLEFT
  249.     /* there is no reverse replace mode */
  250.     revins_on = (State == INSERT && p_ri);
  251.     if (revins_on)
  252. undisplay_dollar();
  253.     revins_chars = 0;
  254.     revins_legal = 0;
  255.     revins_scol = -1;
  256. #endif
  257.     /* if 'keymodel' contains "startsel", may start selection on shifted
  258.      * special key */
  259.     has_startsel = (vim_strchr(p_km, 'a') != NULL);
  260.     /*
  261.      * Handle restarting Insert mode.
  262.      * Don't do this for CTRL-O . (repeat an insert): we get here with
  263.      * restart_edit non-zero, and something in the stuff buffer.
  264.      */
  265.     if (restart_edit && stuff_empty())
  266.     {
  267. #ifdef USE_MOUSE
  268. /*
  269.  * After a paste we consider text typed to be part of the insert for
  270.  * the pasted text. You can backspace over the paste text too.
  271.  */
  272. if (where_paste_started.lnum)
  273.     arrow_used = FALSE;
  274. else
  275. #endif
  276.     arrow_used = TRUE;
  277. restart_edit = 0;
  278. /*
  279.  * If the cursor was after the end-of-line before the CTRL-O and it is
  280.  * now at the end-of-line, put it after the end-of-line (this is not
  281.  * correct in very rare cases).
  282.  * Also do this if curswant is greater than the current virtual
  283.  * column.  Eg after "^O$" or "^O80|".
  284.  */
  285. validate_virtcol();
  286. update_curswant();
  287. if (    ((o_eol && curwin->w_cursor.lnum == o_lnum)
  288.     || curwin->w_curswant > curwin->w_virtcol)
  289. && *(ptr = ml_get_curline() + curwin->w_cursor.col) != NUL
  290. && *(ptr + 1) == NUL)
  291.     ++curwin->w_cursor.col;
  292.     }
  293.     else
  294.     {
  295. arrow_used = FALSE;
  296. o_eol = FALSE;
  297.     }
  298. #ifdef USE_MOUSE
  299.     where_paste_started.lnum = 0;
  300. #endif
  301. #ifdef CINDENT
  302.     can_cindent = TRUE;
  303. #endif
  304.     /*
  305.      * If 'showmode' is set, show the current (insert/replace/..) mode.
  306.      * A warning message for changing a readonly file is given here, before
  307.      * actually changing anything.  It's put after the mode, if any.
  308.      */
  309.     i = 0;
  310.     if (p_smd)
  311. i = showmode();
  312.     if (!p_im)
  313. change_warning(i + 1);
  314. #ifdef CURSOR_SHAPE
  315.     ui_cursor_shape(); /* may show different cursor shape */
  316. #endif
  317. #ifdef DIGRAPHS
  318.     do_digraph(-1); /* clear digraphs */
  319. #endif
  320. /*
  321.  * Get the current length of the redo buffer, those characters have to be
  322.  * skipped if we want to get to the inserted characters.
  323.  */
  324.     ptr = get_inserted();
  325.     if (ptr == NULL)
  326. new_insert_skip = 0;
  327.     else
  328.     {
  329. new_insert_skip = STRLEN(ptr);
  330. vim_free(ptr);
  331.     }
  332.     old_indent = 0;
  333.     for (;;)
  334.     {
  335. #ifdef RIGHTLEFT
  336. if (!revins_legal)
  337.     revins_scol = -1;     /* reset on illegal motions */
  338. else
  339.     revins_legal = 0;
  340. #endif
  341. if (arrow_used)     /* don't repeat insert when arrow key used */
  342.     count = 0;
  343.     /* set curwin->w_curswant for next K_DOWN or K_UP */
  344. if (!arrow_used)
  345.     curwin->w_set_curswant = TRUE;
  346. /*
  347.  * When emsg() was called msg_scroll will have been set.
  348.  */
  349. msg_scroll = FALSE;
  350. /*
  351.  * If we inserted a character at the last position of the last line in
  352.  * the window, scroll the window one line up. This avoids an extra
  353.  * redraw.
  354.  * This is detected when the cursor column is smaller after inserting
  355.  * something.
  356.  * Don't do this when the topline changed already, it has
  357.  * already been adjusted (by insertchar() calling open_line())).
  358.  */
  359. if (need_redraw && curwin->w_p_wrap && !did_backspace &&
  360.      curwin->w_topline == old_topline)
  361. {
  362.     mincol = curwin->w_wcol;
  363.     validate_cursor_col();
  364.     if ((int)curwin->w_wcol < (int)mincol - curbuf->b_p_ts &&
  365.     curwin->w_wrow == curwin->w_winpos +
  366. curwin->w_height - 1 - p_so &&
  367.     curwin->w_cursor.lnum != curwin->w_topline)
  368.     {
  369. set_topline(curwin, curwin->w_topline + 1);
  370. update_topline();
  371. #ifdef SYNTAX_HL
  372. /* recompute syntax hl., starting with current line */
  373. syn_changed(curwin->w_cursor.lnum);
  374. #endif
  375. update_screen(VALID_TO_CURSCHAR);
  376. need_redraw = FALSE;
  377.     }
  378.     else
  379. update_topline();
  380. }
  381. else
  382.     update_topline();
  383. did_backspace = FALSE;
  384. /*
  385.  * redraw is postponed until here to make 'dollar' option work
  386.  * correctly.
  387.  */
  388. validate_cursor(); /* may set must_redraw */
  389. if (need_redraw || must_redraw)
  390. {
  391.     update_screenline();
  392.     if (curwin->w_redr_status == TRUE)
  393. win_redr_status(curwin); /* display [+] if required */
  394.     need_redraw = FALSE;
  395. }
  396. else if (clear_cmdline || redraw_cmdline)
  397.     showmode();     /* clear cmdline, show mode and ruler */
  398. showruler(FALSE);
  399. setcursor();
  400. update_curswant();
  401. emsg_on_display = FALSE; /* may remove error message now */
  402. old_topline = curwin->w_topline;
  403. #ifdef USE_GUI_WIN32
  404. dont_scroll = FALSE; /* allow scrolling here */
  405. #endif
  406. lastc = c; /* remember previous char for CTRL-D */
  407. c = vgetc();
  408. #ifdef RIGHTLEFT
  409. if (p_hkmap && KeyTyped)
  410.     c = hkmap(c); /* Hebrew mode mapping */
  411. #endif
  412. #ifdef FKMAP
  413. if (p_fkmap && KeyTyped)
  414.     c = fkmap(c); /* Farsi mode mapping */
  415. #endif
  416. #ifdef INSERT_EXPAND
  417. /*
  418.  * Prepare for or stop ctrl-x mode.
  419.  */
  420. need_redraw |= ins_expand_pre(c);
  421. #endif
  422. #ifdef DIGRAPHS
  423. c = do_digraph(c);
  424. #endif
  425. if (c == Ctrl('V') || c == Ctrl('Q'))
  426. {
  427.     if (redrawing() && !char_avail())
  428. edit_putchar('^', TRUE);
  429.     AppendToRedobuff((char_u *)"26"); /* CTRL-V */
  430. #ifdef SHOWCMD
  431.     add_to_showcmd_c(c);
  432. #endif
  433.     c = get_literal();
  434. #ifdef SHOWCMD
  435.     clear_showcmd();
  436. #endif
  437.     insert_special(c, FALSE, TRUE);
  438.     need_redraw = TRUE;
  439. #ifdef RIGHTLEFT
  440.     revins_chars++;
  441.     revins_legal++;
  442. #endif
  443.     c = Ctrl('V'); /* pretend CTRL-V is last typed character */
  444.     continue;
  445. }
  446. #ifdef MULTI_BYTE
  447. # if defined(USE_GUI) && !defined(USE_GUI_WIN32)
  448. if (!gui.in_use)
  449. # endif
  450. if (is_dbcs && IsLeadByte(c))
  451. {
  452.     int c2;
  453.     c2 = get_literal();
  454.     insert_special(c, FALSE, FALSE);
  455.     insert_special(c2, FALSE, FALSE);
  456.     need_redraw = TRUE;
  457.     continue;
  458. }
  459. #endif
  460. #ifdef CINDENT
  461. if (curbuf->b_p_cin
  462. # ifdef INSERT_EXPAND
  463.     && !ctrl_x_mode
  464. # endif
  465.        )
  466. {
  467.     line_is_white = inindent(0);
  468.     /*
  469.      * A key name preceded by a bang means that this
  470.      * key wasn't destined to be inserted.  Skip ahead
  471.      * to the re-indenting if we find one.
  472.      */
  473.     if (in_cinkeys(c, '!', line_is_white))
  474. goto force_cindent;
  475.     /*
  476.      * A key name preceded by a star means that indenting
  477.      * has to be done before inserting the key.
  478.      */
  479.     if (can_cindent && in_cinkeys(c, '*', line_is_white))
  480.     {
  481. stop_arrow();
  482. /* re-indent the current line */
  483. fixthisline(get_c_indent);
  484. /* draw the changes on the screen later */
  485. need_redraw = TRUE;
  486.     }
  487. }
  488. #endif /* CINDENT */
  489. #ifdef RIGHTLEFT
  490. if (curwin->w_p_rl)
  491.     switch (c)
  492.     {
  493. case K_LEFT: c = K_RIGHT; break;
  494. case K_S_LEFT: c = K_S_RIGHT; break;
  495. case K_RIGHT: c = K_LEFT; break;
  496. case K_S_RIGHT: c = K_S_LEFT; break;
  497.     }
  498. #endif
  499. /* if 'keymodel' contains "startsel", may start selection */
  500. if (has_startsel)
  501.     switch (c)
  502.     {
  503. case K_KHOME:
  504. case K_KEND:
  505. case K_PAGEUP:
  506. case K_KPAGEUP:
  507. case K_PAGEDOWN:
  508. case K_KPAGEDOWN:
  509.     if (!(mod_mask & MOD_MASK_SHIFT))
  510. break;
  511.     /* FALLTHROUGH */
  512. case K_S_LEFT:
  513. case K_S_RIGHT:
  514. case K_S_UP:
  515. case K_S_DOWN:
  516. case K_S_END:
  517. case K_S_HOME:
  518.     /* Start selection right away, the cursor can move with
  519.      * CTRL-O when beyond the end of the line. */
  520.     start_selection();
  521.     /* Execute the key in (insert) Select mode, unless it's
  522.      * shift-left and beyond the end of the line (the CTRL-O
  523.      * will move the cursor left already). */
  524.     stuffcharReadbuff(Ctrl('O'));
  525.     if (c != K_S_LEFT || gchar_cursor() != NUL)
  526.     {
  527. if (mod_mask)
  528. {
  529.     char_u     buf[4];
  530.     buf[0] = K_SPECIAL;
  531.     buf[1] = KS_MODIFIER;
  532.     buf[2] = mod_mask;
  533.     buf[3] = NUL;
  534.     stuffReadbuff(buf);
  535. }
  536. stuffcharReadbuff(c);
  537.     }
  538.     continue;
  539.     }
  540. /*
  541.  * The big switch to handle a character in insert mode.
  542.  */
  543. switch (c)
  544. {
  545. case K_INS:     /* toggle insert/replace mode */
  546. #ifdef FKMAP
  547.     if (p_fkmap && p_ri)
  548.     {
  549. beep_flush();
  550. EMSG(farsi_text_3); /* encoded in Farsi */
  551. break;
  552.     }
  553. #endif
  554.     if (State == REPLACE)
  555. State = INSERT;
  556.     else
  557. State = REPLACE;
  558.     AppendCharToRedobuff(K_INS);
  559.     showmode();
  560. #ifdef CURSOR_SHAPE
  561.     ui_cursor_shape(); /* may show different cursor shape */
  562. #endif
  563.     break;
  564. #ifdef INSERT_EXPAND
  565. case Ctrl('X'):     /* Enter ctrl-x mode */
  566.     /* if the next ^X<> won't ADD nothing, then reset continue_status */
  567.     continue_status = continue_status & CONT_N_ADDS ?
  568. continue_status | CONT_INTRPT : 0;
  569.     /* We're not sure which ctrl-x mode it will be yet */
  570.     ctrl_x_mode = CTRL_X_NOT_DEFINED_YET;
  571.     edit_submode = (char_u *)ctrl_x_msgs[ctrl_x_mode & 15];
  572.     showmode();
  573.     break;
  574. #endif
  575. case K_SELECT:     /* end of Select mode mapping - ignore */
  576.     break;
  577. case Ctrl('Z'):     /* suspend when 'insertmode' set */
  578.     if (!p_im)
  579. goto normalchar; /* insert CTRL-Z as normal char */
  580.     stuffReadbuff((char_u *)":str");
  581.     c = Ctrl('O');
  582.     /*FALLTHROUGH*/
  583. case Ctrl('O'):     /* execute one command */
  584.     if (echeck_abbr(Ctrl('O') + ABBR_OFF))
  585. break;
  586.     count = 0;
  587.     if (State == INSERT)
  588. restart_edit = 'I';
  589.     else
  590. restart_edit = 'R';
  591.     o_lnum = curwin->w_cursor.lnum;
  592.     o_eol = (gchar_cursor() == NUL);
  593.     goto doESCkey;
  594. #ifdef USE_SNIFF
  595. case K_SNIFF:
  596.     stuffcharReadbuff(K_SNIFF);
  597.     goto doESCkey;
  598. #endif
  599.   /* Hitting the help key in insert mode is like <ESC> <Help> */
  600. case K_HELP:
  601. case K_F1:
  602.     stuffcharReadbuff(K_HELP);
  603.     if (p_im)
  604. stuffcharReadbuff('i');
  605.     goto doESCkey;
  606. case ESC:     /* an escape ends input mode */
  607.     if (echeck_abbr(ESC + ABBR_OFF))
  608. break;
  609.     /*FALLTHROUGH*/
  610. case Ctrl('C'):
  611. #ifdef UNIX
  612. do_intr:
  613. #endif
  614.     /* when 'insertmode' set, and not halfway a mapping, don't leave
  615.      * Insert mode */
  616.     if (goto_im())
  617.     {
  618. if (got_int)
  619. {
  620.     (void)vgetc(); /* flush all buffers */
  621.     got_int = FALSE;
  622. }
  623. else
  624.     vim_beep();
  625. break;
  626.     }
  627. doESCkey:
  628.     /*
  629.      * This is the ONLY return from edit()!
  630.      */
  631.     if (ins_esc(&count, need_redraw, cmdchar))
  632. return (c == Ctrl('O'));
  633.     continue;
  634.     /*
  635.      * Insert the previously inserted text.
  636.      * For ^@ the trailing ESC will end the insert, unless there
  637.      * is an error.
  638.      */
  639. case K_ZERO:
  640. case NUL:
  641. case Ctrl('A'):
  642.     if (stuff_inserted(NUL, 1L, (c == Ctrl('A'))) == FAIL
  643.    && c != Ctrl('A') && !p_im)
  644. goto doESCkey; /* quit insert mode */
  645.     break;
  646. /*
  647.  * insert the contents of a register
  648.  */
  649. case Ctrl('R'):
  650.     need_redraw |= ins_reg();
  651.     break;
  652. #ifdef RIGHTLEFT
  653. case Ctrl('_'):
  654.     if (!p_ari)
  655. goto normalchar;
  656.     ins_ctrl_();
  657.     break;
  658. #endif
  659. /* Make indent one shiftwidth smaller. */
  660. case Ctrl('D'):
  661. #if defined(INSERT_EXPAND) && defined(FIND_IN_PATH)
  662.     if (ctrl_x_mode == CTRL_X_PATH_DEFINES)
  663. goto docomplete;
  664. #endif
  665.     /* FALLTHROUGH */
  666. /* Make indent one shiftwidth greater. */
  667. case Ctrl('T'):
  668.     ins_shift(c, lastc);
  669.     need_redraw = TRUE;
  670.     break;
  671. /* delete character under the cursor */
  672. case K_DEL:
  673.     ins_del();
  674.     need_redraw = TRUE;
  675.     break;
  676. /* delete character before the cursor */
  677. case K_BS:
  678. case Ctrl('H'):
  679.     did_backspace = ins_bs(c, BACKSPACE_CHAR, &inserted_space);
  680.     need_redraw = TRUE;
  681.     break;
  682. /* delete word before the cursor */
  683. case Ctrl('W'):
  684.     did_backspace = ins_bs(c, BACKSPACE_WORD, &inserted_space);
  685.     need_redraw = TRUE;
  686.     break;
  687. /* delete all inserted text in current line */
  688. case Ctrl('U'):
  689.     did_backspace = ins_bs(c, BACKSPACE_LINE, &inserted_space);
  690.     need_redraw = TRUE;
  691.     break;
  692. #ifdef USE_MOUSE
  693. case K_LEFTMOUSE:
  694. case K_LEFTDRAG:
  695. case K_LEFTRELEASE:
  696. case K_MIDDLEMOUSE:
  697. case K_MIDDLEDRAG:
  698. case K_MIDDLERELEASE:
  699. case K_RIGHTMOUSE:
  700. case K_RIGHTDRAG:
  701. case K_RIGHTRELEASE:
  702.     ins_mouse(c);
  703.     break;
  704. case K_IGNORE:
  705.     break;
  706. #endif
  707. #ifdef USE_GUI
  708. case K_SCROLLBAR:
  709.     ins_scroll();
  710.     break;
  711. case K_HORIZ_SCROLLBAR:
  712.     ins_horscroll();
  713.     break;
  714. #endif
  715. case K_HOME:
  716. case K_KHOME:
  717. case K_S_HOME:
  718.     ins_home();
  719.     break;
  720. case K_END:
  721. case K_KEND:
  722. case K_S_END:
  723.     ins_end();
  724.     break;
  725. case K_LEFT:
  726.     if (mod_mask & MOD_MASK_CTRL)
  727. ins_s_left();
  728.     else
  729. ins_left();
  730.     break;
  731. case K_S_LEFT:
  732.     ins_s_left();
  733.     break;
  734. case K_RIGHT:
  735.     if (mod_mask & MOD_MASK_CTRL)
  736. ins_s_right();
  737.     else
  738. ins_right();
  739.     break;
  740. case K_S_RIGHT:
  741.     ins_s_right();
  742.     break;
  743. case K_UP:
  744.     ins_up();
  745.     break;
  746. case K_S_UP:
  747. case K_PAGEUP:
  748. case K_KPAGEUP:
  749.     ins_pageup();
  750.     break;
  751. case K_DOWN:
  752.     ins_down();
  753.     break;
  754. case K_S_DOWN:
  755. case K_PAGEDOWN:
  756. case K_KPAGEDOWN:
  757.     ins_pagedown();
  758.     break;
  759.     /* keypad keys: When not mapped they produce a normal char */
  760. case K_KPLUS: c = '+'; goto normalchar;
  761. case K_KMINUS: c = '-'; goto normalchar;
  762. case K_KDIVIDE: c = '/'; goto normalchar;
  763. case K_KMULTIPLY: c = '*'; goto normalchar;
  764.     /* When <S-Tab> isn't mapped, use it like a normal TAB */
  765. case K_S_TAB:
  766.     c = TAB;
  767.     /* FALLTHROUGH */
  768. /* TAB or Complete patterns along path */
  769. case TAB:
  770. #if defined(INSERT_EXPAND) && defined(FIND_IN_PATH)
  771.     if (ctrl_x_mode == CTRL_X_PATH_PATTERNS)
  772. goto docomplete;
  773. #endif
  774.     inserted_space = FALSE;
  775.     if (ins_tab())
  776. goto normalchar; /* insert TAB as a normal char */
  777.     need_redraw = TRUE;
  778.     break;
  779. case K_KENTER:
  780.     c = CR;
  781.     /* FALLTHROUGH */
  782. case CR:
  783. case NL:
  784.     if (ins_eol(c) && !p_im)
  785. goto doESCkey;     /* out of memory */
  786.     break;
  787. #if defined(DIGRAPHS) || defined (INSERT_EXPAND)
  788. case Ctrl('K'):
  789. # ifdef INSERT_EXPAND
  790.     if (ctrl_x_mode == CTRL_X_DICTIONARY)
  791.     {
  792. if (*p_dict == NUL)
  793. {
  794.     ctrl_x_mode = 0;
  795.     msg_attr((char_u *)"'dictionary' option is empty",
  796.      hl_attr(HLF_E));
  797.     vim_beep();
  798.     setcursor();
  799.     out_flush();
  800.     ui_delay(2000L, FALSE);
  801.     break;
  802. }
  803. goto docomplete;
  804.     }
  805. # endif
  806. # ifdef DIGRAPHS
  807.     c = ins_digraph();
  808.     if (c == NUL)
  809.     {
  810. need_redraw = TRUE;
  811. break;
  812.     }
  813. # endif
  814.     goto normalchar;
  815. #endif /* DIGRAPHS || INSERT_EXPAND */
  816. #ifdef INSERT_EXPAND
  817. case Ctrl(']'): /* Tag name completion after ^X */
  818.     if (ctrl_x_mode != CTRL_X_TAGS)
  819. goto normalchar;
  820.     goto docomplete;
  821. case Ctrl('F'): /* File name completion after ^X */
  822.     if (ctrl_x_mode != CTRL_X_FILES)
  823. goto normalchar;
  824.     goto docomplete;
  825. #endif
  826. case Ctrl('L'): /* Whole line completion after ^X */
  827. #ifdef INSERT_EXPAND
  828.     if (ctrl_x_mode != CTRL_X_WHOLE_LINE)
  829. #endif
  830.     {
  831. /* CTRL-L with 'insertmode' set: Leave Insert mode */
  832. if (p_im)
  833. {
  834.     if (echeck_abbr(Ctrl('L') + ABBR_OFF))
  835. break;
  836.     goto doESCkey;
  837. }
  838. goto normalchar;
  839.     }
  840. #ifdef INSERT_EXPAND
  841.     /* FALLTHROUGH */
  842. case Ctrl('P'): /* Do previous pattern completion */
  843. case Ctrl('N'): /* Do next pattern completion */
  844.     /* if 'complete' is empty then plain ^P is no longer special,
  845.      * but it is under other ^X modes */
  846.     if (    *curbuf->b_p_cpt == NUL && !ctrl_x_mode
  847.     && !(continue_status & CONT_LOCAL))
  848. goto normalchar;
  849. docomplete:
  850.     i = ins_complete(c);
  851.     if (i)
  852. need_redraw |= i;
  853.     else
  854. continue_status = 0;
  855.     break;
  856. #endif /* INSERT_EXPAND */
  857. case Ctrl('Y'): /* copy from previous line or scroll down */
  858. case Ctrl('E'): /* copy from next line    or scroll up */
  859. #ifdef INSERT_EXPAND
  860.     if (ctrl_x_mode == CTRL_X_SCROLL)
  861.     {
  862. if (c == Ctrl('Y'))
  863.     scrolldown_clamp();
  864. else
  865.     scrollup_clamp();
  866. update_screen(VALID);
  867.     }
  868.     else
  869. #endif
  870.     {
  871. c = ins_copychar(curwin->w_cursor.lnum
  872.  + (c == Ctrl('Y') ? -1 : 1));
  873. if (c != NUL)
  874. {
  875.     long tw_save;
  876.     /* The character must be taken literally, insert like it
  877.      * was typed after a CTRL-V, and pretend 'textwidth'
  878.      * wasn't set.  Digits, 'o' and 'x' are special after a
  879.      * CTRL-V, don't use it for these. */
  880.     if (!isalnum(c))
  881. AppendToRedobuff((char_u *)"26"); /* CTRL-V */
  882.     tw_save = curbuf->b_p_tw;
  883.     curbuf->b_p_tw = -1;
  884.     insert_special(c, TRUE, TRUE);
  885.     curbuf->b_p_tw = tw_save;
  886.     need_redraw = TRUE;
  887. #ifdef RIGHTLEFT
  888.     revins_chars++;
  889.     revins_legal++;
  890. #endif
  891.     c = Ctrl('V'); /* pretend CTRL-V is last character */
  892. }
  893.     }
  894.     break;
  895.   default:
  896. #ifdef UNIX
  897.     if (c == intr_char) /* special interrupt char */
  898. goto do_intr;
  899. #endif
  900. normalchar:
  901. #ifdef SMARTINDENT
  902.     /*
  903.      * Try to perform smart-indenting.
  904.      */
  905.     ins_try_si(c);
  906. #endif
  907.     if (c == ' ')
  908.     {
  909. inserted_space = TRUE;
  910. #ifdef CINDENT
  911. if (inindent(0))
  912.     can_cindent = FALSE;
  913. #endif
  914. if (Insstart_blank_vcol == MAXCOL
  915. && curwin->w_cursor.lnum == Insstart.lnum)
  916.     Insstart_blank_vcol = get_nolist_virtcol();
  917.     }
  918.     if (vim_iswordc(c) || !echeck_abbr(c))
  919.     {
  920. insert_special(c, FALSE, FALSE);
  921. need_redraw = TRUE;
  922. #ifdef RIGHTLEFT
  923. revins_legal++;
  924. revins_chars++;
  925. #endif
  926.     }
  927.     break;
  928. }   /* end of switch (c) */
  929. #ifdef CINDENT
  930. if (curbuf->b_p_cin && can_cindent
  931. # ifdef INSERT_EXPAND
  932.     && !ctrl_x_mode
  933. # endif
  934.        )
  935. {
  936. force_cindent:
  937.     /*
  938.      * Indent now if a key was typed that is in 'cinkeys'.
  939.      */
  940.     if (in_cinkeys(c, ' ', line_is_white))
  941.     {
  942. stop_arrow();
  943. /* re-indent the current line */
  944. fixthisline(get_c_indent);
  945. /* draw the changes on the screen later */
  946. need_redraw = TRUE;
  947.     }
  948. }
  949. #endif /* CINDENT */
  950.     } /* for (;;) */
  951.     /* NOTREACHED */
  952. }
  953. /*
  954.  * Put a character directly onto the screen.  It's not stored in a buffer.
  955.  * Used while handling CTRL-K, CTRL-V, etc. in Insert mode.
  956.  */
  957.     static void
  958. edit_putchar(c, highlight)
  959.     int     c;
  960.     int     highlight;
  961. {
  962.     int     attr;
  963.     if (NextScreen != NULL)
  964.     {
  965. update_topline(); /* just in case w_topline isn't valid */
  966. validate_cursor();
  967. if (highlight)
  968.     attr = hl_attr(HLF_8);
  969. else
  970.     attr = 0;
  971. screen_putchar(c, curwin->w_winpos + curwin->w_wrow,
  972. #ifdef RIGHTLEFT
  973.     curwin->w_p_rl ? (int)Columns - 1 - curwin->w_wcol :
  974. #endif
  975.  curwin->w_wcol, attr);
  976.     }
  977. }
  978. /*
  979.  * Called when p_dollar is set: display a '$' at the end of the changed text
  980.  * Only works when cursor is in the line that changes.
  981.  */
  982.     void
  983. display_dollar(col)
  984.     colnr_t col;
  985. {
  986.     colnr_t save_col;
  987.     if (!redrawing())
  988. return;
  989.     cursor_off();
  990.     save_col = curwin->w_cursor.col;
  991.     curwin->w_cursor.col = col;
  992.     curs_columns(FALSE);     /* recompute w_wrow and w_wcol */
  993.     if (curwin->w_wcol < Columns)
  994.     {
  995. edit_putchar('$', FALSE);
  996. dollar_vcol = curwin->w_virtcol;
  997.     }
  998.     curwin->w_cursor.col = save_col;
  999. }
  1000. /*
  1001.  * Call this function before moving the cursor from the normal insert position
  1002.  * in insert mode.
  1003.  */
  1004.     static void
  1005. undisplay_dollar()
  1006. {
  1007.     if (dollar_vcol)
  1008.     {
  1009. dollar_vcol = 0;
  1010. update_screenline();
  1011.     }
  1012. }
  1013. /*
  1014.  * Insert an indent (for <Tab> or CTRL-T) or delete an indent (for CTRL-D).
  1015.  * Keep the cursor on the same character.
  1016.  * type == INDENT_INC increase indent (for CTRL-T or <Tab>)
  1017.  * type == INDENT_DEC decrease indent (for CTRL-D)
  1018.  * type == INDENT_SET set indent to "amount"
  1019.  * if round is TRUE, round the indent to 'shiftwidth' (only with _INC and _Dec).
  1020.  */
  1021.     static void
  1022. change_indent(type, amount, round, replaced)
  1023.     int     type;
  1024.     int     amount;
  1025.     int     round;
  1026.     int     replaced; /* replaced character, put on replace stack */
  1027. {
  1028.     int vcol;
  1029.     int last_vcol;
  1030.     int insstart_less; /* reduction for Insstart.col */
  1031.     int new_cursor_col;
  1032.     int i;
  1033.     char_u *ptr;
  1034.     int save_p_list;
  1035.     int start_col;
  1036.     colnr_t vc;
  1037.     /* for the following tricks we don't want list mode */
  1038.     save_p_list = curwin->w_p_list;
  1039.     curwin->w_p_list = FALSE;
  1040.     getvcol(curwin, &curwin->w_cursor, NULL, &vc, NULL);
  1041.     vcol = vc;
  1042.     /*
  1043.      * For Replace mode we need to fix the replace stack later, which is only
  1044.      * possible when the cursor is in the indent.  Remember the number of
  1045.      * characters before the cursor if it's possible.
  1046.      */
  1047.     start_col = curwin->w_cursor.col;
  1048.     /* determine offset from first non-blank */
  1049.     new_cursor_col = curwin->w_cursor.col;
  1050.     beginline(BL_WHITE);
  1051.     new_cursor_col -= curwin->w_cursor.col;
  1052.     insstart_less = curwin->w_cursor.col;
  1053.     /*
  1054.      * If the cursor is in the indent, compute how many screen columns the
  1055.      * cursor is to the left of the first non-blank.
  1056.      */
  1057.     if (new_cursor_col < 0)
  1058. vcol = get_indent() - vcol;
  1059.     if (new_cursor_col > 0)     /* can't fix replace stack */
  1060. start_col = -1;
  1061.     /*
  1062.      * Set the new indent.  The cursor will be put on the first non-blank.
  1063.      */
  1064.     if (type == INDENT_SET)
  1065. set_indent(amount, TRUE);
  1066.     else
  1067. shift_line(type == INDENT_DEC, round, 1);
  1068.     insstart_less -= curwin->w_cursor.col;
  1069.     /*
  1070.      * Try to put cursor on same character.
  1071.      * If the cursor is at or after the first non-blank in the line,
  1072.      * compute the cursor column relative to the column of the first
  1073.      * non-blank character.
  1074.      * If we are not in insert mode, leave the cursor on the first non-blank.
  1075.      * If the cursor is before the first non-blank, position it relative
  1076.      * to the first non-blank, counted in screen columns.
  1077.      */
  1078.     if (new_cursor_col >= 0)
  1079. new_cursor_col += curwin->w_cursor.col;
  1080.     else if (!(State & INSERT))
  1081. new_cursor_col = curwin->w_cursor.col;
  1082.     else
  1083.     {
  1084. /*
  1085.  * Compute the screen column where the cursor should be.
  1086.  */
  1087. vcol = get_indent() - vcol;
  1088. curwin->w_virtcol = (vcol < 0) ? 0 : vcol;
  1089. /*
  1090.  * Advance the cursor until we reach the right screen column.
  1091.  */
  1092. vcol = last_vcol = 0;
  1093. new_cursor_col = -1;
  1094. ptr = ml_get_curline();
  1095. while (vcol <= (int)curwin->w_virtcol)
  1096. {
  1097.     last_vcol = vcol;
  1098.     ++new_cursor_col;
  1099.     vcol += lbr_chartabsize(ptr + new_cursor_col, (colnr_t)vcol);
  1100. }
  1101. vcol = last_vcol;
  1102. /*
  1103.  * May need to insert spaces to be able to position the cursor on
  1104.  * the right screen column.
  1105.  */
  1106. if (vcol != (int)curwin->w_virtcol)
  1107. {
  1108.     curwin->w_cursor.col = new_cursor_col;
  1109.     i = (int)curwin->w_virtcol - vcol;
  1110.     ptr = alloc(i + 1);
  1111.     if (ptr != NULL)
  1112.     {
  1113. new_cursor_col += i;
  1114. ptr[i] = NUL;
  1115. while (--i >= 0)
  1116.     ptr[i] = ' ';
  1117. ins_str(ptr);
  1118. vim_free(ptr);
  1119.     }
  1120. }
  1121. /*
  1122.  * When changing the indent while the cursor is in it, reset
  1123.  * Insstart_col to 0.
  1124.  */
  1125. insstart_less = Insstart.col;
  1126.     }
  1127.     curwin->w_p_list = save_p_list;
  1128.     if (new_cursor_col <= 0)
  1129. curwin->w_cursor.col = 0;
  1130.     else
  1131. curwin->w_cursor.col = new_cursor_col;
  1132.     curwin->w_set_curswant = TRUE;
  1133.     changed_cline_bef_curs();
  1134.     /*
  1135.      * May have to adjust the start of the insert.
  1136.      */
  1137.     if ((State & INSERT) && curwin->w_cursor.lnum == Insstart.lnum &&
  1138.     Insstart.col != 0)
  1139.     {
  1140. if ((int)Insstart.col <= insstart_less)
  1141.     Insstart.col = 0;
  1142. else
  1143.     Insstart.col -= insstart_less;
  1144.     }
  1145.     /*
  1146.      * May have to fix the replace stack, if it's possible.
  1147.      * If the number of characters before the cursor decreased, need to pop a
  1148.      * few characters from the replace stack.
  1149.      * If the number of characters before the cursor increased, need to push a
  1150.      * few NULs onto the replace stack.
  1151.      */
  1152.     if (State == REPLACE && start_col >= 0)
  1153.     {
  1154. while (start_col > (int)curwin->w_cursor.col)
  1155. {
  1156.     replace_join(0);     /* remove a NUL from the replace stack */
  1157.     --start_col;
  1158. }
  1159. while (start_col < (int)curwin->w_cursor.col || replaced)
  1160. {
  1161.     replace_push(NUL);
  1162.     if (replaced)
  1163.     {
  1164. replace_push(replaced);
  1165. replaced = NUL;
  1166.     }
  1167.     ++start_col;
  1168. }
  1169.     }
  1170. }
  1171. #ifdef INSERT_EXPAND
  1172. /*
  1173.  * Is the character 'c' a valid key to keep us in the current ctrl-x mode?
  1174.  * -- webb
  1175.  */
  1176.     int
  1177. vim_is_ctrl_x_key(c)
  1178.     int     c;
  1179. {
  1180.     switch (ctrl_x_mode)
  1181.     {
  1182. case 0:     /* Not in any ctrl-x mode */
  1183.     break;
  1184. case CTRL_X_NOT_DEFINED_YET:
  1185.     if (       c == Ctrl('X') || c == Ctrl('Y') || c == Ctrl('E')
  1186.     || c == Ctrl('L') || c == Ctrl('F') || c == Ctrl(']')
  1187.     || c == Ctrl('I') || c == Ctrl('D') || c == Ctrl('P')
  1188.     || c == Ctrl('N'))
  1189. return TRUE;
  1190.     break;
  1191. case CTRL_X_SCROLL:
  1192.     if (c == Ctrl('Y') || c == Ctrl('E'))
  1193. return TRUE;
  1194.     break;
  1195. case CTRL_X_WHOLE_LINE:
  1196.     if (c == Ctrl('L') || c == Ctrl('P') || c == Ctrl('N'))
  1197. return TRUE;
  1198.     break;
  1199. case CTRL_X_FILES:
  1200.     if (c == Ctrl('F') || c == Ctrl('P') || c == Ctrl('N'))
  1201. return TRUE;
  1202.     break;
  1203. case CTRL_X_DICTIONARY:
  1204.     if (c == Ctrl('K') || c == Ctrl('P') || c == Ctrl('N'))
  1205. return TRUE;
  1206.     break;
  1207. case CTRL_X_TAGS:
  1208.     if (c == Ctrl(']') || c == Ctrl('P') || c == Ctrl('N'))
  1209. return TRUE;
  1210.     break;
  1211. #ifdef FIND_IN_PATH
  1212. case CTRL_X_PATH_PATTERNS:
  1213.     if (c == Ctrl('P') || c == Ctrl('N'))
  1214. return TRUE;
  1215.     break;
  1216. case CTRL_X_PATH_DEFINES:
  1217.     if (c == Ctrl('D') || c == Ctrl('P') || c == Ctrl('N'))
  1218. return TRUE;
  1219.     break;
  1220. #endif
  1221. default:
  1222.     emsg(e_internal);
  1223.     break;
  1224.     }
  1225.     return FALSE;
  1226. }
  1227. /*
  1228.  * This is like add_completion(), but if ic and inf are set, then the
  1229.  * case of the originally typed text is used, and the case of the completed
  1230.  * text is infered, ie this tries to work out what case you probably wanted
  1231.  * the rest of the word to be in -- webb
  1232.  */
  1233.     int
  1234. add_completion_and_infercase(str, len, fname, dir, reuse)
  1235.     char_u  *str;
  1236.     int     len;
  1237.     char_u  *fname;
  1238.     int     dir;
  1239.     int     reuse;
  1240. {
  1241.     int has_lower = FALSE;
  1242.     int was_letter = FALSE;
  1243.     int idx;
  1244.     if (p_ic && curbuf->b_p_inf && len < IOSIZE)
  1245.     {
  1246. /* Infer case of completed part -- webb */
  1247. /* Use IObuff, str would change text in buffer! */
  1248. STRNCPY(IObuff, str, len);
  1249. IObuff[len] = NUL;
  1250. /* Rule 1: Were any chars converted to lower? */
  1251. for (idx = 0; idx < completion_length; ++idx)
  1252. {
  1253.     if (islower(original_text[idx]))
  1254.     {
  1255. has_lower = TRUE;
  1256. if (isupper(IObuff[idx]))
  1257. {
  1258.     /* Rule 1 is satisfied */
  1259.     for (idx = completion_length; idx < len; ++idx)
  1260. IObuff[idx] = TO_LOWER(IObuff[idx]);
  1261.     break;
  1262. }
  1263.     }
  1264. }
  1265. /*
  1266.  * Rule 2: No lower case, 2nd consecutive letter converted to
  1267.  * upper case.
  1268.  */
  1269. if (!has_lower)
  1270. {
  1271.     for (idx = 0; idx < completion_length; ++idx)
  1272.     {
  1273. if (was_letter && isupper(original_text[idx]) &&
  1274.     islower(IObuff[idx]))
  1275. {
  1276.     /* Rule 2 is satisfied */
  1277.     for (idx = completion_length; idx < len; ++idx)
  1278. IObuff[idx] = TO_UPPER(IObuff[idx]);
  1279.     break;
  1280. }
  1281. was_letter = isalpha(original_text[idx]);
  1282.     }
  1283. }
  1284. /* Copy the original case of the part we typed */
  1285. STRNCPY(IObuff, original_text, completion_length);
  1286. return add_completion(IObuff, len, fname, dir, reuse);
  1287.     }
  1288.     return add_completion(str, len, fname, dir, reuse);
  1289. }
  1290. /*
  1291.  * Add a match to the list of matches.
  1292.  * If the given string is already in the list of completions, then return
  1293.  * FAIL, otherwise add it to the list and return OK.  If there is an error,
  1294.  * maybe because alloc returns NULL, then RET_ERROR is returned -- webb.
  1295.  */
  1296.     static int
  1297. add_completion(str, len, fname, dir, reuse)
  1298.     char_u  *str;
  1299.     int     len;
  1300.     char_u  *fname;
  1301.     int     dir;
  1302.     int     reuse;
  1303. {
  1304.     struct Completion *match;
  1305.     ui_breakcheck();
  1306.     if (got_int)
  1307. return RET_ERROR;
  1308.     if (len < 0)
  1309. len = STRLEN(str);
  1310.     /*
  1311.      * If the same match is already present, don't add it.
  1312.      */
  1313.     if (first_match != NULL)
  1314.     {
  1315. match = first_match;
  1316. do
  1317. {
  1318.     if (    !(match->original & ORIGINAL_TEXT)
  1319.     && STRNCMP(match->str, str, (size_t)len) == 0
  1320.     && match->str[len] == NUL)
  1321. return FAIL;
  1322.     match = match->next;
  1323. } while (match != NULL && match != first_match);
  1324.     }
  1325.     /*
  1326.      * Allocate a new match structure.
  1327.      * Copy the values to the new match structure.
  1328.      */
  1329.     match = (struct Completion *)alloc((unsigned)sizeof(struct Completion));
  1330.     if (match == NULL)
  1331. return RET_ERROR;
  1332.     if (reuse & ORIGINAL_TEXT)
  1333. match->str = original_text;
  1334.     else if ((match->str = vim_strnsave(str, len)) == NULL)
  1335.     {
  1336. vim_free(match);
  1337. return RET_ERROR;
  1338.     }
  1339.     /* match-fname is:
  1340.      * - curr_match->fname if it is a string equal to fname.
  1341.      * - a copy of fname, FREE_FNAME is set to free later THE allocated mem.
  1342.      * - NULL otherwise. --Acevedo */
  1343.     if (fname && curr_match && curr_match->fname
  1344.       && STRCMP(fname, curr_match->fname) == 0)
  1345. match->fname = curr_match->fname;
  1346.     else if (fname && (match->fname = vim_strsave(fname)) != NULL)
  1347. reuse |= FREE_FNAME;
  1348.     else
  1349. match->fname = NULL;
  1350.     match->original = reuse;
  1351.     /*
  1352.      * Link the new match structure in the list of matches.
  1353.      */
  1354.     if (first_match == NULL)
  1355. match->next = match->prev = NULL;
  1356.     else if (dir == FORWARD)
  1357.     {
  1358. match->next = curr_match->next;
  1359. match->prev = curr_match;
  1360.     }
  1361.     else /* BACKWARD */
  1362.     {
  1363. match->next = curr_match;
  1364. match->prev = curr_match->prev;
  1365.     }
  1366.     if (match->next)
  1367. match->next->prev = match;
  1368.     if (match->prev)
  1369. match->prev->next = match;
  1370.     else /* if there's nothing before, it is the first match */
  1371. first_match = match;
  1372.     curr_match = match;
  1373.     return OK;
  1374. }
  1375. /* Make the completion list cyclic.
  1376.  * Return the number of matches (excluding the original).
  1377.  */
  1378.     static int
  1379. make_cyclic()
  1380. {
  1381.     struct Completion *match;
  1382.     int     count = 0;
  1383.     if (first_match != NULL)
  1384.     {
  1385. /*
  1386.  * Find the end of the list.
  1387.  */
  1388. match = first_match;
  1389. /* there's always an entry for the original_text, it doesn't count. */
  1390. while (match->next != NULL && match->next != first_match)
  1391. {
  1392.     match = match->next;
  1393.     ++count;
  1394. }
  1395. match->next = first_match;
  1396. first_match->prev = match;
  1397.     }
  1398.     return count;
  1399. }
  1400. #define DICT_FIRST (1) /* use just first element in "dict" */
  1401. #define DICT_EXACT (2) /* "dict" is the exact name of a file */
  1402. /*
  1403.  * Add any identifiers that match the given pattern to the list of
  1404.  * completions.
  1405.  */
  1406.     static void
  1407. complete_dictionaries(dict, pat, dir, flags)
  1408.     char_u  *dict;
  1409.     char_u  *pat;
  1410.     int      dir;
  1411.     int      flags;
  1412. {
  1413.     char_u *ptr;
  1414.     char_u *buf;
  1415.     int at_start;
  1416.     FILE *fp;
  1417.     vim_regexp *prog;
  1418.     int add_r;
  1419.     char_u **files;
  1420.     int count;
  1421.     int i;
  1422.     buf = alloc(LSIZE);
  1423.     set_reg_ic(pat); /* set reg_ic according to p_ic, p_scs and pat */
  1424.     prog = vim_regcomp(pat, (int)p_magic);
  1425.     expand_interactively = TRUE;
  1426.     while (buf && prog && *dict != NUL && !got_int)
  1427.     {
  1428. /* copy one dictionary file name into buf */
  1429. if (flags == DICT_EXACT)
  1430. {
  1431.     count = 1;
  1432.     files = &dict;
  1433. }
  1434. else
  1435. {
  1436.     copy_option_part(&dict, buf, LSIZE, ",");
  1437.     if (expand_wildcards(1, &buf, &count, &files, EW_FILE|EW_DIR) != OK)
  1438. count = 0;
  1439. }
  1440. for (i = 0; i < count && !got_int; i++)
  1441. {
  1442.     fp = fopen((char *)files[i], "r"); /* open dictionary file */
  1443.     if (flags != DICT_EXACT)
  1444.     {
  1445. sprintf((char*)IObuff, "Scanning dictionary: %s",
  1446.     (char *)files[i]);
  1447. msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
  1448.     }
  1449.     if (fp != NULL)
  1450.     {
  1451. /*
  1452.  * Read dictionary file line by line.
  1453.  * Check each line for a match.
  1454.  */
  1455. while (!got_int && !vim_fgets(buf, LSIZE, fp))
  1456. {
  1457.     ptr = buf;
  1458.     at_start = TRUE;
  1459.     while (vim_regexec(prog, ptr, at_start))
  1460.     {
  1461. at_start = FALSE;
  1462. ptr = prog->startp[0];
  1463. while (vim_iswordc(*ptr))
  1464.     ++ptr;
  1465. add_r = add_completion_and_infercase(prog->startp[0],
  1466. (int)(ptr - prog->startp[0]), files[i], dir, 0);
  1467. if (add_r == OK)
  1468.     /* if dir was BACKWARD then honor it just once */
  1469.     dir = FORWARD;
  1470. else if (add_r == RET_ERROR)
  1471.     break;
  1472.     }
  1473.     line_breakcheck();
  1474. }
  1475. fclose(fp);
  1476.     }
  1477. }
  1478. if (flags != DICT_EXACT && count > 0)
  1479.     FreeWild(count, files);
  1480. if (flags)
  1481.     break;
  1482.     }
  1483.     expand_interactively = FALSE;
  1484.     vim_free(prog);
  1485.     vim_free(buf);
  1486. }
  1487. /*
  1488.  * Free the list of completions
  1489.  */
  1490.     static void
  1491. free_completions()
  1492. {
  1493.     struct Completion *match;
  1494.     if (first_match == NULL)
  1495. return;
  1496.     curr_match = first_match;
  1497.     do
  1498.     {
  1499. match = curr_match;
  1500. curr_match = curr_match->next;
  1501. vim_free(match->str);
  1502. /* several entries may use the same fname, free it just once. */
  1503. if (match->original & FREE_FNAME)
  1504.     vim_free(match->fname);
  1505. vim_free(match);
  1506.     } while (curr_match != NULL && curr_match != first_match);
  1507.     first_match = curr_match = NULL;
  1508. }
  1509.     static void
  1510. clear_insexp()
  1511. {
  1512.     continue_status = 0;
  1513.     started_completion = FALSE;
  1514.     complete_pat = NULL;
  1515.     save_sm = -1;
  1516. }
  1517. /*
  1518.  * Prepare for insert-expand, or stop it.
  1519.  */
  1520.     static int
  1521. ins_expand_pre(c)
  1522.     int     c;
  1523. {
  1524.     char_u *ptr;
  1525.     char_u *tmp_ptr;
  1526.     int temp;
  1527.     linenr_t lnum;
  1528.     int need_redraw = FALSE;
  1529.     if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET)
  1530.     {
  1531. /*
  1532.  * We have just entered ctrl-x mode and aren't quite sure which
  1533.  * ctrl-x mode it will be yet. Now we decide -- webb
  1534.  */
  1535. switch (c)
  1536. {
  1537.     case Ctrl('E'):
  1538.     case Ctrl('Y'):
  1539. ctrl_x_mode = CTRL_X_SCROLL;
  1540. if (State == INSERT)
  1541.     edit_submode = (char_u *)" (insert) Scroll (^E/^Y)";
  1542. else
  1543.     edit_submode = (char_u *)" (replace) Scroll (^E/^Y)";
  1544. showmode();
  1545. break;
  1546.     case Ctrl('L'):
  1547. ctrl_x_mode = CTRL_X_WHOLE_LINE;
  1548. break;
  1549.     case Ctrl('F'):
  1550. ctrl_x_mode = CTRL_X_FILES;
  1551. break;
  1552.     case Ctrl('K'):
  1553. ctrl_x_mode = CTRL_X_DICTIONARY;
  1554. break;
  1555.     case Ctrl(']'):
  1556. ctrl_x_mode = CTRL_X_TAGS;
  1557. break;
  1558. #ifdef FIND_IN_PATH
  1559.     case Ctrl('I'):
  1560.     case K_S_TAB:
  1561. ctrl_x_mode = CTRL_X_PATH_PATTERNS;
  1562. break;
  1563.     case Ctrl('D'):
  1564. ctrl_x_mode = CTRL_X_PATH_DEFINES;
  1565. break;
  1566. #endif
  1567.     case Ctrl('P'):
  1568.     case Ctrl('N'):
  1569. /* ^X^P means LOCAL expansion if nothing interrupted (eg we
  1570.  * just started ^X mode, or there were enough ^X's to cancel
  1571.  * the previous mode, say ^X^F^X^X^P or ^P^X^X^X^P, see below)
  1572.  * do normal expansion when interrupting a different mode (say
  1573.  * ^X^F^X^P or ^P^X^X^P, see below)
  1574.  * nothing changes if interrupting mode 0, (eg, the flag
  1575.  * doesn't change when going to ADDING mode  -- Acevedo */
  1576. if (!(continue_status & CONT_INTRPT))
  1577.     continue_status |= CONT_LOCAL;
  1578. else if (continue_mode)
  1579.     continue_status &=~CONT_LOCAL;
  1580. /* FALLTHROUGH */
  1581.     default:
  1582. /* if we have typed at least 2 ^X's... for modes != 0, we set
  1583.  * continue_status = 0 (eg, as if we had just started ^X mode)
  1584.  * for mode 0, we set continue_mode to an impossible value, in
  1585.  * both cases ^X^X can be used to restart the same mode
  1586.  * (avoiding ADDING mode).   Undocumented feature:
  1587.  * In a mode != 0 ^X^P and ^X^X^P start 'complete' and local
  1588.  * ^P expansions respectively. In mode 0 an extra ^X is
  1589.  * needed since ^X^P goes to ADDING mode  -- Acevedo */
  1590. if (c == Ctrl('X'))
  1591. {
  1592.     if (continue_mode)
  1593. continue_status = 0;
  1594.     else
  1595. continue_mode = CTRL_X_NOT_DEFINED_YET;
  1596. }
  1597. ctrl_x_mode = 0;
  1598. edit_submode = NULL;
  1599. showmode();
  1600. break;
  1601. }
  1602.     }
  1603.     else if (ctrl_x_mode)
  1604.     {
  1605. /* We we're already in ctrl-x mode, do we stay in it? */
  1606. if (!vim_is_ctrl_x_key(c))
  1607. {
  1608.     if (ctrl_x_mode == CTRL_X_SCROLL)
  1609. ctrl_x_mode = 0;
  1610.     else
  1611. ctrl_x_mode = CTRL_X_FINISHED;
  1612.     edit_submode = NULL;
  1613. }
  1614. showmode();
  1615.     }
  1616.     if (started_completion || ctrl_x_mode == CTRL_X_FINISHED)
  1617.     {
  1618. /* Show error message from attempted keyword completion (probably
  1619.  * 'Pattern not found') until another key is hit, then go back to
  1620.  * showing what mode we are in.
  1621.  */
  1622. showmode();
  1623. if ((ctrl_x_mode == 0 && c != Ctrl('N') && c != Ctrl('P')) ||
  1624.     ctrl_x_mode == CTRL_X_FINISHED)
  1625. {
  1626.     /* Get here when we have finished typing a sequence of ^N and
  1627.      * ^P or other completion characters in CTRL-X mode. Free up
  1628.      * memory that was used, and make sure we can redo the insert
  1629.      * -- webb.
  1630.      */
  1631.     if (curr_match != NULL)
  1632.     {
  1633. /*
  1634.  * If any of the original typed text has been changed,
  1635.  * eg when ignorecase is set, we must add back-spaces to
  1636.  * the redo buffer.  We add as few as necessary to delete
  1637.  * just the part of the original text that has changed
  1638.  * -- webb
  1639.  */
  1640. ptr = curr_match->str;
  1641. tmp_ptr = original_text;
  1642. while (*tmp_ptr && *tmp_ptr == *ptr)
  1643. {
  1644.     ++tmp_ptr;
  1645.     ++ptr;
  1646. }
  1647. for (temp = 0; tmp_ptr[temp]; ++temp)
  1648.     AppendCharToRedobuff(K_BS);
  1649. while (*ptr)
  1650. {
  1651.     /* Put a string of normal characters in the redo buffer */
  1652.     tmp_ptr = ptr;
  1653.     while (*ptr >= ' ' && *ptr < DEL)
  1654. ++ptr;
  1655.     /* Don't put '0' or '^' as last character, just in case a
  1656.      * CTRL-D is typed next */
  1657.     if (*ptr == NUL && (ptr[-1] == '0' || ptr[-1] == '^'))
  1658. --ptr;
  1659.     if (ptr > tmp_ptr)
  1660.     {
  1661. temp = *ptr;
  1662. *ptr = NUL;
  1663. AppendToRedobuff(tmp_ptr);
  1664. *ptr = temp;
  1665.     }
  1666.     if (*ptr)
  1667.     {
  1668. /* quote special chars with a CTRL-V */
  1669. AppendCharToRedobuff(Ctrl('V'));
  1670. AppendCharToRedobuff(*ptr);
  1671. /* CTRL-V '0' must be inserted as CTRL-V 048 */
  1672. if (*ptr++ == '0')
  1673.     AppendToRedobuff((char_u *)"48");
  1674.     }
  1675. }
  1676.     }
  1677.     /*
  1678.      * When completing whole lines: fix indent for 'cindent'.
  1679.      * Otherwise, break line if it's too long.
  1680.      */
  1681.     lnum = curwin->w_cursor.lnum;
  1682.     if (continue_mode == CTRL_X_WHOLE_LINE)
  1683.     {
  1684. #ifdef CINDENT
  1685. /* re-indent the current line */
  1686. if (curbuf->b_p_cin)
  1687.     fixthisline(get_c_indent);
  1688. #endif
  1689.     }
  1690.     else
  1691.     {
  1692. /* put the cursor on the last char, for 'tw' formatting */
  1693. curwin->w_cursor.col--;
  1694. insertchar(NUL, FALSE, -1, FALSE);
  1695. curwin->w_cursor.col++;
  1696.     }
  1697.     if (lnum != curwin->w_cursor.lnum)
  1698.     {
  1699. update_topline();
  1700. update_screen(NOT_VALID);
  1701.     }
  1702.     else
  1703. need_redraw = TRUE;
  1704.     vim_free(complete_pat);
  1705.     complete_pat = NULL;
  1706.     free_completions();
  1707.     started_completion = FALSE;
  1708.     ctrl_x_mode = 0;
  1709.     p_sm = save_sm;
  1710.     if (edit_submode != NULL)
  1711.     {
  1712. edit_submode = NULL;
  1713. showmode();
  1714.     }
  1715. }
  1716.     }
  1717.     /* reset continue_* if we left expansion-mode, if we stay they'll be
  1718.      * (re)set properly in ins_complete */
  1719.     if (!ctrl_x_mode && c != Ctrl('P') && c != Ctrl('N') && c != Ctrl('X'))
  1720. continue_status = continue_mode = 0;
  1721.     return need_redraw;
  1722. }
  1723. /*
  1724.  * Loops through the list of windows, loaded-buffers or non-loaded-buffers
  1725.  * (depending on flag) starting from buf and looking for a non-scanned
  1726.  * buffer (other than curbuf). curbuf is special, if it is called with
  1727.  * buf=curbuf then it has to be the first call for a given flag/expansion.
  1728.  *
  1729.  * Returns the buffer to scan, if any, otherwise returns curbuf -- Acevedo
  1730.  */
  1731.     static BUF*
  1732. next_buf(buf, flag)
  1733.     BUF *buf;
  1734.     int flag;
  1735. {
  1736.     static WIN *w;
  1737.     if (flag == 'w') /* just windows */
  1738.     {
  1739. if (buf == curbuf) /* first call for this flag/expansion */
  1740.     w = curwin;
  1741. while ((w = w->w_next ? w->w_next : firstwin) != curwin
  1742. && w->w_buffer->b_scanned)
  1743.     ;
  1744. buf = w->w_buffer;
  1745.     }
  1746.     else /* 'b' (just loaded buffers) or 'u' (just non-loaded buffers) */
  1747. while ((buf = buf->b_next ? buf->b_next : firstbuf) != curbuf
  1748. && ((buf->b_ml.ml_mfp == NULL) != (flag == 'u')
  1749.     || buf->b_scanned))
  1750.     ;
  1751.     return buf;
  1752. }
  1753. /*
  1754.  * Get the next expansion(s) for the text starting at the initial curbuf
  1755.  * position "ini" and in the direction dir.
  1756.  * Return the total of matches or -1 if still unknown -- Acevedo
  1757.  */
  1758.     static int
  1759. get_expansion(ini, dir)
  1760.     FPOS *ini;
  1761.     int dir;
  1762. {
  1763.     static FPOS first_match_pos;
  1764.     static FPOS last_match_pos;
  1765.     static char_u *e_cpt = (char_u *)""; /* curr. entry in 'complete' */
  1766.     static int done_info = 0; /* Found all matches in this dir. */
  1767.     static BUF *ins_buf = NULL;
  1768.     FPOS *pos;
  1769.     char_u **matches;
  1770.     int save_p_scs;
  1771.     int save_p_ws;
  1772.     int i;
  1773.     int temp;
  1774.     int type = ctrl_x_mode;
  1775.     char_u *ptr;
  1776.     char_u *tmp_ptr;
  1777.     char_u *dict = NULL;
  1778.     int dict_f = 0;
  1779.     struct Completion *old_match;
  1780.     if (!started_completion)
  1781.     {
  1782. for (ins_buf = firstbuf; ins_buf; ins_buf = ins_buf->b_next)
  1783.     ins_buf->b_scanned = 0;
  1784. done_info = 0;
  1785. ins_buf = curbuf;
  1786. e_cpt = continue_status & CONT_LOCAL ? (char_u *)"." : curbuf->b_p_cpt;
  1787. last_match_pos = first_match_pos = *ini;
  1788.     }
  1789.     old_match = curr_match; /* remember the last current match */
  1790.     pos = (dir == FORWARD) ? &last_match_pos : &first_match_pos;
  1791.     /* For ^N/^P loop over all the flags/windows/buffers in 'complete' */
  1792.     for (;;)
  1793.     {
  1794. temp = FAIL;
  1795. /* in mode 0 pick a new entry from e_cpt if started_completion is off,
  1796.  * or if done_info says this entry is done  -- Acevedo */
  1797. if (!ctrl_x_mode && (!started_completion || done_info == 6))
  1798. {
  1799.     done_info = 0;
  1800.     while (*e_cpt == ',' || *e_cpt == ' ')
  1801. e_cpt++;
  1802.     if (*e_cpt == '.' && !curbuf->b_scanned)
  1803.     {
  1804. ins_buf = curbuf;
  1805. first_match_pos = *ini;
  1806. /* So that ^N can match word immediately after cursor */
  1807. if (ctrl_x_mode == 0)
  1808.     dec(&first_match_pos);
  1809. last_match_pos = first_match_pos;
  1810. type = 0;
  1811.     }
  1812.     else if (vim_strchr((char_u *)"buw", *e_cpt) != NULL
  1813.     && (ins_buf = next_buf(ins_buf, *e_cpt)) != curbuf)
  1814.     {
  1815. if (*e_cpt != 'u')
  1816. {
  1817.     started_completion = TRUE;
  1818.     first_match_pos.col = last_match_pos.col = 0;
  1819.     first_match_pos.lnum = ins_buf->b_ml.ml_line_count + 1;
  1820.     last_match_pos.lnum = 0;
  1821.     type = 0;
  1822. }
  1823. else
  1824. {
  1825.     done_info = 6;
  1826.     if (ins_buf->b_fname == NULL)
  1827. continue;
  1828.     type = CTRL_X_DICTIONARY;
  1829.     dict = ins_buf->b_fname;
  1830.     dict_f = DICT_EXACT;
  1831. }
  1832. sprintf((char*)IObuff, "Scanning: %s",
  1833. ins_buf->b_sfname == NULL ? "No File"
  1834.   : (char *)ins_buf->b_sfname);
  1835. msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
  1836.     }
  1837.     else if (*e_cpt == NUL)
  1838. break;
  1839.     else
  1840.     {
  1841. if (*e_cpt == 'k')
  1842. {
  1843.     type = CTRL_X_DICTIONARY;
  1844.     if (*++e_cpt != ',' && *e_cpt != NUL)
  1845.     {
  1846. dict = e_cpt;
  1847. dict_f = DICT_FIRST;
  1848.     }
  1849. }
  1850. #ifdef FIND_IN_PATH
  1851. else if (*e_cpt == 'i')
  1852.     type = CTRL_X_PATH_PATTERNS;
  1853. #endif
  1854. else if (*e_cpt == ']' || *e_cpt == 't')
  1855. {
  1856.     type = CTRL_X_TAGS;
  1857.     sprintf((char*)IObuff, "Scanning tags.");
  1858.     msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
  1859. }
  1860. else
  1861.     type = -1;
  1862. /* in any case e_cpt is advanced to the next entry */
  1863. (void)copy_option_part(&e_cpt, IObuff, IOSIZE, ",");
  1864. done_info = 6;
  1865. if (type == -1)
  1866.     continue;
  1867.     }
  1868. }
  1869. switch (type)
  1870. {
  1871. case -1:
  1872.     break;
  1873. #ifdef FIND_IN_PATH
  1874. case CTRL_X_PATH_PATTERNS:
  1875. case CTRL_X_PATH_DEFINES:
  1876.     find_pattern_in_path(complete_pat, dir,
  1877.  (int)STRLEN(complete_pat), FALSE, FALSE,
  1878.  (type == CTRL_X_PATH_DEFINES
  1879.   && !(continue_status & CONT_SOL))
  1880.  ? FIND_DEFINE : FIND_ANY, 1L, ACTION_EXPAND,
  1881.  (linenr_t)1, (linenr_t)MAXLNUM);
  1882.     break;
  1883. #endif
  1884. case CTRL_X_DICTIONARY:
  1885.     complete_dictionaries(dict ? dict : p_dict, complete_pat, dir,
  1886.   dict ? dict_f : 0);
  1887.     dict = NULL;
  1888.     break;
  1889. case CTRL_X_TAGS:
  1890.     /* set reg_ic according to p_ic, p_scs and pat */
  1891.     set_reg_ic(complete_pat);
  1892.     if (find_tags(complete_pat, &temp, &matches,
  1893.     TAG_REGEXP | TAG_NAMES | (ctrl_x_mode ? TAG_VERBOSE : 0),
  1894.     MAXCOL) == OK && temp > 0)
  1895.     {
  1896. int add_r = OK;
  1897. int ldir = dir;
  1898. for (i = 0; i < temp && add_r != RET_ERROR; i++)
  1899.     if ((add_r = add_completion(matches[i], -1, NULL, ldir, 0))
  1900.     == OK)
  1901. /* if dir was BACKWARD then honor it just once */
  1902. ldir = FORWARD;
  1903. FreeWild(temp, matches);
  1904.     }
  1905.     break;
  1906. case CTRL_X_FILES:
  1907.     expand_interactively = TRUE;
  1908.     if (expand_wildcards(1, &complete_pat, &temp, &matches,
  1909. EW_FILE|EW_DIR) == OK)
  1910.     {
  1911. int add_r = OK;
  1912. int ldir = dir;
  1913. /* May change home directory back to "~". */
  1914. tilde_replace(complete_pat, temp, matches);
  1915. for (i = 0; i < temp && add_r != RET_ERROR; i++)
  1916.     if ((add_r = add_completion(matches[i], -1, NULL, ldir, 0))
  1917.     == OK)
  1918. /* if dir was BACKWARD then honor it just once */
  1919. ldir = FORWARD;
  1920. FreeWild(temp, matches);
  1921.     }
  1922.     expand_interactively = FALSE;
  1923.     break;
  1924. default: /* normal ^P/^N and ^X^L */
  1925.     /*
  1926.      * If 'infercase' is set, don't use 'smartcase' here
  1927.      */
  1928.     save_p_scs = p_scs;
  1929.     if (ins_buf->b_p_inf)
  1930. p_scs = FALSE;
  1931.     /* buffers other than curbuf are scanned from the beginning or the
  1932.      * end but never from the middle, thus setting nowrapscan in this
  1933.      * buffers is a good idea -- Acevedo */
  1934.     save_p_ws = p_ws;
  1935.     if (ins_buf != curbuf)
  1936. p_ws = FALSE;
  1937.     for (;;)
  1938.     {
  1939. int reuse = 0;
  1940. /* ctrl_x_mode == CTRL_X_WHOLE_LINE || word-wise search that has
  1941.  * added a word that was at the beginning of the line */
  1942. if ( ctrl_x_mode == CTRL_X_WHOLE_LINE
  1943. || (continue_status & CONT_SOL))
  1944.     temp = search_for_exact_line(ins_buf, pos,
  1945.    dir, complete_pat);
  1946. else
  1947.     temp = searchit(ins_buf, pos, dir, complete_pat, 1L,
  1948.     SEARCH_KEEP + SEARCH_NFMSG, RE_LAST);
  1949. if (!started_completion)
  1950. {
  1951.     /* set started_completion even on fail */
  1952.     started_completion = TRUE;
  1953.     first_match_pos = *pos;
  1954.     last_match_pos = *pos;
  1955. }
  1956. else if (first_match_pos.lnum == last_match_pos.lnum
  1957.  && first_match_pos.col == last_match_pos.col)
  1958.     temp = FAIL;
  1959. if (   temp == FAIL && ins_buf == curbuf
  1960.        && (done_info |= p_ws ? 6 : dir + 3) < 6)
  1961.     /* With nowrapscan, we haven't finished looking in the
  1962.      * other direction yet -- webb */
  1963.     temp = -OK;
  1964. if (temp != OK)
  1965.     break;
  1966. /* when ADDING, the text before the cursor matches, skip it */
  1967. if ( (continue_status & CONT_ADDING) && ins_buf == curbuf
  1968. && ini->lnum == pos->lnum
  1969. && ini->col  == pos->col)
  1970.     continue;
  1971. ptr = ml_get_buf(ins_buf, pos->lnum, FALSE) + pos->col;
  1972. if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
  1973. {
  1974.     if (continue_status & CONT_ADDING)
  1975.     {
  1976. if (pos->lnum >= ins_buf->b_ml.ml_line_count)
  1977.     continue;
  1978. ptr = ml_get_buf(ins_buf, pos->lnum + 1, FALSE);
  1979. if (!p_paste)
  1980.     ptr = skipwhite(ptr);
  1981.     }
  1982.     temp = STRLEN(ptr);
  1983. }
  1984. else
  1985. {
  1986.     tmp_ptr = ptr;
  1987.     if (continue_status & CONT_ADDING)
  1988.     {
  1989. tmp_ptr += completion_length;
  1990. if (vim_iswordc(*tmp_ptr))
  1991.     continue;
  1992. while (*tmp_ptr && !vim_iswordc(*tmp_ptr++))
  1993.     ;
  1994.     }
  1995.     while (vim_iswordc(*tmp_ptr))
  1996. tmp_ptr++;
  1997.     temp = tmp_ptr - ptr;
  1998.     if ((continue_status & CONT_ADDING)
  1999. && temp == completion_length)
  2000.     {
  2001. if (pos->lnum < ins_buf->b_ml.ml_line_count)
  2002. {
  2003.     /* Try next line, if any. the new word will be
  2004.      * "join" as if the normal command "J" was used.
  2005.      * IOSIZE is always greater than
  2006.      * completion_length, so the next STRNCPY always
  2007.      * works -- Acevedo */
  2008.     STRNCPY(IObuff, ptr, temp);
  2009.     ptr = ml_get_buf(ins_buf, pos->lnum + 1, FALSE);
  2010.     tmp_ptr = ptr = skipwhite(ptr);
  2011.     while (*tmp_ptr && !vim_iswordc(*tmp_ptr++))
  2012. ;
  2013.     while (vim_iswordc(*tmp_ptr))
  2014. tmp_ptr++;
  2015.     if (tmp_ptr > ptr)
  2016.     {
  2017. if (*ptr != ')' && IObuff[temp-1] != TAB)
  2018. {
  2019.     if (IObuff[temp-1] != ' ')
  2020. IObuff[temp++] = ' ';
  2021.     /* IObuf =~ "k.* ", thus temp >= 2 */
  2022.     if (p_js
  2023. && (IObuff[temp-2] == '.'
  2024.     || (vim_strchr(p_cpo, CPO_JOINSP)
  2025.        == NULL
  2026. && (IObuff[temp-2] == '?'
  2027.     || IObuff[temp-2] == '!'))))
  2028. IObuff[temp++] = ' ';
  2029. }
  2030. /* copy as much as posible of the new word */
  2031. if (tmp_ptr - ptr >= IOSIZE - temp)
  2032.     tmp_ptr = ptr + IOSIZE - temp - 1;
  2033. STRNCPY(IObuff + temp, ptr, tmp_ptr - ptr);
  2034. temp += tmp_ptr - ptr;
  2035. reuse |= CONT_S_IPOS;
  2036.     }
  2037.     IObuff[temp] = NUL;
  2038.     ptr = IObuff;
  2039. }
  2040. if (temp == completion_length)
  2041.     continue;
  2042.     }
  2043. }
  2044. if (add_completion_and_infercase(ptr, temp, ins_buf == curbuf ?
  2045. NULL : ins_buf->b_sfname, dir, reuse) != FAIL)
  2046. {
  2047.     temp = OK;
  2048.     break;
  2049. }
  2050.     }
  2051.     p_scs = save_p_scs;
  2052.     p_ws = save_p_ws;
  2053. }
  2054. /* check if curr_match has changed, (e.g. other type of expansion
  2055.  * added somenthing) */
  2056. if (curr_match != old_match)
  2057.     temp = OK;
  2058. /* break the loop for specialized modes (use 'complete' just for the
  2059.  * generic ctrl_x_mode == 0) and when temp != FAIL */
  2060. if (ctrl_x_mode || temp)
  2061.     break;
  2062. if (type == 0 || type == CTRL_X_PATH_PATTERNS)
  2063.     ins_buf->b_scanned = TRUE;
  2064. started_completion = FALSE;
  2065.     }
  2066.     started_completion = TRUE;
  2067.     i = -1; /* total of matches, unknown */
  2068.     if (temp == FAIL || (ctrl_x_mode != 0 && ctrl_x_mode != CTRL_X_WHOLE_LINE))
  2069. i = make_cyclic();
  2070.     else if (temp == -OK && (curr_match->original & ORIGINAL_TEXT))
  2071.     {
  2072. edit_submode_extra = (continue_status & CONT_ADDING)
  2073.     && completion_length > 1
  2074. ? (dir == FORWARD ? e_hitend_f : e_hitend_b)
  2075. : (dir == FORWARD ? e_patnotf_f : e_patnotf_b);
  2076. edit_submode_highl = HLF_E;
  2077.     }
  2078.     /* If several matches were added (FORWARD) or the search failed and has
  2079.      * just been made cyclic then we have to move curr_match to the next or
  2080.      * previous entry (if any, when search failed with 'nows') -- Acevedo */
  2081.     curr_match = dir == FORWARD ? old_match->next : old_match->prev;
  2082.     if (curr_match == NULL)
  2083. curr_match = old_match;
  2084.     return i;
  2085. }
  2086.     static int
  2087. ins_complete(c)
  2088.     int     c;
  2089. {
  2090.     int     complete_direction;
  2091.     char_u     *ptr;
  2092.     char_u     *tmp_ptr = NULL; /* init for gcc */
  2093.     static colnr_t  complete_col = 0; /* init for gcc */
  2094.     int     temp = 0;
  2095.     int     i;
  2096.     int     cc;
  2097.     static FPOS     initial_pos;
  2098.     if (c == Ctrl('P') || c == Ctrl('L'))
  2099. complete_direction = BACKWARD;
  2100.     else
  2101. complete_direction = FORWARD;
  2102.     if (!started_completion)
  2103.     {
  2104. /* First time we hit ^N or ^P (in a row, I mean) */
  2105. /* Turn off 'sm' so we don't show matches with ^X^L */
  2106. save_sm = p_sm;
  2107. p_sm = FALSE;
  2108. did_ai = FALSE;
  2109. #ifdef SMARTINDENT
  2110. did_si = FALSE;
  2111. can_si = FALSE;
  2112. can_si_back = FALSE;
  2113. #endif
  2114. stop_arrow();
  2115. ptr = ml_get(curwin->w_cursor.lnum);
  2116. complete_col = curwin->w_cursor.col;
  2117. /* if this same ctrl_x_mode has been interrupted use the text from
  2118.  * initial_pos to the cursor as a pattern to add a new word instead of
  2119.  * expand the one before the cursor, in word-wise if "initial_pos" is
  2120.  * not in the same line as the cursor then fix it (the line has been
  2121.  * split because it was longer than 'tw').  if SOL is set then skip
  2122.  * the previous pattern, a word at the beginning of the line has been
  2123.  * inserted, we'll look for that  -- Acevedo. */
  2124. if ((continue_status & CONT_INTRPT) && continue_mode == ctrl_x_mode)
  2125. { /* it is a continued search */
  2126.     continue_status &= ~CONT_INTRPT; /* remove INTRPT */
  2127.     if (ctrl_x_mode == 0 || ctrl_x_mode == CTRL_X_PATH_PATTERNS
  2128. || ctrl_x_mode == CTRL_X_PATH_DEFINES)
  2129.     {
  2130. if (initial_pos.lnum != curwin->w_cursor.lnum)
  2131. {
  2132.     /* line (probably) wrapped, set initial_pos to the first
  2133.      * non_blank in the line, if it is not a wordchar include
  2134.      * it to get a better pattern, but then we don't want the
  2135.      * "\<" prefix, check it bellow */
  2136.     tmp_ptr = skipwhite(ptr);
  2137.     initial_pos.col = tmp_ptr - ptr;
  2138.     initial_pos.lnum = curwin->w_cursor.lnum;
  2139.     continue_status &= ~CONT_SOL;    /* clear SOL if present */
  2140. }
  2141. else
  2142. {
  2143.     /* S_IPOS was set when we inserted a word that was at the
  2144.      * beginning of the line, which means that we'll go to SOL
  2145.      * mode but first we need to redefine initial_pos */
  2146.     if (continue_status & CONT_S_IPOS)
  2147.     {
  2148. continue_status |= CONT_SOL;
  2149. initial_pos.col = skipwhite(ptr + completion_length +
  2150.     initial_pos.col) - ptr;
  2151.     }
  2152.     tmp_ptr = ptr + initial_pos.col;
  2153. }
  2154. temp = curwin->w_cursor.col - (tmp_ptr-ptr);
  2155. /* IObuf is used to add a "word from the next line" would we
  2156.  * have enough space?  just being paranoic */
  2157. #define MIN_SPACE 75
  2158. if (temp > (IOSIZE - MIN_SPACE))
  2159. {
  2160.     continue_status &= ~CONT_SOL;
  2161.     temp = (IOSIZE - MIN_SPACE);
  2162.     tmp_ptr = curwin->w_cursor.col - temp + ptr;
  2163. }
  2164. continue_status |= CONT_ADDING | CONT_N_ADDS;
  2165. if (temp < 1)
  2166.     continue_status &= CONT_LOCAL;
  2167.     }
  2168.     else if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
  2169. continue_status = CONT_ADDING | CONT_N_ADDS;
  2170.     else
  2171. continue_status = 0;
  2172. }
  2173. else
  2174.     continue_status &= CONT_LOCAL;
  2175. if (!(continue_status & CONT_ADDING)) /* normal expansion */
  2176. {
  2177.     continue_mode = ctrl_x_mode;
  2178.     if (ctrl_x_mode) /* Remove LOCAL iff ctrl_x_mode != 0 */
  2179. continue_status = 0;
  2180.     continue_status |= CONT_N_ADDS;
  2181.     initial_pos = curwin->w_cursor;
  2182.     temp = (int)complete_col;
  2183.     tmp_ptr = ptr;
  2184. }
  2185. /* Work out completion pattern and original text -- webb */
  2186. if (ctrl_x_mode == 0 || (ctrl_x_mode & CTRL_X_WANT_IDENT))
  2187. {
  2188.     if (       (continue_status & CONT_SOL)
  2189.     || ctrl_x_mode == CTRL_X_PATH_DEFINES)
  2190.     {
  2191. if (!(continue_status & CONT_ADDING))
  2192. {
  2193.     while (--temp >= 0 && vim_isIDc(ptr[temp]))
  2194. ;
  2195.     tmp_ptr += ++temp;
  2196.     temp = complete_col - temp;
  2197. }
  2198. complete_pat = vim_strnsave(tmp_ptr, temp);
  2199. if (complete_pat == NULL)
  2200.     return FALSE;
  2201. if (p_ic)
  2202.     for (i = 0; i < temp; i++)
  2203. complete_pat[i] = TO_LOWER(complete_pat[i]);
  2204.     }
  2205.     else if (continue_status & CONT_ADDING)
  2206.     {
  2207. char_u     *prefix = (char_u *)"\<";
  2208. /* we need 3 extra chars, 1 for the NUL and
  2209.  * 2 >= strlen(prefix) -- Acevedo */
  2210. complete_pat = alloc(quote_meta(NULL, tmp_ptr, temp) + 3);
  2211. if (complete_pat == NULL)
  2212.     return FALSE;
  2213. if (!vim_iswordc(*tmp_ptr) ||
  2214. (tmp_ptr > ptr && vim_iswordc(*(tmp_ptr-1))))
  2215.     prefix = (char_u *)"";
  2216. STRCPY((char *)complete_pat, prefix);
  2217. (void)quote_meta(complete_pat + STRLEN(prefix), tmp_ptr, temp);
  2218.     }
  2219.     else if (--temp < 0 || !vim_iswordc(ptr[temp]))
  2220.     {
  2221. /* Match any word of at least two chars */
  2222. complete_pat = vim_strsave((char_u *)"\<\k\k");
  2223. if (complete_pat == NULL)
  2224.     return FALSE;
  2225. tmp_ptr += complete_col;
  2226. temp = 0;
  2227.     }
  2228.     else
  2229.     {
  2230. while (--temp >= 0 && vim_iswordc(ptr[temp]))
  2231.     ;
  2232. tmp_ptr += ++temp;
  2233. if ((temp = (int)complete_col - temp) == 1)
  2234. {
  2235.     /* Only match word with at least two chars -- webb
  2236.      * there's no need to call quote_meta,
  2237.      * alloc(7) is enough  -- Acevedo
  2238.      */
  2239.     complete_pat = alloc(7);
  2240.     if (complete_pat == NULL)
  2241. return FALSE;
  2242.     STRCPY((char *)complete_pat, "\<");
  2243.     (void)quote_meta(complete_pat + 2, tmp_ptr, 1);
  2244.     STRCAT((char *)complete_pat, "\k");
  2245. }
  2246. else
  2247. {
  2248.     complete_pat = alloc(quote_meta(NULL, tmp_ptr, temp) + 3);
  2249.     if (complete_pat == NULL)
  2250. return FALSE;
  2251.     STRCPY((char *)complete_pat, "\<");
  2252.     (void)quote_meta(complete_pat + 2, tmp_ptr, temp);
  2253. }
  2254.     }
  2255. }
  2256. else if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
  2257. {
  2258.     tmp_ptr = skipwhite(ptr);
  2259.     temp = (int)complete_col - (tmp_ptr - ptr);
  2260.     complete_pat = vim_strnsave(tmp_ptr, temp);
  2261.     if (complete_pat == NULL)
  2262. return FALSE;
  2263.     if (p_ic)
  2264. for (i = 0; i < temp; i ++)
  2265.     complete_pat[i] = TO_LOWER(complete_pat[i]);
  2266. }
  2267. else if (ctrl_x_mode == CTRL_X_FILES)
  2268. {
  2269.     while (--temp >= 0 && vim_isfilec(ptr[temp]))
  2270. ;
  2271.     tmp_ptr += ++temp;
  2272.     temp = (int)complete_col - temp;
  2273.     complete_pat = addstar(tmp_ptr, temp);
  2274.     if (complete_pat == NULL)
  2275. return FALSE;
  2276. }
  2277. complete_col = tmp_ptr - ptr;
  2278. if (continue_status & CONT_ADDING)
  2279. {
  2280.     if (continue_status & CONT_LOCAL)
  2281. edit_submode = (char_u *)ctrl_x_msgs[2];
  2282.     else
  2283. edit_submode = (char_u *)ctrl_x_msgs[ctrl_x_mode & 15];
  2284.     if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
  2285.     {
  2286. /* Insert a new line, keep indentation but ignore 'comments' */
  2287. char_u *old = curbuf->b_p_com;
  2288. initial_pos.lnum = curwin->w_cursor.lnum;
  2289. initial_pos.col = complete_col;
  2290. curbuf->b_p_com = (char_u *)"";
  2291. ins_eol('r');
  2292. curbuf->b_p_com = old;
  2293. tmp_ptr = (char_u *)"";
  2294. temp = 0;
  2295. complete_col = curwin->w_cursor.col;
  2296.     }
  2297. }
  2298. else
  2299. {
  2300.     /* msg. without the " Adding" part. */
  2301.     if (continue_status & CONT_LOCAL)
  2302. edit_submode = (char_u *)ctrl_x_msgs[2] + C_X_SKIP;
  2303.     else
  2304. edit_submode = (char_u *)ctrl_x_msgs[ctrl_x_mode & 15] + C_X_SKIP;
  2305.     initial_pos.col = complete_col;
  2306. }
  2307. completion_length = temp;
  2308. /* Always "add completion" for the "original text", it uses
  2309.  * "original_text" not a copy -- Acevedo */
  2310. if ((original_text = vim_strnsave(tmp_ptr, temp)) == NULL
  2311.     || add_completion(original_text, -1, NULL, 0, ORIGINAL_TEXT) != OK)
  2312. {
  2313.     vim_free(complete_pat);
  2314.     complete_pat = NULL;
  2315.     return FALSE;
  2316. }
  2317. /* showmode might reset the internal line pointers, so it must
  2318.  * be called before ptr = ml_get, or when this address is no
  2319.  * longer needed.  -- Acevedo.
  2320.  */
  2321. edit_submode_extra = (char_u *)"-- Searching...";
  2322. edit_submode_highl = HLF_COUNT;
  2323. showmode();
  2324. edit_submode_extra = NULL;
  2325. out_flush();
  2326.     }
  2327.     /*
  2328.      * In insert mode: Delete the typed part.
  2329.      * In replace mode: Put the old characters back, if any.
  2330.      */
  2331.     i = complete_col + (continue_status & CONT_ADDING ? completion_length : 0);
  2332.     while ((int)curwin->w_cursor.col > i)
  2333.     {
  2334. curwin->w_cursor.col--;
  2335. if (State == REPLACE)
  2336. {
  2337.     /*
  2338.      * First character popped from the replace stack replaces a
  2339.      * character that's already there. Further popped characters need
  2340.      * to be inserted.
  2341.      */
  2342.     if ((cc = replace_pop()) > 0)
  2343.     {
  2344. pchar(curwin->w_cursor, cc);
  2345. replace_pop_ins();
  2346.     }
  2347. }
  2348. else
  2349.     (void)del_char(FALSE);
  2350.     }
  2351.     changed_cline_bef_curs();
  2352.     if (complete_direction == FORWARD && curr_match->next != NULL)
  2353. curr_match = curr_match->next;
  2354.     else if (complete_direction == BACKWARD && curr_match->prev != NULL)
  2355. curr_match = curr_match->prev;
  2356.     else
  2357. temp = get_expansion(&initial_pos, complete_direction);
  2358.     /* we found no match if the list has only the original_text-entry */
  2359.     if (first_match == first_match->next)
  2360.     {
  2361. edit_submode_extra = (continue_status & CONT_ADDING)
  2362.       && completion_length > 1 ? e_hitend : e_patnotf;
  2363. edit_submode_highl = HLF_E;
  2364. /* remove N_ADDS flag, so next ^X<> won't try to go to ADDING mode,
  2365.  * because we couldn't expand anything at first place, but if we used
  2366.  * ^P, ^N, ^X^I or ^X^D we might want to add-expand a single-char-word
  2367.  * (such as M in M'exico) if not tried already.  -- Acevedo */
  2368. if (    completion_length > 1
  2369. || (continue_status & CONT_ADDING)
  2370. || (ctrl_x_mode != 0
  2371.     && ctrl_x_mode != CTRL_X_PATH_PATTERNS
  2372.     && ctrl_x_mode != CTRL_X_PATH_DEFINES))
  2373.     continue_status &= ~CONT_N_ADDS;
  2374.     }
  2375.     /* eat the ESC to avoid leaving insert mode */
  2376.     if (got_int && !global_busy)
  2377.     {
  2378. (void)vgetc();
  2379. got_int = FALSE;
  2380.     }
  2381.     if (curr_match->original & CONT_S_IPOS)
  2382. continue_status |= CONT_S_IPOS;
  2383.     else
  2384. continue_status &= ~CONT_S_IPOS;
  2385.     if (edit_submode_extra == NULL)
  2386.     {
  2387. if (curr_match->original & ORIGINAL_TEXT)
  2388. {
  2389.     edit_submode_extra = (char_u *)"Back at original";
  2390.     edit_submode_highl = HLF_W;
  2391. }
  2392. else if (continue_status & CONT_S_IPOS)
  2393. {
  2394.     edit_submode_extra = (char_u *)"Word from other line";
  2395.     edit_submode_highl = HLF_COUNT;
  2396. }
  2397. else if (curr_match->next == curr_match->prev)
  2398. {
  2399.     edit_submode_extra = (char_u *)"The only match";
  2400.     edit_submode_highl = HLF_COUNT;
  2401. }
  2402.     }
  2403.     /*