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

编辑器/阅读器

开发平台:

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.  * ex_getln.c: Functions for entering and editing an Ex command line.
  10.  */
  11. #include "vim.h"
  12. /*
  13.  * Variables shared between getcmdline(), redrawcmdline() and others.
  14.  * These need to be saved when using CTRL-R |, that's why they are in a
  15.  * structure.
  16.  */
  17. struct cmdline_info
  18. {
  19.     char_u *cmdbuff; /* pointer to command line buffer */
  20.     int cmdbufflen; /* length of cmdbuff */
  21.     int cmdlen; /* number of chars on command line */
  22.     int cmdpos; /* current cursor position */
  23.     int cmdspos; /* cursor column on screen */
  24.     int cmdfirstc; /* ':', '/', '?', '=' or NUL */
  25.     int cmdindent; /* number of spaces before cmdline */
  26.     char_u *cmdprompt; /* message in front of cmdline */
  27.     int cmdattr; /* attributes for prompt */
  28.     int overstrike; /* Typing mode on the command line.  Shared by
  29.    getcmdline() and put_on_cmdline(). */
  30. };
  31. static struct cmdline_info ccline; /* current cmdline_info */
  32. static int cmd_numfiles = -1; /* number of files found by
  33.     file name completion */
  34. static char_u **(history[HIST_COUNT]) = {NULL, NULL, NULL, NULL};
  35. static int hisidx[HIST_COUNT] = {-1, -1, -1, -1};  /* last entered entry */
  36. static int hislen = 0; /* actual length of history tables */
  37. #ifdef RIGHTLEFT
  38. static int cmd_hkmap = 0;     /* Hebrew mapping during command line */
  39. #endif
  40. #ifdef FKMAP
  41. static int     cmd_fkmap = 0; /* Farsi mapping during command line */
  42. #endif
  43. static int hist_char2type __ARGS((int c));
  44. static void init_history __ARGS((void));
  45. static int in_history __ARGS((int, char_u *, int));
  46. static void set_cmdspos __ARGS((void));
  47. static void alloc_cmdbuff __ARGS((int len));
  48. static int realloc_cmdbuff __ARGS((int len));
  49. static void putcmdline __ARGS((int));
  50. static void redrawcmdprompt __ARGS((void));
  51. static void redrawcmd __ARGS((void));
  52. static void cursorcmd __ARGS((void));
  53. static int ccheck_abbr __ARGS((int));
  54. static int nextwild __ARGS((int, int));
  55. static int showmatches __ARGS((void));
  56. static void set_expand_context __ARGS((void));
  57. static int ExpandFromContext __ARGS((char_u *, int *, char_u ***, int, int));
  58. /*
  59.  * getcmdline() - accept a command line starting with firstc.
  60.  *
  61.  * firstc == ':'     get ":" command line.
  62.  * firstc == '/' or '?'     get search pattern
  63.  * firstc == '='     get expression
  64.  * firstc == '@'     get text for input() function
  65.  * firstc == NUL     get text for :insert command
  66.  *
  67.  * The line is collected in ccline.cmdbuff, which is reallocated to fit the
  68.  * command line.
  69.  *
  70.  * Careful: getcmdline() can be called recursively!
  71.  *
  72.  * Return pointer to allocated string if there is a commandline, NULL
  73.  * otherwise.
  74.  */
  75.     char_u *
  76. getcmdline(firstc, count, indent)
  77.     int firstc;
  78.     long count; /* only used for incremental search */
  79.     int indent; /* indent for inside conditionals */
  80. {
  81.     int c;
  82. #ifdef DIGRAPHS
  83.     int cc;
  84. #endif
  85.     int i;
  86.     int j;
  87.     char_u *p;
  88.     int hiscnt; /* current history line in use */
  89.     char_u *lookfor = NULL; /* string to match */
  90.     int gotesc = FALSE; /* TRUE when <ESC> just typed */
  91.     int do_abbr; /* when TRUE check for abbr. */
  92.     int histype; /* history type to be used */
  93. #ifdef EXTRA_SEARCH
  94.     FPOS old_cursor;
  95.     colnr_t old_curswant;
  96.     colnr_t old_leftcol;
  97.     linenr_t old_topline;
  98.     linenr_t old_botline;
  99.     int did_incsearch = FALSE;
  100.     int incsearch_postponed = FALSE;
  101. #endif
  102.     int did_wild_list = FALSE; /* did wild_list() recently */
  103.     int wim_index = 0; /* index in wim_flags[] */
  104.     int res;
  105.     int save_msg_scroll = msg_scroll;
  106.     int save_State = State; /* remember State when called */
  107.     int some_key_typed = FALSE; /* one of the keys was typed */
  108. #ifdef USE_MOUSE
  109.     /* mouse drag and release events are ignored, unless they are
  110.      * preceded with a mouse down event */
  111.     int ignore_drag_release = TRUE;
  112. #endif
  113. #ifdef USE_SNIFF
  114.     want_sniff_request = 0;
  115. #endif
  116.     ccline.overstrike = FALSE;     /* always start in insert mode */
  117. #ifdef EXTRA_SEARCH
  118.     old_cursor = curwin->w_cursor;     /* needs to be restored later */
  119.     old_curswant = curwin->w_curswant;
  120.     old_leftcol = curwin->w_leftcol;
  121.     old_topline = curwin->w_topline;
  122.     old_botline = curwin->w_botline;
  123. #endif
  124.     /*
  125.      * set some variables for redrawcmd()
  126.      */
  127.     ccline.cmdfirstc = (firstc == '@' ? 0 : firstc);
  128.     ccline.cmdindent = indent;
  129.     alloc_cmdbuff(exmode_active ? 250 : 0); /* alloc initial ccline.cmdbuff */
  130.     if (ccline.cmdbuff == NULL)
  131. return NULL;     /* out of memory */
  132.     ccline.cmdlen = ccline.cmdpos = 0;
  133.     redir_off = TRUE; /* don't redirect the typed command */
  134.     i = msg_scrolled;
  135.     msg_scrolled = 0; /* avoid wait_return message */
  136.     gotocmdline(TRUE);
  137.     msg_scrolled += i;
  138.     redrawcmdprompt(); /* draw prompt or indent */
  139.     set_cmdspos();
  140.     /*
  141.      * Avoid scrolling when called by a recursive do_cmdline(), e.g. when doing
  142.      * ":@0" when register 0 doesn't contain a CR.
  143.      */
  144.     msg_scroll = FALSE;
  145.     State = CMDLINE;
  146. #ifdef USE_MOUSE
  147.     setmouse();
  148. #endif
  149.     init_history();
  150.     hiscnt = hislen; /* set hiscnt to impossible history value */
  151.     histype = hist_char2type(firstc);
  152. #ifdef DIGRAPHS
  153.     do_digraph(-1); /* init digraph typahead */
  154. #endif
  155.     /* collect the command string, handling editing keys */
  156.     for (;;)
  157.     {
  158. #ifdef USE_GUI_WIN32
  159. dont_scroll = FALSE; /* allow scrolling here */
  160. #endif
  161. quit_more = FALSE; /* reset after CTRL-D which had a more-prompt */
  162. cursorcmd(); /* set the cursor on the right spot */
  163. c = vgetc();
  164. if (KeyTyped)
  165. {
  166.     some_key_typed = TRUE;
  167. #ifdef RIGHTLEFT
  168.     if (cmd_hkmap)
  169. c = hkmap(c);
  170. # ifdef FKMAP
  171.     if (cmd_fkmap)
  172. c = cmdl_fkmap(c);
  173. # endif
  174. #endif
  175. }
  176. /*
  177.  * Ignore got_int when CTRL-C was typed here.
  178.  * Don't ignore it in :global, we really need to break then, e.g., for
  179.  * ":g/pat/normal /pat" (without the <CR>).
  180.  * Don't ignore it for the input() function.
  181.  */
  182. if ((c == Ctrl('C')
  183. #ifdef UNIX
  184. || c == intr_char
  185. #endif
  186. )
  187. #ifdef WANT_EVAL
  188. && firstc != '@'
  189. #endif
  190. && !global_busy)
  191.     got_int = FALSE;
  192. /* free old command line when finished moving around in the history
  193.  * list */
  194. if (lookfor
  195. && c != K_S_DOWN && c != K_S_UP && c != K_DOWN && c != K_UP
  196. && c != K_PAGEDOWN && c != K_PAGEUP
  197. && c != K_KPAGEDOWN && c != K_KPAGEUP
  198. && c != K_LEFT && c != K_RIGHT
  199. && (cmd_numfiles > 0 || (c != Ctrl('P') && c != Ctrl('N'))))
  200. {
  201.     vim_free(lookfor);
  202.     lookfor = NULL;
  203. }
  204. /*
  205.  * <S-Tab> works like CTRL-P (unless 'wc' is <S-Tab>).
  206.  */
  207. if (c != p_wc && c == K_S_TAB && cmd_numfiles != -1)
  208.     c = Ctrl('P');
  209. /* free expanded names when finished walking through matches */
  210. if (cmd_numfiles != -1 && !(c == p_wc && KeyTyped)
  211. && c != Ctrl('N') && c != Ctrl('P') && c != Ctrl('A')
  212. && c != Ctrl('L'))
  213. {
  214.     (void)ExpandOne(NULL, NULL, 0, WILD_FREE);
  215.     did_wild_list = FALSE;
  216.     wim_index = 0;
  217. }
  218. #ifdef DIGRAPHS
  219. c = do_digraph(c);
  220. #endif
  221. if (c == 'n' || c == 'r' || c == K_KENTER || (c == ESC
  222. && (!KeyTyped || vim_strchr(p_cpo, CPO_ESC) != NULL)))
  223. {
  224.     gotesc = FALSE; /* Might have typed ESC previously, don't
  225.    truncate the cmdline now. */
  226.     if (ccheck_abbr(c + ABBR_OFF))
  227. goto cmdline_changed;
  228.     windgoto(msg_row, 0);
  229.     out_flush();
  230.     break;
  231. }
  232. /*
  233.  * Completion for 'wildchar' key.
  234.  * - hitting <ESC> twice means: abandon command line.
  235.  * - wildcard expansion is only done when the key is really typed, not
  236.  *   when it comes from a macro
  237.  */
  238. if (c == p_wc && !gotesc && KeyTyped)
  239. {
  240.     if (cmd_numfiles > 0)   /* typed p_wc at least twice */
  241.     {
  242. /* if 'wildmode' contains "list", may still need to list */
  243. if (cmd_numfiles > 1
  244. && !did_wild_list
  245. && (wim_flags[wim_index] & WIM_LIST))
  246. {
  247.     showmatches();
  248.     redrawcmd();
  249.     did_wild_list = TRUE;
  250. }
  251. if (wim_flags[wim_index] & WIM_LONGEST)
  252.     res = nextwild(WILD_LONGEST, WILD_NO_BEEP);
  253. else if (wim_flags[wim_index] & WIM_FULL)
  254.     res = nextwild(WILD_NEXT, WILD_NO_BEEP);
  255. else
  256.     res = OK;     /* don't insert 'wildchar' now */
  257.     }
  258.     else     /* typed p_wc first time */
  259.     {
  260. j = ccline.cmdpos;
  261. /* if 'wildmode' first contains "longest", get longest
  262.  * common part */
  263. if (wim_flags[0] & WIM_LONGEST)
  264.     res = nextwild(WILD_LONGEST, WILD_NO_BEEP);
  265. else
  266.     res = nextwild(WILD_EXPAND_KEEP, WILD_NO_BEEP);
  267. /* when more than one match, and 'wildmode' first contains
  268.  * "list", or no change and 'wildmode' contains "longest,list",
  269.  * list all matches */
  270. if (res == OK && cmd_numfiles > 1)
  271. {
  272.     /* a "longest" that didn't do anything is skipped (but not
  273.      * "list:longest") */
  274.     if (wim_flags[0] == WIM_LONGEST && ccline.cmdpos == j)
  275. wim_index = 1;
  276.     if (wim_flags[wim_index] & WIM_LIST)
  277.     {
  278. if (!(wim_flags[0] & WIM_LONGEST))
  279.     nextwild(WILD_PREV, 0); /* remove match */
  280. showmatches();
  281. redrawcmd();
  282. did_wild_list = TRUE;
  283. if (wim_flags[wim_index] & WIM_LONGEST)
  284.     nextwild(WILD_LONGEST, WILD_NO_BEEP);
  285. else if (wim_flags[wim_index] & WIM_FULL)
  286.     nextwild(WILD_NEXT, WILD_NO_BEEP);
  287.     }
  288.     else
  289. vim_beep();
  290. }
  291.     }
  292.     if (wim_index < 3)
  293. ++wim_index;
  294.     if (c == ESC)
  295. gotesc = TRUE;
  296.     if (res == OK)
  297. goto cmdline_changed;
  298. }
  299. gotesc = FALSE;
  300. /* <S-Tab> goes to last match, in a clumsy way */
  301. if (c == K_S_TAB && KeyTyped)
  302. {
  303.     if (nextwild(WILD_EXPAND_KEEP, 0) == OK
  304.     && nextwild(WILD_PREV, 0) == OK
  305.     && nextwild(WILD_PREV, 0) == OK)
  306. goto cmdline_changed;
  307. }
  308. if (c == NUL || c == K_ZERO)     /* NUL is stored as NL */
  309.     c = NL;
  310. do_abbr = TRUE; /* default: check for abbreviation */
  311. switch (c)
  312. {
  313. case K_BS:
  314. case Ctrl('H'):
  315. case K_DEL:
  316. case Ctrl('W'):
  317. #ifdef FKMAP
  318. if (cmd_fkmap && c == K_BS)
  319.     c = K_DEL;
  320. #endif
  321. /*
  322.  * delete current character is the same as backspace on next
  323.  * character, except at end of line
  324.  */
  325. if (c == K_DEL && ccline.cmdpos != ccline.cmdlen)
  326.     ++ccline.cmdpos;
  327. if (ccline.cmdpos > 0)
  328. {
  329.     j = ccline.cmdpos;
  330.     if (c == Ctrl('W'))
  331.     {
  332. while (ccline.cmdpos &&
  333.        vim_isspace(ccline.cmdbuff[ccline.cmdpos - 1]))
  334.     --ccline.cmdpos;
  335. i = vim_iswordc(ccline.cmdbuff[ccline.cmdpos - 1]);
  336. while (ccline.cmdpos && !vim_isspace(
  337.  ccline.cmdbuff[ccline.cmdpos - 1]) &&
  338. vim_iswordc(
  339.       ccline.cmdbuff[ccline.cmdpos - 1]) == i)
  340.     --ccline.cmdpos;
  341.     }
  342.     else
  343. --ccline.cmdpos;
  344.     ccline.cmdlen -= j - ccline.cmdpos;
  345.     i = ccline.cmdpos;
  346.     while (i < ccline.cmdlen)
  347. ccline.cmdbuff[i++] = ccline.cmdbuff[j++];
  348.     redrawcmd();
  349. }
  350. else if (ccline.cmdlen == 0 && c != Ctrl('W')
  351.    && ccline.cmdprompt == NULL && indent == 0)
  352. {
  353.     vim_free(ccline.cmdbuff); /* no commandline to return */
  354.     ccline.cmdbuff = NULL;
  355.     msg_col = 0;
  356.     msg_putchar(' '); /* delete ':' */
  357.     redraw_cmdline = TRUE;
  358.     goto returncmd; /* back to cmd mode */
  359. }
  360. goto cmdline_changed;
  361. case K_INS:
  362. #ifdef FKMAP
  363. /* if Farsi mode set, we are in reverse insert mode -
  364.    Do not change the mode */
  365. if (cmd_fkmap)
  366.     beep_flush();
  367. else
  368. #endif
  369. ccline.overstrike = !ccline.overstrike;
  370. #ifdef CURSOR_SHAPE
  371. ui_cursor_shape(); /* may show different cursor shape */
  372. #endif
  373. goto cmdline_not_changed;
  374. /* case '@':   only in very old vi */
  375. case Ctrl('U'):
  376. ccline.cmdpos = 0;
  377. ccline.cmdlen = 0;
  378. set_cmdspos();
  379. redrawcmd();
  380. goto cmdline_changed;
  381. case ESC: /* get here if p_wc != ESC or when ESC typed twice */
  382. case Ctrl('C'):
  383. gotesc = TRUE;     /* will free ccline.cmdbuff after putting
  384.        it in history */
  385. goto returncmd;     /* back to cmd mode */
  386. case Ctrl('R'):     /* insert register */
  387. #ifdef USE_GUI_WIN32
  388. dont_scroll = TRUE; /* disallow scrolling here */
  389. #endif
  390. putcmdline('"');
  391. ++no_mapping;
  392. c = vgetc();
  393. --no_mapping;
  394. #ifdef WANT_EVAL
  395. /*
  396.  * Insert the result of an expression.
  397.  * Need to save the current command line, to be able to enter
  398.  * a new one...
  399.  */
  400. if (c == '=')
  401. {
  402.     struct cmdline_info     save_ccline;
  403.     if (ccline.cmdfirstc == '=')/* can't do this recursively */
  404.     {
  405. beep_flush();
  406. c = ESC;
  407.     }
  408.     else
  409.     {
  410. save_ccline = ccline;
  411. c = get_expr_register();
  412. ccline = save_ccline;
  413.     }
  414. }
  415. #endif
  416. if (c != ESC)     /* use ESC to cancel inserting register */
  417.     cmdline_paste(c);
  418. redrawcmd();
  419. goto cmdline_changed;
  420. case Ctrl('D'):
  421. if (showmatches() == FAIL)
  422.     break; /* Use ^D as normal char instead */
  423. redrawcmd();
  424. continue; /* don't do incremental search now */
  425. case K_RIGHT:
  426. case K_S_RIGHT:
  427. do
  428. {
  429.     if (ccline.cmdpos >= ccline.cmdlen)
  430. break;
  431.     ccline.cmdspos += charsize(ccline.cmdbuff[ccline.cmdpos]);
  432.     ++ccline.cmdpos;
  433. }
  434. while ((c == K_S_RIGHT || (mod_mask & MOD_MASK_CTRL))
  435. && ccline.cmdbuff[ccline.cmdpos] != ' ');
  436. goto cmdline_not_changed;
  437. case K_LEFT:
  438. case K_S_LEFT:
  439. do
  440. {
  441.     if (ccline.cmdpos <= 0)
  442. break;
  443.     --ccline.cmdpos;
  444.     ccline.cmdspos -= charsize(ccline.cmdbuff[ccline.cmdpos]);
  445. }
  446. while ((c == K_S_LEFT || (mod_mask & MOD_MASK_CTRL))
  447. && ccline.cmdbuff[ccline.cmdpos - 1] != ' ');
  448. goto cmdline_not_changed;
  449. #if defined(USE_MOUSE) || defined(FKMAP)
  450. case K_IGNORE:
  451. #endif
  452. #ifdef USE_MOUSE
  453. case K_MIDDLEDRAG:
  454. case K_MIDDLERELEASE:
  455. goto cmdline_not_changed;   /* Ignore mouse */
  456. case K_MIDDLEMOUSE:
  457. # ifdef USE_GUI
  458. /* When GUI is active, also paste when 'mouse' is empty */
  459. if (!gui.in_use)
  460. # endif
  461.     if (!mouse_has(MOUSE_COMMAND))
  462. goto cmdline_not_changed;   /* Ignore mouse */
  463. # ifdef USE_GUI
  464. if (gui.in_use)
  465.     cmdline_paste('*');
  466. else
  467. # endif
  468.     cmdline_paste(0);
  469. redrawcmd();
  470. goto cmdline_changed;
  471. case K_LEFTDRAG:
  472. case K_LEFTRELEASE:
  473. case K_RIGHTDRAG:
  474. case K_RIGHTRELEASE:
  475. if (ignore_drag_release)
  476.     goto cmdline_not_changed;
  477. /* FALLTHROUGH */
  478. case K_LEFTMOUSE:
  479. case K_RIGHTMOUSE:
  480. if (c == K_LEFTRELEASE || c == K_RIGHTRELEASE)
  481.     ignore_drag_release = TRUE;
  482. else
  483.     ignore_drag_release = FALSE;
  484. # ifdef USE_GUI
  485. /* When GUI is active, also move when 'mouse' is empty */
  486. if (!gui.in_use)
  487. # endif
  488.     if (!mouse_has(MOUSE_COMMAND))
  489. goto cmdline_not_changed;   /* Ignore mouse */
  490. set_cmdspos();
  491. for (ccline.cmdpos = 0; ccline.cmdpos < ccline.cmdlen;
  492.       ++ccline.cmdpos)
  493. {
  494.     i = charsize(ccline.cmdbuff[ccline.cmdpos]);
  495.     if (mouse_row <= cmdline_row + ccline.cmdspos / Columns &&
  496.      mouse_col < ccline.cmdspos % Columns + i)
  497. break;
  498.     ccline.cmdspos += i;
  499. }
  500. goto cmdline_not_changed;
  501. #endif /* USE_MOUSE */
  502. #ifdef USE_GUI
  503. case K_SCROLLBAR:
  504. if (!msg_scrolled)
  505. {
  506.     gui_do_scroll();
  507.     redrawcmd();
  508. }
  509. goto cmdline_not_changed;
  510. case K_HORIZ_SCROLLBAR:
  511. if (!msg_scrolled)
  512. {
  513.     gui_do_horiz_scroll();
  514.     redrawcmd();
  515. }
  516. goto cmdline_not_changed;
  517. #endif
  518. case K_SELECT:     /* end of Select mode mapping - ignore */
  519. goto cmdline_not_changed;
  520. case Ctrl('B'):     /* begin of command line */
  521. case K_HOME:
  522. case K_KHOME:
  523. case K_S_HOME:
  524. ccline.cmdpos = 0;
  525. set_cmdspos();
  526. goto cmdline_not_changed;
  527. case Ctrl('E'):     /* end of command line */
  528. case K_END:
  529. case K_KEND:
  530. case K_S_END:
  531. ccline.cmdpos = ccline.cmdlen;
  532. ccline.cmdbuff[ccline.cmdlen] = NUL;
  533. set_cmdspos();
  534. ccline.cmdspos += vim_strsize(ccline.cmdbuff);
  535. goto cmdline_not_changed;
  536. case Ctrl('A'):     /* all matches */
  537. if (nextwild(WILD_ALL, 0) == FAIL)
  538.     break;
  539. goto cmdline_changed;
  540. case Ctrl('L'):     /* longest common part */
  541. if (nextwild(WILD_LONGEST, 0) == FAIL)
  542.     break;
  543. goto cmdline_changed;
  544. case Ctrl('N'):     /* next match */
  545. case Ctrl('P'):     /* previous match */
  546. if (cmd_numfiles > 0)
  547. {
  548.     if (nextwild((c == Ctrl('P')) ? WILD_PREV : WILD_NEXT, 0)
  549.       == FAIL)
  550. break;
  551.     goto cmdline_changed;
  552. }
  553. case K_UP:
  554. case K_DOWN:
  555. case K_S_UP:
  556. case K_S_DOWN:
  557. case K_PAGEUP:
  558. case K_KPAGEUP:
  559. case K_PAGEDOWN:
  560. case K_KPAGEDOWN:
  561. if (hislen == 0 || firstc == NUL) /* no history */
  562.     goto cmdline_not_changed;
  563. i = hiscnt;
  564. /* save current command string so it can be restored later */
  565. ccline.cmdbuff[ccline.cmdlen] = NUL;
  566. if (lookfor == NULL)
  567. {
  568.     if ((lookfor = vim_strsave(ccline.cmdbuff)) == NULL)
  569. goto cmdline_not_changed;
  570.     lookfor[ccline.cmdpos] = NUL;
  571. }
  572. j = STRLEN(lookfor);
  573. for (;;)
  574. {
  575.     /* one step backwards */
  576.     if (c == K_UP || c == K_S_UP || c == Ctrl('P') ||
  577.     c == K_PAGEUP || c == K_KPAGEUP)
  578.     {
  579. if (hiscnt == hislen) /* first time */
  580.     hiscnt = hisidx[histype];
  581. else if (hiscnt == 0 && hisidx[histype] != hislen - 1)
  582.     hiscnt = hislen - 1;
  583. else if (hiscnt != hisidx[histype] + 1)
  584.     --hiscnt;
  585. else /* at top of list */
  586. {
  587.     hiscnt = i;
  588.     break;
  589. }
  590.     }
  591.     else    /* one step forwards */
  592.     {
  593. /* on last entry, clear the line */
  594. if (hiscnt == hisidx[histype])
  595. {
  596.     hiscnt = hislen;
  597.     break;
  598. }
  599. /* not on a history line, nothing to do */
  600. if (hiscnt == hislen)
  601.     break;
  602. if (hiscnt == hislen - 1)   /* wrap around */
  603.     hiscnt = 0;
  604. else
  605.     ++hiscnt;
  606.     }
  607.     if (hiscnt < 0 || history[histype][hiscnt] == NULL)
  608.     {
  609. hiscnt = i;
  610. break;
  611.     }
  612.     if ((c != K_UP && c != K_DOWN) || hiscnt == i ||
  613.     STRNCMP(history[histype][hiscnt],
  614.     lookfor, (size_t)j) == 0)
  615. break;
  616. }
  617. if (hiscnt != i) /* jumped to other entry */
  618. {
  619.     vim_free(ccline.cmdbuff);
  620.     if (hiscnt == hislen)
  621. p = lookfor; /* back to the old one */
  622.     else
  623. p = history[histype][hiscnt];
  624.     alloc_cmdbuff((int)STRLEN(p));
  625.     if (ccline.cmdbuff == NULL)
  626. goto returncmd;
  627.     STRCPY(ccline.cmdbuff, p);
  628.     ccline.cmdpos = ccline.cmdlen = STRLEN(ccline.cmdbuff);
  629.     redrawcmd();
  630.     goto cmdline_changed;
  631. }
  632. beep_flush();
  633. goto cmdline_not_changed;
  634. case Ctrl('V'):
  635. case Ctrl('Q'):
  636. #ifdef USE_MOUSE
  637. ignore_drag_release = TRUE;
  638. #endif
  639. putcmdline('^');
  640. c = get_literal();     /* get next (two) character(s) */
  641. do_abbr = FALSE;     /* don't do abbreviation now */
  642. break;
  643. #ifdef DIGRAPHS
  644. case Ctrl('K'):
  645. #ifdef USE_MOUSE
  646. ignore_drag_release = TRUE;
  647. #endif
  648. putcmdline('?');
  649. #ifdef USE_GUI_WIN32
  650. dont_scroll = TRUE;     /* disallow scrolling here */
  651. #endif
  652. ++no_mapping;
  653. ++allow_keys;
  654. c = vgetc();
  655. --no_mapping;
  656. --allow_keys;
  657. if (c != ESC)     /* ESC cancels CTRL-K */
  658. {
  659.     if (IS_SPECIAL(c))     /* insert special key code */
  660. break;
  661.     if (charsize(c) == 1)
  662. putcmdline(c);
  663.     ++no_mapping;
  664.     ++allow_keys;
  665.     cc = vgetc();
  666.     --no_mapping;
  667.     --allow_keys;
  668.     if (cc != ESC)     /* ESC cancels CTRL-K */
  669.     {
  670. c = getdigraph(c, cc, TRUE);
  671. break;
  672.     }
  673. }
  674. redrawcmd();
  675. goto cmdline_not_changed;
  676. #endif /* DIGRAPHS */
  677. #ifdef RIGHTLEFT
  678. case Ctrl('_'):     /* CTRL-_: switch language mode */
  679. if (!p_ari)
  680.     break;
  681. #ifdef FKMAP
  682. if (p_altkeymap)
  683. {
  684.     cmd_fkmap = !cmd_fkmap;
  685.     if (cmd_fkmap) /* in Farsi always in Insert mode */
  686. ccline.overstrike = FALSE;
  687. }
  688. else     /* Hebrew is default */
  689. #endif
  690.     cmd_hkmap = !cmd_hkmap;
  691. goto cmdline_not_changed;
  692. #endif
  693.     /* keypad keys: When not mapped they produce a normal char */
  694. case K_KPLUS: c = '+'; break;
  695. case K_KMINUS: c = '-'; break;
  696. case K_KDIVIDE: c = '/'; break;
  697. case K_KMULTIPLY: c = '*'; break;
  698. default:
  699. #ifdef UNIX
  700. if (c == intr_char)
  701. {
  702.     gotesc = TRUE; /* will free ccline.cmdbuff after
  703.    putting it in history */
  704.     goto returncmd; /* back to cmd mode */
  705. }
  706. #endif
  707. /*
  708.  * Normal character with no special meaning.  Just set mod_mask
  709.  * to 0x0 so that typing Shift-Space in the GUI doesn't enter
  710.  * the string <S-Space>.  This should only happen after ^V.
  711.  */
  712. if (!IS_SPECIAL(c))
  713.     mod_mask = 0x0;
  714. break;
  715. }
  716. /* we come here if we have a normal character */
  717. if (do_abbr && (IS_SPECIAL(c) || !vim_iswordc(c)) && ccheck_abbr(c))
  718.     goto cmdline_changed;
  719. /*
  720.  * put the character in the command line
  721.  */
  722. if (IS_SPECIAL(c) || mod_mask != 0x0)
  723.     put_on_cmdline(get_special_key_name(c, mod_mask), -1, TRUE);
  724. else
  725. {
  726.     IObuff[0] = c;
  727. #ifdef MULTI_BYTE
  728.     /* prevent from splitting a multi-byte character into two
  729.        indivisual characters in command line. */
  730.     if (is_dbcs && IsLeadByte(c))
  731.     {
  732. IObuff[1] = vgetc();
  733. put_on_cmdline(IObuff, 2, TRUE);
  734.     }
  735.     else
  736. put_on_cmdline(IObuff, 1, TRUE);
  737. #else
  738.     put_on_cmdline(IObuff, 1, TRUE);
  739. #endif
  740. }
  741. goto cmdline_changed;
  742. /*
  743.  * This part implements incremental searches for "/" and "?"
  744.  * Jump to cmdline_not_changed when a character has been read but the command
  745.  * line did not change. Then we only search and redraw if something changed in
  746.  * the past.
  747.  * Jump to cmdline_changed when the command line did change.
  748.  * (Sorry for the goto's, I know it is ugly).
  749.  */
  750. cmdline_not_changed:
  751. #ifdef EXTRA_SEARCH
  752. if (!incsearch_postponed)
  753.     continue;
  754. #endif
  755. cmdline_changed:
  756. #ifdef EXTRA_SEARCH
  757. if (p_is && (firstc == '/' || firstc == '?'))
  758. {
  759.     /* if there is a character waiting, search and redraw later */
  760.     if (char_avail())
  761.     {
  762. incsearch_postponed = TRUE;
  763. continue;
  764.     }
  765.     incsearch_postponed = FALSE;
  766.     curwin->w_cursor = old_cursor;  /* start at old position */
  767.     /* If there is no command line, don't do anything */
  768.     if (ccline.cmdlen == 0)
  769. i = 0;
  770.     else
  771.     {
  772. ccline.cmdbuff[ccline.cmdlen] = NUL;
  773. emsg_off = TRUE;    /* So it doesn't beep if bad expr */
  774. i = do_search(NULL, firstc, ccline.cmdbuff, count,
  775.       SEARCH_KEEP + SEARCH_OPT + SEARCH_NOOF);
  776. emsg_off = FALSE;
  777.     }
  778.     if (i)
  779. highlight_match = TRUE; /* highlight position */
  780.     else
  781. highlight_match = FALSE;     /* don't highlight */
  782.     /* first restore the old curwin values, so the screen is
  783.      * positioned in the same way as the actual search command */
  784.     curwin->w_leftcol = old_leftcol;
  785.     curwin->w_topline = old_topline;
  786.     curwin->w_botline = old_botline;
  787.     update_topline();
  788.     /*
  789.      * First move cursor to end of match, then to start.  This moves
  790.      * the whole match onto the screen when 'nowrap' is set.
  791.      */
  792.     curwin->w_cursor.col += search_match_len;
  793.     validate_cursor();
  794.     curwin->w_cursor.col -= search_match_len;
  795.     validate_cursor();
  796.     update_screen(NOT_VALID);
  797.     redrawcmdline();
  798.     did_incsearch = TRUE;
  799. }
  800. #else
  801. ;
  802. #endif
  803.     }
  804. returncmd:
  805. #ifdef FKMAP
  806.     cmd_fkmap = 0;
  807. #endif
  808. #ifdef EXTRA_SEARCH
  809.     if (did_incsearch)
  810.     {
  811. curwin->w_cursor = old_cursor;
  812. curwin->w_curswant = old_curswant;
  813. curwin->w_leftcol = old_leftcol;
  814. curwin->w_topline = old_topline;
  815. curwin->w_botline = old_botline;
  816. highlight_match = FALSE;
  817. validate_cursor(); /* needed for TAB */
  818. redraw_later(NOT_VALID);
  819.     }
  820. #endif
  821.     if (ccline.cmdbuff != NULL)
  822.     {
  823. /*
  824.  * Put line in history buffer (":" and "=" only when it was typed).
  825.  */
  826. ccline.cmdbuff[ccline.cmdlen] = NUL;
  827. if (ccline.cmdlen && firstc &&
  828.    (some_key_typed || histype == HIST_SEARCH))
  829. {
  830.     add_to_history(histype, ccline.cmdbuff);
  831.     if (firstc == ':')
  832.     {
  833. vim_free(new_last_cmdline);
  834. new_last_cmdline = vim_strsave(ccline.cmdbuff);
  835.     }
  836. }
  837. if (gotesc)     /* abandon command line */
  838. {
  839.     vim_free(ccline.cmdbuff);
  840.     ccline.cmdbuff = NULL;
  841.     MSG("");
  842.     redraw_cmdline = TRUE;
  843. }
  844.     }
  845.     /*
  846.      * If the screen was shifted up, redraw the whole screen (later).
  847.      * If the line is too long, clear it, so ruler and shown command do
  848.      * not get printed in the middle of it.
  849.      */
  850.     msg_check();
  851.     msg_scroll = save_msg_scroll;
  852.     redir_off = FALSE;
  853.     State = save_State;
  854. #ifdef USE_MOUSE
  855.     setmouse();
  856. #endif
  857.     return ccline.cmdbuff;
  858. }
  859.     static void
  860. set_cmdspos()
  861. {
  862.     if (ccline.cmdfirstc)
  863. ccline.cmdspos = 1 + ccline.cmdindent;
  864.     else
  865. ccline.cmdspos = 0 + ccline.cmdindent;
  866. }
  867. /*
  868.  * Get an Ex command line for the ":" command.
  869.  */
  870. /* ARGSUSED */
  871.     char_u *
  872. getexline(c, dummy, indent)
  873.     int c; /* normally ':', NUL for ":append" */
  874.     void *dummy; /* cookie not used */
  875.     int indent; /* indent for inside conditionals */
  876. {
  877.     return getcmdline(c, 1L, indent);
  878. }
  879. /*
  880.  * Get an Ex command line for Ex mode.
  881.  * In Ex mode we only use the OS supplied line editing features and no
  882.  * mappings or abbreviations.
  883.  */
  884. /* ARGSUSED */
  885.     char_u *
  886. getexmodeline(c, dummy, indent)
  887.     int c; /* normally ':', NUL for ":append" */
  888.     void *dummy; /* cookie not used */
  889.     int indent; /* indent for inside conditionals */
  890. {
  891.     struct growarray line_ga;
  892.     int len;
  893.     int off = 0;
  894.     char_u *p;
  895.     int finished = FALSE;
  896. #if defined(USE_GUI) || defined(NO_COOKED_INPUT)
  897.     int startcol = 0;
  898.     int c1;
  899.     int escaped = FALSE; /* CTRL-V typed */
  900.     int vcol = 0;
  901. #endif
  902.     /* always start in column 0; write a newline if necessary */
  903.     compute_cmdrow();
  904.     if (msg_col)
  905. msg_putchar('n');
  906.     if (c == ':')
  907.     {
  908. msg_putchar(':');
  909. while (indent-- > 0)
  910.     msg_putchar(' ');
  911. #if defined(USE_GUI) || defined(NO_COOKED_INPUT)
  912. startcol = msg_col;
  913. #endif
  914.     }
  915.     ga_init2(&line_ga, 1, 30);
  916.     /*
  917.      * Get the line, one character at a time.
  918.      */
  919.     got_int = FALSE;
  920.     while (!got_int && !finished)
  921.     {
  922. if (ga_grow(&line_ga, 40) == FAIL)
  923.     break;
  924. p = (char_u *)line_ga.ga_data + line_ga.ga_len;
  925. /* Get one character (inchar gets a third of maxlen characters!) */
  926. len = inchar(p + off, 3, -1L);
  927. if (len < 0)
  928.     continue;     /* end of input script reached */
  929. /* for a special character, we need at least three characters */
  930. if ((*p == K_SPECIAL || *p == CSI) && off + len < 3)
  931. {
  932.     off += len;
  933.     continue;
  934. }
  935. len += off;
  936. off = 0;
  937. /*
  938.  * When using the GUI, and for systems that don't have cooked input,
  939.  * handle line editing here.
  940.  */
  941. #if defined(USE_GUI) || defined(NO_COOKED_INPUT)
  942. # ifndef NO_COOKED_INPUT
  943. if (gui.in_use)
  944. # endif
  945. {
  946.     if (got_int)
  947.     {
  948. msg_putchar('n');
  949. break;
  950.     }
  951.     while (len > 0)
  952.     {
  953. c1 = *p++;
  954. --len;
  955. # ifndef NO_COOKED_INPUT
  956. if ((c1 == K_SPECIAL || c1 == CSI) && len >= 2)
  957. # else
  958. #  ifdef USE_GUI
  959. if ((c1 == K_SPECIAL || (c1 == CSI && gui.in_use)) && len >= 2)
  960. #  else
  961. if (c1 == K_SPECIAL && len >= 2)
  962. #  endif
  963. # endif
  964. {
  965.     c1 = TO_SPECIAL(p[0], p[1]);
  966.     p += 2;
  967.     len -= 2;
  968. }
  969. if (!escaped)
  970. {
  971.     if (c1 == BS || c1 == K_BS || c1 == DEL || c1 == K_DEL)
  972.     {
  973. if (line_ga.ga_len > 0)
  974. {
  975.     int i, v;
  976.     char_u *q;
  977.     --line_ga.ga_len;
  978.     ++line_ga.ga_room;
  979.     /* compute column that cursor should be in */
  980.     v = 0;
  981.     q = ((char_u *)line_ga.ga_data);
  982.     for (i = 0; i < line_ga.ga_len; ++i)
  983.     {
  984. if (*q == TAB)
  985.     v += 8 - v % 8;
  986. else
  987.     v += charsize(*q);
  988. ++q;
  989.     }
  990.     /* erase characters to position cursor */
  991.     while (vcol > v)
  992.     {
  993. msg_putchar('b');
  994. msg_putchar(' ');
  995. msg_putchar('b');
  996. --vcol;
  997.     }
  998. }
  999. continue;
  1000.     }
  1001.     if (c1 == Ctrl('U'))
  1002.     {
  1003. msg_col = startcol;
  1004. msg_clr_eos();
  1005. line_ga.ga_room += line_ga.ga_len;
  1006. line_ga.ga_len = 0;
  1007. continue;
  1008.     }
  1009.     if (c1 == Ctrl('V'))
  1010.     {
  1011. escaped = TRUE;
  1012. continue;
  1013.     }
  1014. }
  1015. ((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1;
  1016. if (c1 == 'r')
  1017.     msg_putchar('n');
  1018. else if (c1 == TAB)
  1019. {
  1020.     /* Don't use chartabsize(), 'ts' can be different */
  1021.     do
  1022.     {
  1023. msg_putchar(' ');
  1024.     } while (++vcol % 8);
  1025. }
  1026. else
  1027. {
  1028.     msg_outtrans_len(
  1029.      ((char_u *)line_ga.ga_data) + line_ga.ga_len, 1);
  1030.     vcol += charsize(c1);
  1031. }
  1032. ++line_ga.ga_len;
  1033. --line_ga.ga_room;
  1034. escaped = FALSE;
  1035.     }
  1036.     windgoto(msg_row, msg_col);
  1037. }
  1038. # ifndef NO_COOKED_INPUT
  1039. else
  1040. # endif
  1041. #endif
  1042. #ifndef NO_COOKED_INPUT
  1043. {
  1044.     line_ga.ga_len += len;
  1045.     line_ga.ga_room -= len;
  1046. }
  1047. #endif
  1048. p = (char_u *)(line_ga.ga_data) + line_ga.ga_len;
  1049. while (line_ga.ga_len && (p[-1] == 'n' || p[-1] == 'r'))
  1050. {
  1051.     finished = TRUE;
  1052.     --line_ga.ga_len;
  1053.     --p;
  1054.     *p = NUL;
  1055. }
  1056.     }
  1057.     /* note that cursor has moved, because of the echoed <CR> */
  1058.     screen_down();
  1059.     /* make following messages go to the next line */
  1060.     msg_didout = FALSE;
  1061.     msg_col = 0;
  1062.     if (msg_row < Rows - 1)
  1063. ++msg_row;
  1064.     emsg_on_display = FALSE; /* don't want ui_delay() */
  1065.     if (got_int)
  1066. ga_clear(&line_ga);
  1067.     return (char_u *)line_ga.ga_data;
  1068. }
  1069. #ifdef CURSOR_SHAPE
  1070. /*
  1071.  * Return TRUE if ccline.overstrike is on.
  1072.  */
  1073.     int
  1074. cmdline_overstrike()
  1075. {
  1076.     return ccline.overstrike;
  1077. }
  1078. /*
  1079.  * Return TRUE if the cursor is at the end of the cmdline.
  1080.  */
  1081.     int
  1082. cmdline_at_end()
  1083. {
  1084.     return (ccline.cmdpos >= ccline.cmdlen);
  1085. }
  1086. #endif
  1087. /*
  1088.  * Allocate a new command line buffer.
  1089.  * Assigns the new buffer to ccline.cmdbuff and ccline.cmdbufflen.
  1090.  * Returns the new value of ccline.cmdbuff and ccline.cmdbufflen.
  1091.  */
  1092.     static void
  1093. alloc_cmdbuff(len)
  1094.     int     len;
  1095. {
  1096.     /*
  1097.      * give some extra space to avoid having to allocate all the time
  1098.      */
  1099.     if (len < 80)
  1100. len = 100;
  1101.     else
  1102. len += 20;
  1103.     ccline.cmdbuff = alloc(len);    /* caller should check for out-of-memory */
  1104.     ccline.cmdbufflen = len;
  1105. }
  1106. /*
  1107.  * Re-allocate the command line to length len + something extra.
  1108.  * return FAIL for failure, OK otherwise
  1109.  */
  1110.     static int
  1111. realloc_cmdbuff(len)
  1112.     int     len;
  1113. {
  1114.     char_u *p;
  1115.     p = ccline.cmdbuff;
  1116.     alloc_cmdbuff(len); /* will get some more */
  1117.     if (ccline.cmdbuff == NULL) /* out of memory */
  1118.     {
  1119. ccline.cmdbuff = p; /* keep the old one */
  1120. return FAIL;
  1121.     }
  1122.     mch_memmove(ccline.cmdbuff, p, (size_t)ccline.cmdlen);
  1123.     vim_free(p);
  1124.     return OK;
  1125. }
  1126. /*
  1127.  * put a character on the command line.
  1128.  * Used for CTRL-V and CTRL-K
  1129.  */
  1130.     static void
  1131. putcmdline(c)
  1132.     int     c;
  1133. {
  1134.     char_u  buf[1];
  1135.     buf[0] = c;
  1136.     msg_outtrans_len(buf, 1);
  1137.     msg_outtrans_len(ccline.cmdbuff + ccline.cmdpos,
  1138.        ccline.cmdlen - ccline.cmdpos);
  1139.     cursorcmd();
  1140. }
  1141. /*
  1142.  * Put the given string, of the given length, onto the command line.
  1143.  * If len is -1, then STRLEN() is used to calculate the length.
  1144.  * If 'redraw' is TRUE then the new part of the command line, and the remaining
  1145.  * part will be redrawn, otherwise it will not.  If this function is called
  1146.  * twice in a row, then 'redraw' should be FALSE and redrawcmd() should be
  1147.  * called afterwards.
  1148.  */
  1149.     int
  1150. put_on_cmdline(str, len, redraw)
  1151.     char_u  *str;
  1152.     int     len;
  1153.     int     redraw;
  1154. {
  1155.     int     i;
  1156.     if (len < 0)
  1157. len = STRLEN(str);
  1158.     /* Check if ccline.cmdbuff needs to be longer */
  1159.     if (ccline.cmdlen + len + 1 >= ccline.cmdbufflen)
  1160. i = realloc_cmdbuff(ccline.cmdlen + len);
  1161.     else
  1162. i = OK;
  1163.     if (i == OK)
  1164.     {
  1165. if (!ccline.overstrike)
  1166. {
  1167.     mch_memmove(ccline.cmdbuff + ccline.cmdpos + len,
  1168.        ccline.cmdbuff + ccline.cmdpos,
  1169.      (size_t)(ccline.cmdlen - ccline.cmdpos));
  1170.     ccline.cmdlen += len;
  1171. }
  1172. else if (ccline.cmdpos + len > ccline.cmdlen)
  1173.     ccline.cmdlen = ccline.cmdpos + len;
  1174. mch_memmove(ccline.cmdbuff + ccline.cmdpos, str, (size_t)len);
  1175. if (redraw)
  1176.     msg_outtrans_len(ccline.cmdbuff + ccline.cmdpos,
  1177.        ccline.cmdlen - ccline.cmdpos);
  1178. #ifdef FKMAP
  1179. /*
  1180.  ** If we are in Farsi command mode, the character input must be in
  1181.  ** insert mode. So do not advance the cmdpos.
  1182.  */
  1183. if (!cmd_fkmap)
  1184. #endif
  1185. {
  1186.     ccline.cmdpos += len;
  1187.     while (len--)
  1188. ccline.cmdspos += charsize(str[len]);
  1189. }
  1190.     }
  1191.     if (redraw)
  1192. msg_check();
  1193.     return i;
  1194. }
  1195. /*
  1196.  * this fuction is called when the screen size changes and with incremental
  1197.  * search
  1198.  */
  1199.     void
  1200. redrawcmdline()
  1201. {
  1202.     msg_scrolled = 0;
  1203.     need_wait_return = FALSE;
  1204.     compute_cmdrow();
  1205.     redrawcmd();
  1206.     cursorcmd();
  1207. }
  1208.     static void
  1209. redrawcmdprompt()
  1210. {
  1211.     int i;
  1212.     if (ccline.cmdfirstc)
  1213. msg_putchar(ccline.cmdfirstc);
  1214.     if (ccline.cmdprompt != NULL)
  1215.     {
  1216. msg_puts_attr(ccline.cmdprompt, ccline.cmdattr);
  1217. ccline.cmdindent = msg_col;
  1218.     }
  1219.     else
  1220. for (i = ccline.cmdindent; i > 0; --i)
  1221.     msg_putchar(' ');
  1222. }
  1223. /*
  1224.  * Redraw what is currently on the command line.
  1225.  */
  1226.     static void
  1227. redrawcmd()
  1228. {
  1229.     int     i;
  1230.     msg_start();
  1231.     redrawcmdprompt();
  1232.     msg_outtrans_len(ccline.cmdbuff, ccline.cmdlen);
  1233.     msg_clr_eos();
  1234.     set_cmdspos();
  1235.     for (i = 0; i < ccline.cmdlen && i < ccline.cmdpos; ++i)
  1236. ccline.cmdspos += charsize(ccline.cmdbuff[i]);
  1237.     /*
  1238.      * An emsg() before may have set msg_scroll. This is used in normal mode,
  1239.      * in cmdline mode we can reset them now.
  1240.      */
  1241.     msg_scroll = FALSE; /* next message overwrites cmdline */
  1242.     /* Typing ':' at the more prompt may set skip_redraw.  We don't want this
  1243.      * in cmdline mode */
  1244.     skip_redraw = FALSE;
  1245. }
  1246. /*
  1247.  * Set prompt in front of cmdline.
  1248.  */
  1249.     void
  1250. cmdline_prompt(cmsg, attr)
  1251.     char_u *cmsg;
  1252.     int attr;
  1253. {
  1254.     ccline.cmdprompt = cmsg;
  1255.     ccline.cmdattr = attr;
  1256. }
  1257.     void
  1258. compute_cmdrow()
  1259. {
  1260.     if (exmode_active)
  1261. cmdline_row = Rows - 1;
  1262.     else
  1263. cmdline_row = lastwin->w_winpos + lastwin->w_height +
  1264. lastwin->w_status_height;
  1265. }
  1266.     static void
  1267. cursorcmd()
  1268. {
  1269.     msg_row = cmdline_row + (ccline.cmdspos / (int)Columns);
  1270.     msg_col = ccline.cmdspos % (int)Columns;
  1271.     if (msg_row >= Rows)
  1272. msg_row = Rows - 1;
  1273.     windgoto(msg_row, msg_col);
  1274. #if defined(MSDOS) || (defined(WIN32) && !defined(USE_GUI_WIN32))
  1275.     mch_update_cursor();
  1276. #endif
  1277. }
  1278.     void
  1279. gotocmdline(clr)
  1280.     int     clr;
  1281. {
  1282.     msg_start();
  1283.     msg_col = 0;     /* always start in column 0 */
  1284.     if (clr)     /* clear the bottom line(s) */
  1285. msg_clr_eos();     /* will reset clear_cmdline */
  1286.     windgoto(cmdline_row, 0);
  1287. }
  1288. /*
  1289.  * Check the word in front of the cursor for an abbreviation.
  1290.  * Called when the non-id character "c" has been entered.
  1291.  * When an abbreviation is recognized it is removed from the text with
  1292.  * backspaces and the replacement string is inserted, followed by "c".
  1293.  */
  1294.     static int
  1295. ccheck_abbr(c)
  1296.     int c;
  1297. {
  1298.     if (p_paste || no_abbr)     /* no abbreviations or in paste mode */
  1299. return FALSE;
  1300.     return check_abbr(c, ccline.cmdbuff, ccline.cmdpos, 0);
  1301. }
  1302. /*
  1303.  * Return FAIL if this is not an appropriate context in which to do
  1304.  * completion of anything, return OK if it is (even if there are no matches).
  1305.  * For the caller, this means that the character is just passed through like a
  1306.  * normal character (instead of being expanded).  This allows :s/^I^D etc.
  1307.  */
  1308.     static int
  1309. nextwild(type, options)
  1310.     int     type;
  1311.     int     options;     /* extra options for ExpandOne() */
  1312. {
  1313.     int     i, j;
  1314.     char_u  *p1;
  1315.     char_u  *p2;
  1316.     int     oldlen;
  1317.     int     difflen;
  1318.     int     v;
  1319.     if (cmd_numfiles == -1)
  1320. set_expand_context();
  1321.     if (expand_context == EXPAND_UNSUCCESSFUL)
  1322.     {
  1323. beep_flush();
  1324. return OK;  /* Something illegal on command line */
  1325.     }
  1326.     if (expand_context == EXPAND_NOTHING)
  1327.     {
  1328. /* Caller can use the character as a normal char instead */
  1329. return FAIL;
  1330.     }
  1331.     expand_interactively = TRUE;
  1332.     MSG_PUTS("...");     /* show that we are busy */
  1333.     out_flush();
  1334.     i = expand_pattern - ccline.cmdbuff;
  1335.     oldlen = ccline.cmdpos - i;
  1336.     if (type == WILD_NEXT || type == WILD_PREV)
  1337.     {
  1338. /*
  1339.  * Get next/previous match for a previous expanded pattern.
  1340.  */
  1341. p2 = ExpandOne(NULL, NULL, 0, type);
  1342.     }
  1343.     else
  1344.     {
  1345. /*
  1346.  * Translate string into pattern and expand it.
  1347.  */
  1348. if ((p1 = addstar(&ccline.cmdbuff[i], oldlen)) == NULL)
  1349.     p2 = NULL;
  1350. else
  1351. {
  1352.     p2 = ExpandOne(p1, vim_strnsave(&ccline.cmdbuff[i], oldlen),
  1353.    WILD_HOME_REPLACE | options, type);
  1354.     vim_free(p1);
  1355.     /* longest match: make sure it is not shorter (happens with :help */
  1356.     if (p2 != NULL && type == WILD_LONGEST)
  1357.     {
  1358. for (j = 0; j < oldlen; ++j)
  1359.      if (ccline.cmdbuff[i + j] == '*'
  1360.      || ccline.cmdbuff[i + j] == '?')
  1361.  break;
  1362. if ((int)STRLEN(p2) < j)
  1363. {
  1364.     vim_free(p2);
  1365.     p2 = NULL;
  1366. }
  1367.     }
  1368. }
  1369.     }
  1370.     if (p2 != NULL)
  1371.     {
  1372. if (ccline.cmdlen + (difflen = STRLEN(p2) - oldlen) >
  1373. ccline.cmdbufflen - 4)
  1374. {
  1375.     v = realloc_cmdbuff(ccline.cmdlen + difflen);
  1376.     expand_pattern = ccline.cmdbuff + i;
  1377. }
  1378. else
  1379.     v = OK;
  1380. if (v == OK)
  1381. {
  1382.     vim_strncpy(&ccline.cmdbuff[ccline.cmdpos + difflen],
  1383.        &ccline.cmdbuff[ccline.cmdpos],
  1384.     ccline.cmdlen - ccline.cmdpos);
  1385.     STRNCPY(&ccline.cmdbuff[i], p2, STRLEN(p2));
  1386.     ccline.cmdlen += difflen;
  1387.     ccline.cmdpos += difflen;
  1388. }
  1389. vim_free(p2);
  1390.     }
  1391.     redrawcmd();
  1392.     if (cmd_numfiles <= 0 && p2 == NULL)
  1393. beep_flush();
  1394.     else if (cmd_numfiles == 1)
  1395. (void)ExpandOne(NULL, NULL, 0, WILD_FREE);  /* free expanded pattern */
  1396.     expand_interactively = FALSE;     /* reset for next call */
  1397.     return OK;
  1398. }
  1399. /*
  1400.  * Do wildcard expansion on the string 'str'.
  1401.  * Return a pointer to alloced memory containing the new string.
  1402.  * Return NULL for failure.
  1403.  *
  1404.  * mode = WILD_FREE:     just free previously expanded matches
  1405.  * mode = WILD_EXPAND_FREE: normal expansion, do not keep matches
  1406.  * mode = WILD_EXPAND_KEEP: normal expansion, keep matches
  1407.  * mode = WILD_NEXT:     use next match in multiple match, wrap to first
  1408.  * mode = WILD_PREV:     use previous match in multiple match, wrap to first
  1409.  * mode = WILD_ALL:     return all matches concatenated
  1410.  * mode = WILD_LONGEST:     return longest matched part
  1411.  *
  1412.  * options = WILD_LIST_NOTFOUND:    list entries without a match
  1413.  * options = WILD_HOME_REPLACE:     do home_replace() for buffer names
  1414.  * options = WILD_USE_NL:     Use 'n' for WILD_ALL
  1415.  * options = WILD_NO_BEEP:     Don't beep for multiple matches
  1416.  */
  1417.     char_u *
  1418. ExpandOne(str, orig, options, mode)
  1419.     char_u  *str;
  1420.     char_u  *orig;     /* original string which is expanded */
  1421.     int     options;
  1422.     int     mode;
  1423. {
  1424.     char_u *ss = NULL;
  1425.     static char_u **cmd_files = NULL; /* list of input files */
  1426.     static int findex;
  1427.     static char_u *orig_save = NULL; /* kept value of orig */
  1428.     int i;
  1429.     int non_suf_match; /* number without matching suffix */
  1430.     long_u len;
  1431.     char_u *p;
  1432. /*
  1433.  * first handle the case of using an old match
  1434.  */
  1435.     if (mode == WILD_NEXT || mode == WILD_PREV)
  1436.     {
  1437. if (cmd_numfiles > 0)
  1438. {
  1439.     if (mode == WILD_PREV)
  1440.     {
  1441. if (findex == -1)
  1442.     findex = cmd_numfiles;
  1443. --findex;
  1444.     }
  1445.     else    /* mode == WILD_NEXT */
  1446. ++findex;
  1447.     /*
  1448.      * When wrapping around, return the original string, set findex to
  1449.      * -1.
  1450.      */
  1451.     if (findex < 0)
  1452.     {
  1453. if (orig_save == NULL)
  1454.     findex = cmd_numfiles - 1;
  1455. else
  1456.     findex = -1;
  1457.     }
  1458.     if (findex >= cmd_numfiles)
  1459.     {
  1460. if (orig_save == NULL)
  1461.     findex = 0;
  1462. else
  1463.     findex = -1;
  1464.     }
  1465.     if (findex == -1)
  1466. return vim_strsave(orig_save);
  1467.     return vim_strsave(cmd_files[findex]);
  1468. }
  1469. else
  1470.     return NULL;
  1471.     }
  1472. /* free old names */
  1473.     if (cmd_numfiles != -1 && mode != WILD_ALL && mode != WILD_LONGEST)
  1474.     {
  1475. FreeWild(cmd_numfiles, cmd_files);
  1476. cmd_numfiles = -1;
  1477. vim_free(orig_save);
  1478. orig_save = NULL;
  1479.     }
  1480.     findex = 0;
  1481.     if (mode == WILD_FREE) /* only release file name */
  1482. return NULL;
  1483.     if (cmd_numfiles == -1)
  1484.     {
  1485. vim_free(orig_save);
  1486. orig_save = orig;
  1487. /*
  1488.  * Do the expansion.
  1489.  */
  1490. if (ExpandFromContext(str, &cmd_numfiles, &cmd_files, FALSE,
  1491.      options) == FAIL)
  1492.     /* error: do nothing */;
  1493. else if (cmd_numfiles == 0)
  1494. {
  1495.     if (!expand_interactively)
  1496. emsg2(e_nomatch2, str);
  1497. }
  1498. else
  1499. {
  1500.     /*
  1501.      * May change home directory back to "~"
  1502.      */
  1503.     if (options & WILD_HOME_REPLACE)
  1504. tilde_replace(str, cmd_numfiles, cmd_files);
  1505.     /*
  1506.      * Insert backslashes into a file name before a space, , %, # and
  1507.      * wildmatch characters, except '~'.
  1508.      */
  1509.     if (expand_interactively &&
  1510.     (expand_context == EXPAND_FILES ||
  1511.      expand_context == EXPAND_BUFFERS ||
  1512.      expand_context == EXPAND_DIRECTORIES))
  1513.     {
  1514. for (i = 0; i < cmd_numfiles; ++i)
  1515. {
  1516.     /* for ":set path=" we need to escape spaces twice */
  1517.     if (expand_set_path)
  1518.     {
  1519. p = vim_strsave_escaped(cmd_files[i], (char_u *)" ");
  1520. if (p != NULL)
  1521. {
  1522.     vim_free(cmd_files[i]);
  1523.     cmd_files[i] = p;
  1524. #if defined(BACKSLASH_IN_FILENAME) || defined(COLON_AS_PATHSEP)
  1525.     p = vim_strsave_escaped(cmd_files[i],
  1526.        (char_u *)" ");
  1527.     if (p != NULL)
  1528.     {
  1529. vim_free(cmd_files[i]);
  1530. cmd_files[i] = p;
  1531.     }
  1532. #endif
  1533. }
  1534.     }
  1535.     p = vim_strsave_escaped(cmd_files[i],
  1536. #ifdef BACKSLASH_IN_FILENAME
  1537.     (char_u *)" *?[{`$%#"
  1538. #else
  1539. # ifdef COLON_AS_PATHSEP
  1540.     (char_u *)" *?[{`$%#/"
  1541. # else
  1542.     (char_u *)" *?[{`$\%#"
  1543. # endif
  1544. #endif
  1545.     );
  1546.     if (p != NULL)
  1547.     {
  1548. vim_free(cmd_files[i]);
  1549. cmd_files[i] = p;
  1550.     }
  1551. }
  1552. expand_set_path = FALSE;
  1553.     }
  1554.     /*
  1555.      * Check for matching suffixes in file names.
  1556.      */
  1557.     if (mode != WILD_ALL && mode != WILD_LONGEST)
  1558.     {
  1559. if (cmd_numfiles)
  1560.     non_suf_match = cmd_numfiles;
  1561. else
  1562.     non_suf_match = 1;
  1563. if ((!expand_interactively
  1564.     || expand_context == EXPAND_FILES
  1565.     || expand_context == EXPAND_DIRECTORIES)
  1566. && cmd_numfiles > 1) /* more than one match; check suffix */
  1567. {
  1568.     /*
  1569.      * The files will have been sorted on matching suffix in
  1570.      * expand_wildcards, only need to check the first two.
  1571.      */
  1572.     non_suf_match = 0;
  1573.     for (i = 0; i < 2; ++i)
  1574. if (match_suffix(cmd_files[i]))
  1575.     ++non_suf_match;
  1576. }
  1577. if (non_suf_match != 1)
  1578. {
  1579.     /* Can we ever get here unless it's while expanding
  1580.      * interactively?  If not, we can get rid of this all
  1581.      * together. Don't really want to wait for this message
  1582.      * (and possibly have to hit return to continue!).
  1583.      */
  1584.     if (!expand_interactively)
  1585. emsg(e_toomany);
  1586.     else if (!(options & WILD_NO_BEEP))
  1587. beep_flush();
  1588. }
  1589. if (!(non_suf_match != 1 && mode == WILD_EXPAND_FREE))
  1590.     ss = vim_strsave(cmd_files[0]);
  1591.     }
  1592. }
  1593.     }
  1594.     /* Find longest common part */
  1595.     if (mode == WILD_LONGEST && cmd_numfiles > 0)
  1596.     {
  1597. for (len = 0; cmd_files[0][len]; ++len)
  1598. {
  1599.     for (i = 0; i < cmd_numfiles; ++i)
  1600.     {
  1601. #ifdef CASE_INSENSITIVE_FILENAME
  1602. if (expand_context == EXPAND_DIRECTORIES
  1603. || expand_context == EXPAND_FILES
  1604. || expand_context == EXPAND_BUFFERS)
  1605. {
  1606.     if (TO_LOWER(cmd_files[i][len]) !=
  1607.    TO_LOWER(cmd_files[0][len]))
  1608. break;
  1609. }
  1610. else
  1611. #endif
  1612.      if (cmd_files[i][len] != cmd_files[0][len])
  1613.     break;
  1614.     }
  1615.     if (i < cmd_numfiles)
  1616.     {
  1617. if (!(options & WILD_NO_BEEP))
  1618.     vim_beep();
  1619. break;
  1620.     }
  1621. }
  1622. ss = alloc((unsigned)len + 1);
  1623. if (ss)
  1624. {
  1625.     STRNCPY(ss, cmd_files[0], len);
  1626.     ss[len] = NUL;
  1627. }
  1628. findex = -1;     /* next p_wc gets first one */
  1629.     }
  1630.     /* Concatenate all matching names */
  1631.     if (mode == WILD_ALL && cmd_numfiles > 0)
  1632.     {
  1633. len = 0;
  1634. for (i = 0; i < cmd_numfiles; ++i)
  1635.     len += STRLEN(cmd_files[i]) + 1;
  1636. ss = lalloc(len, TRUE);
  1637. if (ss != NULL)
  1638. {
  1639.     *ss = NUL;
  1640.     for (i = 0; i < cmd_numfiles; ++i)
  1641.     {
  1642. STRCAT(ss, cmd_files[i]);
  1643. if (i != cmd_numfiles - 1)
  1644.     STRCAT(ss, (options & WILD_USE_NL) ? "n" : " ");
  1645.     }
  1646. }
  1647.     }
  1648.     if (mode == WILD_EXPAND_FREE || mode == WILD_ALL)
  1649.     {
  1650. FreeWild(cmd_numfiles, cmd_files);
  1651. cmd_numfiles = -1;
  1652.     }
  1653.     return ss;
  1654. }
  1655. /*
  1656.  * For each file name in files[num_files]:
  1657.  * If 'orig_pat' starts with "~/", replace the home directory with "~".
  1658.  */
  1659.     void
  1660. tilde_replace(orig_pat, num_files, files)
  1661.     char_u  *orig_pat;
  1662.     int     num_files;
  1663.     char_u  **files;
  1664. {
  1665.     int     i;
  1666.     char_u  *p;
  1667.     if (orig_pat[0] == '~' && vim_ispathsep(orig_pat[1]))
  1668.     {
  1669. for (i = 0; i < num_files; ++i)
  1670. {
  1671.     p = home_replace_save(NULL, files[i]);
  1672.     if (p != NULL)
  1673.     {
  1674. vim_free(files[i]);
  1675. files[i] = p;
  1676.     }
  1677. }
  1678.     }
  1679. }
  1680. /*
  1681.  * show all matches for completion on the command line
  1682.  */
  1683.     static int
  1684. showmatches()
  1685. {
  1686.     char_u *file_str;
  1687.     int num_files;
  1688.     char_u **files_found;
  1689.     int i, j, k;
  1690.     int maxlen;
  1691.     int lines;
  1692.     int columns;
  1693.     char_u *p;
  1694.     int lastlen;
  1695.     int attr;
  1696.     set_expand_context();
  1697.     if (expand_context == EXPAND_UNSUCCESSFUL)
  1698.     {
  1699. beep_flush();
  1700. return OK;  /* Something illegal on command line */
  1701.     }
  1702.     if (expand_context == EXPAND_NOTHING)
  1703.     {
  1704. /* Caller can use the character as a normal char instead */
  1705. return FAIL;
  1706.     }
  1707.     expand_interactively = TRUE;
  1708.     /* add star to file name, or convert to regexp if not expanding files! */
  1709.     file_str = addstar(expand_pattern,
  1710.       (int)(ccline.cmdbuff + ccline.cmdpos - expand_pattern));
  1711.     if (file_str == NULL)
  1712.     {
  1713. expand_interactively = FALSE;
  1714. return OK;
  1715.     }
  1716.     msg_didany = FALSE; /* lines_left will be set */
  1717.     msg_start(); /* prepare for paging */
  1718.     msg_putchar('n');
  1719.     out_flush();
  1720.     cmdline_row = msg_row;
  1721.     msg_didany = FALSE; /* lines_left will be set again */
  1722.     msg_start(); /* prepare for paging */
  1723.     /* find all files that match the description */
  1724.     if (ExpandFromContext(file_str, &num_files, &files_found, FALSE, 0) == FAIL)
  1725.     {
  1726. num_files = 0;
  1727. files_found = (char_u **)"";
  1728.     }
  1729.     /* find the length of the longest file name */
  1730.     maxlen = 0;
  1731.     for (i = 0; i < num_files; ++i)
  1732.     {
  1733. if (expand_context == EXPAND_FILES || expand_context == EXPAND_BUFFERS)
  1734. {
  1735.     home_replace(NULL, files_found[i], NameBuff, MAXPATHL, TRUE);
  1736.     j = vim_strsize(NameBuff);
  1737. }
  1738. else
  1739.     j = vim_strsize(files_found[i]);
  1740. if (j > maxlen)
  1741.     maxlen = j;
  1742.     }
  1743.     /* compute the number of columns and lines for the listing */
  1744.     maxlen += 2;    /* two spaces between file names */
  1745.     columns = ((int)Columns + 2) / maxlen;
  1746.     if (columns < 1)
  1747. columns = 1;
  1748.     lines = (num_files + columns - 1) / columns;
  1749.     attr = hl_attr(HLF_D); /* find out highlighting for directories */
  1750.     /* list the files line by line */
  1751.     for (i = 0; i < lines; ++i)
  1752.     {
  1753. lastlen = 999;
  1754. for (k = i; k < num_files; k += lines)
  1755. {
  1756.     for (j = maxlen - lastlen; --j >= 0; )
  1757. msg_putchar(' ');
  1758.     if (expand_context == EXPAND_FILES ||
  1759.      expand_context == EXPAND_BUFFERS)
  1760.     {
  1761. /* highlight directories */
  1762. j = (mch_isdir(files_found[k]));
  1763. home_replace(NULL, files_found[k], NameBuff, MAXPATHL, TRUE);
  1764. p = NameBuff;
  1765.     }
  1766.     else
  1767.     {
  1768. j = FALSE;
  1769. p = files_found[k];
  1770.     }
  1771.     lastlen = msg_outtrans_attr(p, j ? attr : 0);
  1772. }
  1773. msg_clr_eos();
  1774. msg_putchar('n');
  1775. out_flush();     /* show one line at a time */
  1776. if (got_int)
  1777. {
  1778.     got_int = FALSE;
  1779.     break;
  1780. }
  1781.     }
  1782.     vim_free(file_str);
  1783.     FreeWild(num_files, files_found);
  1784. /*
  1785.  * we redraw the command below the lines that we have just listed
  1786.  * This is a bit tricky, but it saves a lot of screen updating.
  1787.  */
  1788.     cmdline_row = msg_row; /* will put it back later */
  1789.     expand_interactively = FALSE;
  1790.     return OK;
  1791. }
  1792. /*
  1793.  * Prepare a string for expansion.
  1794.  * When expanding file names:  The string will be used with expand_wildcards().
  1795.  * Copy the file name into allocated memory and add a '*' at the end.
  1796.  * When expanding other names: The string will be used with regcomp().  Copy
  1797.  * the name into allocated memory and add ".*" at the end.
  1798.  */
  1799.     char_u *
  1800. addstar(fname, len)
  1801.     char_u  *fname;
  1802.     int     len;
  1803. {
  1804.     char_u  *retval;
  1805.     int     i, j;
  1806.     int     new_len;
  1807.     char_u  *tail;
  1808.     if (expand_interactively && expand_context != EXPAND_FILES &&
  1809.  expand_context != EXPAND_DIRECTORIES)
  1810.     {
  1811. /*
  1812.  * Matching will be done internally (on something other than files).
  1813.  * So we convert the file-matching-type wildcards into our kind for
  1814.  * use with vim_regcomp().  First work out how long it will be:
  1815.  */
  1816. /* for help tags the translation is done in find_help_tags() */
  1817. if (expand_context == EXPAND_HELP)
  1818.     retval = vim_strnsave(fname, len);
  1819. else
  1820. {
  1821.     new_len = len + 2; /* +2 for '^' at start, NUL at end */
  1822.     for (i = 0; i < len; i++)
  1823.     {
  1824. if (fname[i] == '*' || fname[i] == '~')
  1825.     new_len++; /* '*' needs to be replaced by ".*"
  1826.    '~' needs to be replaced by "~" */
  1827. /* Buffer names are like file names.  "." should be literal */
  1828. if (expand_context == EXPAND_BUFFERS && fname[i] == '.')
  1829.     new_len++; /* "." becomes "." */
  1830.     }
  1831.     retval = alloc(new_len);
  1832.     if (retval != NULL)
  1833.     {
  1834. retval[0] = '^';
  1835. j = 1;
  1836. for (i = 0; i < len; i++, j++)
  1837. {
  1838.     if (fname[i] == '\' && ++i == len) /* skip backslash */
  1839. break;
  1840.     switch (fname[i])
  1841.     {
  1842. case '*':   retval[j++] = '.';
  1843.     break;
  1844. case '~':   retval[j++] = '\';
  1845.     break;
  1846. case '?':   retval[j] = '.';
  1847.     continue;
  1848. case '.':   if (expand_context == EXPAND_BUFFERS)
  1849. retval[j++] = '\';
  1850.     break;
  1851.     }
  1852.     retval[j] = fname[i];
  1853. }
  1854. retval[j] = NUL;
  1855.     }
  1856. }
  1857.     }
  1858.     else
  1859.     {
  1860. retval = alloc(len + 4);
  1861. if (retval != NULL)
  1862. {
  1863.     STRNCPY(retval, fname, len);
  1864.     retval[len] = NUL;
  1865. #ifndef macintosh
  1866.     if (!expand_set_path)
  1867. backslash_halve(retval, TRUE); /* remove some backslashes */
  1868. #endif
  1869.     len = STRLEN(retval);
  1870.     /*
  1871.      * Don't add a star to ~, ~user, $var or `cmd`.
  1872.      * ~ would be at the start of the tail.
  1873.      * $ could be anywhere in the tail.
  1874.      * ` could be anywhere in the file name.
  1875.      */
  1876.     tail = gettail(retval);
  1877.     if (*tail != '~' && vim_strchr(tail, '$') == NULL
  1878.    && vim_strchr(retval, '`') == NULL)
  1879.     {
  1880. #ifdef MSDOS
  1881. /*
  1882.  * if there is no dot in the file name, add "*.*" instead of
  1883.  * "*".
  1884.  */
  1885. for (i = len - 1; i >= 0; --i)
  1886.     if (vim_strchr((char_u *)".\/:", retval[i]) != NULL)
  1887. break;
  1888. if (i < 0 || retval[i] != '.')
  1889. {
  1890.     retval[len++] = '*';
  1891.     retval[len++] = '.';
  1892. }
  1893. #endif
  1894. retval[len++] = '*';
  1895.     }
  1896.     retval[len] = NUL;
  1897. }
  1898.     }
  1899.     return retval;
  1900. }
  1901. /*
  1902.  * Must parse the command line so far to work out what context we are in.
  1903.  * Completion can then be done based on that context.
  1904.  * This routine sets two global variables:
  1905.  *  char_u *expand_pattern  The start of the pattern to be expanded within
  1906.  * the command line (ends at the cursor).
  1907.  *  int expand_context     The type of thing to expand.  Will be one of:
  1908.  *
  1909.  *  EXPAND_UNSUCCESSFUL     Used sometimes when there is something illegal on
  1910.  *     the command line, like an unknown command. Caller
  1911.  *     should beep.
  1912.  *  EXPAND_NOTHING     Unrecognised context for completion, use char like
  1913.  *     a normal char, rather than for completion. eg
  1914.  *     :s/^I/
  1915.  *  EXPAND_COMMANDS     Cursor is still touching the command, so complete
  1916.  *     it.
  1917.  *  EXPAND_BUFFERS     Complete file names for :buf and :sbuf commands.
  1918.  *  EXPAND_FILES     After command with XFILE set, or after setting
  1919.  *     with P_EXPAND set. eg :e ^I, :w>>^I
  1920.  *  EXPAND_DIRECTORIES     In some cases this is used instead of the latter
  1921.  *     when we know only directories are of interest.  eg
  1922.  *     :set dir=^I
  1923.  *  EXPAND_SETTINGS     Complete variable names.  eg :set d^I
  1924.  *  EXPAND_BOOL_SETTINGS    Complete boolean variables only,  eg :set no^I
  1925.  *  EXPAND_TAGS     Complete tags from the files in p_tags.  eg :ta a^I
  1926.  *  EXPAND_HELP     Complete tags from the file 'helpfile'/tags
  1927.  *  EXPAND_EVENTS     Complete event names
  1928.  *  EXPAND_SYNTAX     Complete :syntax command arguments
  1929.  *  EXPAND_HIGHLIGHT     Complete highlight (syntax) group names
  1930.  *  EXPAND_AUGROUP     Complete autocommand group names
  1931.  *  EXPAND_USER_VARS     Complete user defined variable names, eg :unlet a^I
  1932.  *
  1933.  * -- webb.
  1934.  */
  1935.     static void
  1936. set_expand_context()
  1937. {
  1938.     char_u *nextcomm;
  1939.     int old_char = NUL;
  1940.     if (ccline.cmdfirstc != ':') /* only expansion for ':' commands */
  1941.     {
  1942. expand_context = EXPAND_NOTHING;
  1943. return;
  1944.     }
  1945.     /*
  1946.      * Avoid a UMR warning from Purify, only save the character if it has been
  1947.      * written before.
  1948.      */
  1949.     if (ccline.cmdpos < ccline.cmdlen)
  1950. old_char = ccline.cmdbuff[ccline.cmdpos];
  1951.     ccline.cmdbuff[ccline.cmdpos] = NUL;
  1952.     nextcomm = ccline.cmdbuff;
  1953.     while (nextcomm != NULL)
  1954. nextcomm = set_one_cmd_context(nextcomm);
  1955.     ccline.cmdbuff[ccline.cmdpos] = old_char;
  1956. }
  1957. /*
  1958.  * Do the expansion based on the global variables expand_context and
  1959.  * expand_pattern -- webb.
  1960.  */
  1961.     static int
  1962. ExpandFromContext(pat, num_file, file, files_only, options)
  1963.     char_u  *pat;
  1964.     int     *num_file;
  1965.     char_u  ***file;
  1966.     int     files_only;
  1967.     int     options;
  1968. {
  1969.     vim_regexp *prog;
  1970.     int ret;
  1971.     int flags;
  1972.     flags = 0;
  1973.     if (!files_only)
  1974. flags |= EW_DIR;
  1975.     if (options & WILD_LIST_NOTFOUND)
  1976. flags |= EW_NOTFOUND;
  1977.     if (!expand_interactively || expand_context == EXPAND_FILES)
  1978.     {
  1979. /*
  1980.  * Expand file names.
  1981.  */
  1982. return expand_wildcards(1, &pat, num_file, file, flags|EW_FILE);
  1983.     }
  1984.     else if (expand_context == EXPAND_DIRECTORIES)
  1985.     {
  1986. /*
  1987.  * Expand directory names.
  1988.  */
  1989. int free_pat = FALSE;
  1990. int i;
  1991. /* for ":set path=" we need to remove backslashes for escaped space */
  1992. if (expand_set_path)
  1993. {
  1994.     free_pat = TRUE;
  1995.     pat = vim_strsave(pat);
  1996.     for (i = 0; pat[i]; ++i)
  1997. if (pat[i] == '\' && pat[i + 1] == '\' &&
  1998.       pat[i + 2] == '\' && pat[i + 3] == ' ')
  1999.     STRCPY(pat + i, pat + i + 3);
  2000. }
  2001. ret = expand_wildcards(1, &pat, num_file, file,
  2002.  (flags | EW_DIR) & ~EW_FILE);
  2003. if (free_pat)
  2004.     vim_free(pat);
  2005. return ret;
  2006.     }
  2007.     *file = (char_u **)"";
  2008.     *num_file = 0;
  2009.     if (expand_context == EXPAND_OLD_SETTING)
  2010. return ExpandOldSetting(num_file, file);
  2011.     if (expand_context == EXPAND_HELP)
  2012. return find_help_tags(pat, num_file, file);
  2013.     set_reg_ic(pat);     /* set reg_ic according to p_ic, p_scs and pat */
  2014.     if (expand_context == EXPAND_BUFFERS)
  2015. return ExpandBufnames(pat, num_file, file, options);
  2016.     else if (expand_context == EXPAND_TAGS)
  2017.     {
  2018. if (pat[0] == '^' && pat[1] == '/')
  2019.     return find_tags(pat + 2, num_file, file,
  2020. TAG_REGEXP | TAG_NAMES | TAG_VERBOSE, MAXCOL);
  2021. return find_tags(pat, num_file, file,
  2022.      TAG_REGEXP | TAG_NAMES | TAG_VERBOSE | TAG_NOIC, MAXCOL);
  2023.     }
  2024.     prog = vim_regcomp(pat, (int)p_magic);
  2025.     if (prog == NULL)
  2026. return FAIL;
  2027.     if (expand_context == EXPAND_COMMANDS)
  2028. ret = ExpandGeneric(prog, num_file, file, get_command_name);
  2029.     else if (expand_context == EXPAND_SETTINGS ||
  2030.        expand_context == EXPAND_BOOL_SETTINGS)
  2031. ret = ExpandSettings(prog, num_file, file);
  2032. #ifdef WANT_EVAL
  2033.     else if (expand_context == EXPAND_USER_VARS)
  2034. ret = ExpandGeneric(prog, num_file, file, get_user_var_name);
  2035. #endif
  2036. #ifdef USE_GUI
  2037.     else if (expand_context == EXPAND_MENUS)
  2038. ret = ExpandGeneric(prog, num_file, file, get_menu_name);
  2039. #endif
  2040. #ifdef SYNTAX_HL
  2041.     else if (expand_context == EXPAND_SYNTAX)
  2042.     {
  2043. reg_ic = TRUE;
  2044. ret = ExpandGeneric(prog, num_file, file, get_syntax_name);
  2045.     }
  2046. #endif
  2047.     else if (expand_context == EXPAND_HIGHLIGHT)
  2048.     {
  2049. reg_ic = TRUE;
  2050. ret = ExpandGeneric(prog, num_file, file, get_highlight_name);
  2051.     }
  2052. #ifdef AUTOCMD
  2053.     else if (expand_context == EXPAND_EVENTS)
  2054.     {
  2055. reg_ic = TRUE;
  2056. ret = ExpandGeneric(prog, num_file, file, get_event_name);
  2057.     }
  2058.     else if (expand_context == EXPAND_AUGROUP)
  2059.     {
  2060. reg_ic = TRUE;
  2061. ret = ExpandGeneric(prog, num_file, file, get_augroup_name);
  2062.     }
  2063. #endif
  2064.     else
  2065. ret = FAIL;
  2066.     vim_free(prog);
  2067.     return ret;
  2068. }
  2069. /*
  2070.  * Expand a list of names.
  2071.  *
  2072.  * Generic function for command line completion.  It calls a function to
  2073.  * obtain strings, one by one. The strings are matched against a regexp
  2074.  * program.  Matching strings are copied into an array, which is returned.
  2075.  *
  2076.  * Returns OK when no problems encountered, FAIL for error (out of memory).
  2077.  */
  2078.     int
  2079. ExpandGeneric(prog, num_file, file, func)
  2080.     vim_regexp *prog;
  2081.     int *num_file;
  2082.     char_u ***file;
  2083.     char_u *((*func)__ARGS((int))); /* returns a string from the list */
  2084. {
  2085.     int i;
  2086.     int count = 0;
  2087.     int loop;
  2088.     char_u  *str;
  2089.     /* do this loop twice:
  2090.      * loop == 0: count the number of matching names
  2091.      * loop == 1: copy the matching names into allocated memory
  2092.      */
  2093.     for (loop = 0; loop <= 1; ++loop)
  2094.     {
  2095. for (i = 0; ; ++i)
  2096. {
  2097.     str = (*func)(i);
  2098.     if (str == NULL)     /* end of list */
  2099. break;
  2100.     if (*str == NUL)     /* skip empty strings */
  2101. continue;
  2102.     if (vim_regexec(prog, str, TRUE))
  2103.     {
  2104. if (loop)
  2105.     (*file)[count] = vim_strsave_escaped(str,
  2106.   (char_u *)" t\.");
  2107. ++count;
  2108.     }
  2109. }
  2110. if (loop == 0)
  2111. {
  2112.     if (count == 0)
  2113. return OK;
  2114.     *num_file = count;
  2115.     *file = (char_u **)alloc((unsigned)(count * sizeof(char_u *)));
  2116.     if (*file == NULL)
  2117.     {
  2118. *file = (char_u **)"";
  2119. return FAIL;
  2120.     }
  2121.     count = 0;
  2122. }
  2123.     }
  2124.     return OK;
  2125. }
  2126. /*********************************
  2127.  *  Command line history stuff  *
  2128.  *********************************/
  2129. /*
  2130.  * Translate a history character to the associated type number.
  2131.  */
  2132.     static int
  2133. hist_char2type(c)
  2134.     int     c;
  2135. {
  2136.     if (c == ':')
  2137. return HIST_CMD;
  2138.     if (c == '=')
  2139. return HIST_EXPR;
  2140.     if (c == '@')
  2141. return HIST_INPUT;
  2142.     return HIST_SEARCH;     /* must be '?' or '/' */
  2143. }
  2144. /*
  2145.  * init_history() - Initialize the command line history.
  2146.  * Also used to re-allocate the history when the size changes.
  2147.  */
  2148.     static void
  2149. init_history()
  2150. {
  2151.     int     newlen;     /* new length of history table */
  2152.     char_u  **temp;
  2153.     int     i;
  2154.     int     j;
  2155.     int     type;
  2156.     /*
  2157.      * If size of history table changed, reallocate it
  2158.      */
  2159.     newlen = (int)p_hi;
  2160.     if (newlen != hislen) /* history length changed */
  2161.     {
  2162. for (type = 0; type < HIST_COUNT; ++type)   /* adjust the tables */
  2163. {
  2164.     if (newlen)
  2165.     {
  2166. temp = (char_u **)lalloc((long_u)(newlen * sizeof(char_u *)),
  2167. TRUE);
  2168. if (temp == NULL)   /* out of memory! */
  2169. {
  2170.     if (type == 0)  /* first one: just keep the old length */
  2171.     {
  2172. newlen = hislen;
  2173. break;
  2174.     }
  2175.     /* Already changed one table, now we can only have zero
  2176.      * length for all tables. */
  2177.     newlen = 0;
  2178.     type = -1;
  2179.     continue;
  2180. }
  2181.     }
  2182.     else
  2183. temp = NULL;
  2184.     if (newlen == 0 || temp != NULL)
  2185.     {
  2186. if (hisidx[type] < 0) /* there are no entries yet */
  2187. {
  2188.     for (i = 0; i < newlen; ++i)
  2189. temp[i] = NULL;
  2190. }
  2191. else if (newlen > hislen) /* array becomes bigger */
  2192. {
  2193.     for (i = 0; i <= hisidx[type]; ++i)
  2194. temp[i] = history[type][i];
  2195.     j = i;
  2196.     for ( ; i <= newlen - (hislen - hisidx[type]); ++i)
  2197. temp[i] = NULL;
  2198.     for ( ; j < hislen; ++i, ++j)
  2199. temp[i] = history[type][j];
  2200. }
  2201. else /* array becomes smaller or 0 */
  2202. {
  2203.     j = hisidx[type];
  2204.     for (i = newlen - 1; ; --i)
  2205.     {
  2206. if (i >= 0) /* copy newest entries */
  2207.     temp[i] = history[type][j];
  2208. else /* remove older entries */
  2209.     vim_free(history[type][j]);
  2210. if (--j < 0)
  2211.     j = hislen - 1;
  2212. if (j == hisidx[type])
  2213.     break;
  2214.     }
  2215.     hisidx[type] = newlen - 1;
  2216. }
  2217. vim_free(history[type]);
  2218. history[type] = temp;
  2219.     }
  2220. }
  2221. hislen = newlen;
  2222.     }
  2223. }
  2224. /*
  2225.  * Check if command line 'str' is already in history.
  2226.  * If 'move_to_front' is TRUE, matching entry is moved to end of history.
  2227.  */
  2228.     static int
  2229. in_history(type, str, move_to_front)
  2230.     int     type;
  2231.     char_u  *str;
  2232.     int     move_to_front; /* Move the entry to the front if it exists */
  2233. {
  2234.     int     i;
  2235.     int     last_i = -1;
  2236.     if (hisidx[type] < 0)
  2237. return FALSE;
  2238.     i = hisidx[type];
  2239.     do
  2240.     {
  2241. if (history[type][i] == NULL)
  2242.     return FALSE;
  2243. if (STRCMP(str, history[type][i]) == 0)
  2244. {
  2245.     if (!move_to_front)
  2246. return TRUE;
  2247.     last_i = i;
  2248.     break;
  2249. }
  2250. if (--i < 0)
  2251.     i = hislen - 1;
  2252.     } while (i != hisidx[type]);
  2253.     if (last_i >= 0)
  2254.     {
  2255. str = history[type][i];
  2256. while (i != hisidx[type])
  2257. {
  2258.     if (++i >= hislen)
  2259. i = 0;
  2260.     history[type][last_i] = history[type][i];
  2261.     last_i = i;
  2262. }
  2263. history[type][i] = str;
  2264. return TRUE;
  2265.     }
  2266.     return FALSE;
  2267. }
  2268. /*
  2269.  * Add the given string to the given history.  If the string is already in the
  2270.  * history then it is moved to the front.  "histype" may be HIST_CMD,
  2271.  * HIST_SEARCH, HIST_EXPR or HIST_INPUT.
  2272.  */
  2273.     void
  2274. add_to_history(histype, new_entry)
  2275.     int histype;
  2276.     char_u *new_entry;
  2277. {
  2278.     static int last_maptick = -1; /* last seen maptick */
  2279.     if (hislen == 0) /* no history */
  2280. return;
  2281.     /*
  2282.      * Searches inside the same mapping overwrite each other, so that only
  2283.      * the last line is kept.  Be careful not to remove a line that was moved
  2284.      * down, only lines that were added.
  2285.      */
  2286.     if (histype == HIST_SEARCH)
  2287.     {
  2288. if (maptick == last_maptick)
  2289. {
  2290.     /* Current line is from the same mapping, remove it */
  2291.     vim_free(history[HIST_SEARCH][hisidx[HIST_SEARCH]]);
  2292.     history[HIST_SEARCH][hisidx[HIST_SEARCH]] = NULL;
  2293.     if (--hisidx[HIST_SEARCH] < 0)
  2294. hisidx[HIST_SEARCH] = hislen - 1;
  2295. }
  2296. last_maptick = -1;
  2297.     }
  2298.     if (!in_history(histype, new_entry, TRUE))
  2299.     {
  2300. if (++hisidx[histype] == hislen)
  2301.     hisidx[histype] = 0;
  2302. vim_free(history[histype][hisidx[histype]]);
  2303. history[histype][hisidx[histype]] = vim_strsave(new_entry);
  2304. if (histype == HIST_SEARCH)
  2305.     last_maptick = maptick;
  2306.     }
  2307. }
  2308. #ifdef VIMINFO
  2309. static char_u **viminfo_history[HIST_COUNT] = {NULL, NULL, NULL, NULL};
  2310. static int viminfo_hisidx[HIST_COUNT] = {0, 0, 0, 0};
  2311. static int viminfo_hislen[HIST_COUNT] = {0, 0, 0, 0};
  2312. static int viminfo_add_at_front = FALSE;
  2313. static int hist_type2char __ARGS((int type, int use_question));
  2314. /*
  2315.  * Translate a history type number to the associated character.
  2316.  */
  2317.     static int
  2318. hist_type2char(type, use_question)
  2319.     int     type;
  2320.     int     use_question;     /* use '?' instead of '/' */
  2321. {
  2322.     if (type == HIST_CMD)
  2323. return ':';
  2324.     if (type == HIST_SEARCH)
  2325.     {
  2326. if (use_question)
  2327.     return '?';
  2328. else
  2329.     return '/';
  2330.     }
  2331.     if (type == HIST_EXPR)
  2332. return '=';
  2333.     return '@';
  2334. }
  2335. /*
  2336.  * Prepare for reading the history from the viminfo file.
  2337.  * This allocates history arrays to store the read history lines.
  2338.  */
  2339.     void
  2340. prepare_viminfo_history(asklen)
  2341.     int     asklen;
  2342. {
  2343.     int     i;
  2344.     int     num;
  2345.     int     type;
  2346.     int     len;
  2347.     init_history();
  2348.     viminfo_add_at_front = (asklen != 0);
  2349.     if (asklen > hislen)
  2350. asklen = hislen;
  2351.     for (type = 0; type < HIST_COUNT; ++type)
  2352.     {
  2353. /*
  2354.  * Count the number of empty spaces in the history list.  If there are
  2355.  * more spaces available than we request, then fill them up.
  2356.  */
  2357. for (i = 0, num = 0; i < hislen; i++)
  2358.     if (history[type][i] == NULL)
  2359. num++;
  2360. len = asklen;
  2361. if (num > len)
  2362.     len = num;
  2363. if (len <= 0)
  2364.     viminfo_history[type] = NULL;
  2365. else
  2366.     viminfo_history[type] =
  2367.    (char_u **)lalloc((long_u)(len * sizeof(char_u *)), FALSE);
  2368. if (viminfo_history[type] == NULL)
  2369.     len = 0;
  2370. viminfo_hislen[type] = len;
  2371. viminfo_hisidx[type] = 0;
  2372.     }
  2373. }
  2374. /*
  2375.  * Accept a line from the viminfo, store it in the history array when it's
  2376.  * new.
  2377.  */
  2378.     int
  2379. read_viminfo_history(line, fp)
  2380.     char_u  *line;
  2381.     FILE    *fp;
  2382. {
  2383.     int     type;
  2384.     type = hist_char2type(line[0]);
  2385.     if (viminfo_hisidx[type] < viminfo_hislen[type])
  2386.     {
  2387. viminfo_readstring(line);
  2388. if (!in_history(type, line + 1, viminfo_add_at_front))
  2389.     viminfo_history[type][viminfo_hisidx[type]++] =
  2390. vim_strsave(line + 1);
  2391.     }
  2392.     return vim_fgets(line, LSIZE, fp);
  2393. }
  2394.     void
  2395. finish_viminfo_history()
  2396. {
  2397.     int idx;
  2398.     int i;
  2399.     int type;
  2400.     for (type = 0; type < HIST_COUNT; ++type)
  2401.     {
  2402. if (history[type] == NULL)
  2403.     return;
  2404. idx = hisidx[type] + viminfo_hisidx[type];
  2405. if (idx >= hislen)
  2406.     idx -= hislen;
  2407. else if (idx < 0)
  2408.     idx = hislen - 1;
  2409. if (viminfo_add_at_front)
  2410.     hisidx[type] = idx;
  2411. else
  2412. {
  2413.     if (hisidx[type] == -1)
  2414. hisidx[type] = hislen - 1;
  2415.     do
  2416.     {
  2417. if (history[type][idx] != NULL)
  2418.     break;
  2419. if (++idx == hislen)
  2420.     idx = 0;
  2421.     } while (idx != hisidx[type]);
  2422.     if (idx != hisidx[type] && --idx < 0)
  2423. idx = hislen - 1;
  2424. }
  2425. for (i = 0; i < viminfo_hisidx[type]; i++)
  2426. {
  2427.     vim_free(history[type][idx]);
  2428.     history[type][idx] = viminfo_history[type][i];
  2429.     if (--idx < 0)
  2430. idx = hislen - 1;
  2431. }
  2432. vim_free(viminfo_history[type]);
  2433. viminfo_history[type] = NULL;
  2434.     }
  2435. }
  2436.     void
  2437. write_viminfo_history(fp)
  2438.     FILE    *fp;
  2439. {
  2440.     int     i;
  2441.     int     type;
  2442.     int     num_saved;
  2443.     init_history();
  2444.     if (hislen == 0)
  2445. return;
  2446.     for (type = 0; type < HIST_COUNT; ++type)
  2447.     {
  2448. num_saved = get_viminfo_parameter(hist_type2char(type, FALSE));
  2449. if (num_saved == 0)
  2450.     continue;
  2451. if (num_saved < 0)  /* Use default */
  2452.     num_saved = hislen;
  2453. fprintf(fp, "n# %s History (newest to oldest):n",
  2454.     type == HIST_CMD ? "Command Line" :
  2455.     type == HIST_SEARCH ? "Search String" :
  2456.     type == HIST_EXPR ?  "Expression" :
  2457. "Input Line");
  2458. if (num_saved > hislen)
  2459.     num_saved = hislen;
  2460. i = hisidx[type];
  2461. if (i >= 0)
  2462.     while (num_saved--)
  2463.     {
  2464. if (history[type][i] != NULL)
  2465. {
  2466.     putc(hist_type2char(type, TRUE), fp);
  2467.     viminfo_writestring(fp, history[type][i]);
  2468. }
  2469. if (--i < 0)
  2470.     i = hislen - 1;
  2471.     }
  2472.     }
  2473. }
  2474. #endif /* VIMINFO */
  2475. #if defined(FKMAP) || defined(PROTO)
  2476. /*
  2477.  * Write a character at the current cursor+offset position.
  2478.  * It is directly written into the command buffer block.
  2479.  */
  2480.     void
  2481. cmd_pchar(c, offset)
  2482.     int     c, offset;
  2483. {
  2484.     if (ccline.cmdpos + offset >= ccline.cmdlen || ccline.cmdpos + offset < 0)
  2485.     {
  2486. EMSG("cmd_pchar beyond the command length");
  2487. return;
  2488.     }
  2489.     ccline.cmdbuff[ccline.cmdpos + offset] = (char_u)c;
  2490. }
  2491.     int
  2492. cmd_gchar(offset)
  2493.     int     offset;
  2494. {
  2495.     if (ccline.cmdpos + offset >= ccline.cmdlen || ccline.cmdpos + offset < 0)
  2496.     {
  2497. /*  EMSG("cmd_gchar beyond the command length"); */
  2498. return NUL;
  2499.     }
  2500.     return (int)ccline.cmdbuff[ccline.cmdpos + offset];
  2501. }
  2502. #endif