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

编辑器/阅读器

开发平台:

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_docmd.c: functions for executing an Ex command line.
  10.  */
  11. #include "vim.h"
  12. #define DO_DECLARE_EXCMD
  13. #include "ex_cmds.h" /* Declare the cmdnames struct. */
  14. #ifdef HAVE_FCNTL_H
  15. # include <fcntl.h>     /* for chdir() */
  16. #endif
  17. static int quitmore = 0;
  18. static int ex_pressedreturn = FALSE;
  19. #ifdef WANT_EVAL
  20. /*
  21.  * For conditional commands a stack is kept of nested conditionals.
  22.  * When cs_idx < 0, there is no conditional command.
  23.  */
  24. #define CSTACK_LEN 50
  25. struct condstack
  26. {
  27.     char cs_flags[CSTACK_LEN]; /* CSF_ flags */
  28.     int cs_line[CSTACK_LEN]; /* line number of ":while" line */
  29.     int cs_idx; /* current entry, or -1 if none */
  30.     int cs_whilelevel; /* number of nested ":while"s */
  31.     char cs_had_while; /* just found ":while" */
  32.     char cs_had_continue; /* just found ":continue" */
  33.     char cs_had_endwhile; /* just found ":endwhile" */
  34. };
  35. #define CSF_TRUE 1 /* condition was TRUE */
  36. #define CSF_ACTIVE 2 /* current state is active */
  37. #define CSF_WHILE 4 /* is a ":while" */
  38. #endif
  39. #ifdef USER_COMMANDS
  40. typedef struct ucmd
  41. {
  42.     char_u *uc_name; /* The command name */
  43.     long uc_argt; /* The argument type */
  44.     char_u *uc_rep; /* The command's replacement string */
  45.     long uc_def; /* The default value for a range/count */
  46.     int uc_compl; /* completion type */
  47. } UCMD;
  48. struct growarray ucmds = { 0, 0, sizeof(UCMD), 4, NULL };
  49. #define USER_CMD(i) (&((UCMD *)(ucmds.ga_data))[i])
  50. #endif
  51. #ifdef WANT_EVAL
  52. static void free_cmdlines __ARGS((struct growarray *gap));
  53. static char_u *do_one_cmd __ARGS((char_u **, int, struct condstack *, char_u *(*getline)(int, void *, int), void *cookie));
  54. #else
  55. static char_u *do_one_cmd __ARGS((char_u **, int, char_u *(*getline)(int, void *, int), void *cookie));
  56. #endif
  57. static int buf_write_all __ARGS((BUF *));
  58. static int do_write __ARGS((EXARG *eap));
  59. static char_u *getargcmd __ARGS((char_u **));
  60. static char_u *skip_cmd_arg __ARGS((char_u *p));
  61. #ifdef QUICKFIX
  62. static void do_make __ARGS((char_u *, char_u *));
  63. static char_u *get_mef_name __ARGS((int newname));
  64. static void do_cfile __ARGS((EXARG *eap));
  65. #endif
  66. static int do_arglist __ARGS((char_u *));
  67. static int rem_backslash __ARGS((char_u *str));
  68. static int check_readonly __ARGS((int *forceit));
  69. static int check_changed __ARGS((BUF *, int, int, int, int));
  70. #if defined(GUI_DIALOG) || defined(CON_DIALOG)
  71. static void dialog_changed __ARGS((BUF *buf, int checkall));
  72. #endif
  73. #if defined(USE_BROWSE) && (defined(GUI_DIALOG) || defined(CON_DIALOG))
  74. static void browse_save_fname __ARGS((BUF *buf));
  75. #endif
  76. static int check_more __ARGS((int, int));
  77. static linenr_t get_address __ARGS((char_u **, int skip));
  78. static char_u * invalid_range __ARGS((EXARG *eap));
  79. static void correct_range __ARGS((EXARG *eap));
  80. static void do_quit __ARGS((EXARG *eap));
  81. static void do_quit_all __ARGS((int forceit));
  82. static void do_close __ARGS((EXARG *eap));
  83. static void do_suspend __ARGS((int forceit));
  84. static void do_exit __ARGS((EXARG *eap));
  85. static void do_wqall __ARGS((EXARG *eap));
  86. static void do_print __ARGS((EXARG *eap));
  87. static void do_argfile __ARGS((EXARG *eap, int argn));
  88. static void do_next __ARGS((EXARG *eap));
  89. static void do_recover __ARGS((EXARG *eap));
  90. static void do_args __ARGS((EXARG *eap));
  91. static void do_wnext __ARGS((EXARG *eap));
  92. static void do_resize __ARGS((EXARG *eap));
  93. static void do_splitview __ARGS((EXARG *eap));
  94. static void do_exedit __ARGS((EXARG *eap, WIN *old_curwin));
  95. #ifdef USE_GUI
  96. static void do_gui __ARGS((EXARG *eap));
  97. #endif
  98. static void do_swapname __ARGS((void));
  99. static void do_read __ARGS((EXARG *eap));
  100. static void do_cd __ARGS((EXARG *eap));
  101. static void do_pwd __ARGS((void));
  102. static void do_sleep __ARGS((EXARG *eap));
  103. static void do_exmap __ARGS((EXARG *eap, int isabbrev));
  104. static void do_winsize __ARGS((char_u *arg));
  105. static void do_exops __ARGS((EXARG *eap));
  106. static void do_copymove __ARGS((EXARG *eap));
  107. static void do_exjoin __ARGS((EXARG *eap));
  108. static void do_exat __ARGS((EXARG *eap));
  109. static void do_redir __ARGS((EXARG *eap));
  110. static void close_redir __ARGS((void));
  111. static void do_mkrc __ARGS((EXARG *eap, char_u *defname));
  112. static FILE *open_exfile __ARGS((EXARG *eap, char *mode));
  113. static void do_setmark __ARGS((EXARG *eap));
  114. #ifdef EX_EXTRA
  115. static void do_normal __ARGS((EXARG *eap));
  116. #endif
  117. #ifdef FIND_IN_PATH
  118. static char_u *do_findpat __ARGS((EXARG *eap, int action));
  119. #endif
  120. static void do_ex_tag __ARGS((EXARG *eap, int dt));
  121. #ifdef WANT_EVAL
  122. static char_u *do_if __ARGS((EXARG *eap, struct condstack *cstack));
  123. static char_u *do_else __ARGS((EXARG *eap, struct condstack *cstack));
  124. static char_u *do_while __ARGS((EXARG *eap, struct condstack *cstack));
  125. static char_u *do_continue __ARGS((struct condstack *cstack));
  126. static char_u *do_break __ARGS((struct condstack *cstack));
  127. static char_u *do_endwhile __ARGS((struct condstack *cstack));
  128. static int has_while_cmd __ARGS((char_u *p));
  129. static int did_endif = FALSE; /* just had ":endif" */
  130. #endif
  131. static int makeopens __ARGS((FILE *fd));
  132. static int put_eol __ARGS((FILE *fd));
  133. static void cmd_source __ARGS((char_u *fname, int forceit));
  134. #ifdef USER_COMMANDS
  135. static int uc_add_command __ARGS((char_u *name, size_t name_len, char_u *rep, long argt, long def, int compl, int force));
  136. static void uc_list __ARGS((char_u *name, size_t name_len));
  137. static int uc_scan_attr __ARGS((char_u *attr, size_t len, long *argt, long *def, int *compl));
  138. static void do_command __ARGS((EXARG *eap));
  139. static void do_comclear __ARGS((void));
  140. static void do_delcommand __ARGS((EXARG *eap));
  141. static char_u *uc_split_args __ARGS((char_u *arg, size_t *lenp));
  142. static size_t uc_check_code __ARGS((char_u *code, size_t len, char_u *buf, UCMD *cmd, EXARG *eap, char_u **split_buf, size_t *split_len));
  143. static void do_ucmd __ARGS((UCMD *cmd, EXARG *eap));
  144. #endif
  145. #if defined(GUI_DIALOG) || defined(CON_DIALOG)
  146. static void dialog_msg __ARGS((char_u *buff, char *format, char_u *fname));
  147. #endif
  148. static void ex_behave __ARGS((char_u *arg));
  149. /*
  150.  * Table used to quickly search for a command, based on its first character.
  151.  */
  152. CMDIDX cmdidxs[27] =
  153. {
  154. CMD_append,
  155. CMD_buffer,
  156. CMD_change,
  157. CMD_delete,
  158. CMD_edit,
  159. CMD_file,
  160. CMD_global,
  161. CMD_help,
  162. CMD_insert,
  163. CMD_join,
  164. CMD_k,
  165. CMD_list,
  166. CMD_move,
  167. CMD_next,
  168. CMD_open,
  169. CMD_print,
  170. CMD_quit,
  171. CMD_read,
  172. CMD_substitute,
  173. CMD_t,
  174. CMD_undo,
  175. CMD_vglobal,
  176. CMD_write,
  177. CMD_xit,
  178. CMD_yank,
  179. CMD_z,
  180. CMD_Next
  181. };
  182. /*
  183.  * do_exmode(): Repeatedly get commands for the "Ex" mode, until the ":vi"
  184.  * command is given.
  185.  */
  186.     void
  187. do_exmode()
  188. {
  189.     int save_msg_scroll;
  190.     int prev_msg_row;
  191.     linenr_t prev_line;
  192.     save_msg_scroll = msg_scroll;
  193.     ++RedrawingDisabled;     /* don't redisplay the window */
  194.     ++no_wait_return;     /* don't wait for return */
  195.     settmode(TMODE_COOK);
  196.     State = NORMAL;
  197.     exmode_active = TRUE;
  198. #ifdef USE_SNIFF
  199.     want_sniff_request = 0;    /* No K_SNIFF wanted */
  200. #endif
  201.     MSG("Entering Ex mode.  Type "visual" to get out.");
  202.     while (exmode_active)
  203.     {
  204. msg_scroll = TRUE;
  205. need_wait_return = FALSE;
  206. ex_pressedreturn = FALSE;
  207. ex_no_reprint = FALSE;
  208. prev_msg_row = msg_row;
  209. prev_line = curwin->w_cursor.lnum;
  210. #ifdef USE_SNIFF
  211. ProcessSniffRequests();
  212. #endif
  213. do_cmdline(NULL, getexmodeline, NULL, DOCMD_NOWAIT);
  214. lines_left = Rows - 1;
  215. if (prev_line != curwin->w_cursor.lnum && !ex_no_reprint)
  216. {
  217.     if (ex_pressedreturn)
  218.     {
  219. /* go up one line, to overwrite the ":<CR>" line, so the
  220.  * output doensn't contain empty lines. */
  221. msg_row = prev_msg_row;
  222. if (prev_msg_row == Rows - 1)
  223.     msg_row--;
  224.     }
  225.     msg_col = 0;
  226.     print_line_no_prefix(curwin->w_cursor.lnum, FALSE);
  227.     msg_clr_eos();
  228. }
  229. else if (ex_pressedreturn) /* must be at EOF */
  230.     EMSG("At end-of-file");
  231.     }
  232.     settmode(TMODE_RAW);
  233.     --RedrawingDisabled;
  234.     --no_wait_return;
  235.     update_screen(CLEAR);
  236.     need_wait_return = FALSE;
  237.     msg_scroll = save_msg_scroll;
  238. }
  239. /*
  240.  * do_cmdline(): execute one Ex command line
  241.  *
  242.  * 1. Execute "cmdline" when it is not NULL.
  243.  *    If "cmdline" is NULL, or more lines are needed, getline() is used.
  244.  * 2. Split up in parts separated with '|'.
  245.  *
  246.  * This function can be called recursively!
  247.  *
  248.  * flags:
  249.  * DOCMD_VERBOSE - The command will be included in the error message.
  250.  * DOCMD_NOWAIT  - Don't call wait_return() and friends.
  251.  * DOCMD_REPEAT  - Repeat execution until getline() returns NULL.
  252.  *
  253.  * return FAIL if cmdline could not be executed, OK otherwise
  254.  */
  255.     int
  256. do_cmdline(cmdline, getline, cookie, flags)
  257.     char_u *cmdline;
  258.     char_u *(*getline) __ARGS((int, void *, int));
  259.     void *cookie; /* argument for getline() */
  260.     int flags;
  261. {
  262.     char_u *next_cmdline; /* next cmd to execute */
  263.     char_u *cmdline_copy = NULL; /* copy of cmd line */
  264.     static int recursive = 0; /* recursive depth */
  265.     int msg_didout_before_start = 0;
  266.     int count = 0; /* line number count */
  267.     int did_inc = FALSE; /* incremented RedrawingDisabled */
  268.     int retval = OK;
  269. #ifdef USE_BROWSE
  270.     int save_browse = browse;
  271. #endif
  272. #if defined(GUI_DIALOG) || defined(CON_DIALOG)
  273.     int save_confirm = confirm;
  274. #endif
  275. #ifdef WANT_EVAL
  276.     struct condstack cstack; /* conditional stack */
  277.     struct growarray lines_ga; /* keep lines for ":while" */
  278.     int current_line = 0; /* active line in lines_ga */
  279. #endif
  280. #ifdef WANT_EVAL
  281.     cstack.cs_idx = -1;
  282.     cstack.cs_whilelevel = 0;
  283.     cstack.cs_had_while = FALSE;
  284.     cstack.cs_had_endwhile = FALSE;
  285.     cstack.cs_had_continue = FALSE;
  286.     ga_init2(&lines_ga, (int)sizeof(char_u *), 10);
  287. #endif
  288.     /*
  289.      * Reset browse and confirm.  They are restored when returning, for
  290.      * recursive calls.
  291.      */
  292. #ifdef USE_BROWSE
  293.     browse = FALSE;
  294. #endif
  295. #if defined(GUI_DIALOG) || defined(CON_DIALOG)
  296.     confirm = FALSE;
  297. #endif
  298.     /*
  299.      * "did_emsg" will be set to TRUE when emsg() is used, in which case we
  300.      * cancel the whole command line, and any if/endif while/endwhile loop.
  301.      */
  302.     did_emsg = FALSE;
  303.     /*
  304.      * KeyTyped is only set when calling vgetc().  Reset it here when not
  305.      * calling vgetc() (sourced command lines).
  306.      */
  307.     if (getline != getexline)
  308. KeyTyped = FALSE;
  309.     /*
  310.      * Continue executing command lines:
  311.      * - when inside an ":if" or ":while"
  312.      * - for multiple commands on one line, separated with '|'
  313.      * - when repeating until there are no more lines (for ":source")
  314.      */
  315.     next_cmdline = cmdline;
  316.     do
  317.     {
  318. /* stop skipping cmds for an error msg after all endifs and endwhiles */
  319. if (next_cmdline == NULL
  320. #ifdef WANT_EVAL
  321. && cstack.cs_idx < 0
  322. #endif
  323. )
  324.     did_emsg = FALSE;
  325. /*
  326.  * 1. If repeating a line with ":while", get a line from lines_ga.
  327.  * 2. If no line given: Get an allocated line with getline().
  328.  * 3. If a line is given: Make a copy, so we can mess with it.
  329.  */
  330. #ifdef WANT_EVAL
  331. /* 1. If repeating, get a previous line from lines_ga. */
  332. if (cstack.cs_whilelevel && current_line < lines_ga.ga_len)
  333. {
  334.     /* Each '|' separated command is stored separately in lines_ga, to
  335.      * be able to jump to it.  Don't use next_cmdline now. */
  336.     vim_free(cmdline_copy);
  337.     cmdline_copy = NULL;
  338.     /* Check if a function has returned or aborted */
  339.     if (getline == get_func_line && func_has_ended(cookie))
  340.     {
  341. retval = FAIL;
  342. break;
  343.     }
  344.     next_cmdline = ((char_u **)(lines_ga.ga_data))[current_line];
  345. }
  346. #endif
  347. /* 2. If no line given, get an allocated line with getline(). */
  348. if (next_cmdline == NULL)
  349. {
  350.     /*
  351.      * Need to set msg_didout for the first line after an ":if",
  352.      * otherwise the ":if" will be overwritten.
  353.      */
  354.     if (count == 1 && getline == getexline)
  355. msg_didout = TRUE;
  356.     if (getline == NULL || (next_cmdline = getline(':', cookie,
  357. #ifdef WANT_EVAL
  358.     cstack.cs_idx < 0 ? 0 : (cstack.cs_idx + 1) * 2
  359. #else
  360.     0
  361. #endif
  362.     )) == NULL)
  363.     {
  364. /* don't call wait_return for aborted command line */
  365. if (KeyTyped)
  366.     need_wait_return = FALSE;
  367. retval = FAIL;
  368. break;
  369.     }
  370. }
  371. /* 3. Make a copy of the command so we can mess with it. */
  372. else if (cmdline_copy == NULL)
  373. {
  374.     next_cmdline = vim_strsave(next_cmdline);
  375.     if (next_cmdline == NULL)
  376.     {
  377. retval = FAIL;
  378. break;
  379.     }
  380. }
  381. cmdline_copy = next_cmdline;
  382. #ifdef WANT_EVAL
  383. /*
  384.  * Save the current line when inside a ":while", and when the command
  385.  * looks like a ":while", because we may need it later.
  386.  * When there is a '|' and another command, it is stored separately,
  387.  * because we need to be able to jump back to it from an :endwhile.
  388.  */
  389. if (    current_line == lines_ga.ga_len
  390. && (cstack.cs_whilelevel || has_while_cmd(next_cmdline))
  391. && ga_grow(&lines_ga, 1) == OK)
  392. {
  393.     ((char_u **)(lines_ga.ga_data))[current_line] =
  394.     vim_strsave(next_cmdline);
  395.     ++lines_ga.ga_len;
  396.     --lines_ga.ga_room;
  397. }
  398. did_endif = FALSE;
  399. #endif
  400. if (count++ == 0)
  401. {
  402.     /*
  403.      * All output from the commands is put below each other, without
  404.      * waiting for a return. Don't do this when executing commands
  405.      * from a script or when being called recursive (e.g. for ":e
  406.      * +command file").
  407.      */
  408.     if (!(flags & DOCMD_NOWAIT) && !recursive)
  409.     {
  410. msg_didout_before_start = msg_didout;
  411. msg_didany = FALSE; /* no output yet */
  412. msg_start();
  413. msg_scroll = TRUE;  /* put messages below each other */
  414. ++no_wait_return;   /* dont wait for return until finished */
  415. ++RedrawingDisabled;
  416. did_inc = TRUE;
  417.     }
  418. }
  419. /*
  420.  * 2. Execute one '|' separated command.
  421.  *    do_one_cmd() will return NULL if there is no trailing '|'.
  422.  *    "cmdline_copy" can change, e.g. for '%' and '#' expansion.
  423.  */
  424. ++recursive;
  425. next_cmdline = do_one_cmd(&cmdline_copy, flags & DOCMD_VERBOSE,
  426. #ifdef WANT_EVAL
  427. &cstack,
  428. #endif
  429. getline, cookie);
  430. --recursive;
  431. if (next_cmdline == NULL)
  432. {
  433.     vim_free(cmdline_copy);
  434.     cmdline_copy = NULL;
  435.     /*
  436.      * If the command was typed, remember it for the ':' register.
  437.      * Do this AFTER executing the command to make :@: work.
  438.      */
  439.     if (getline == getexline && new_last_cmdline != NULL)
  440.     {
  441. vim_free(last_cmdline);
  442. last_cmdline = new_last_cmdline;
  443. new_last_cmdline = NULL;
  444.     }
  445. }
  446. else
  447. {
  448.     /* need to copy the command after the '|' to cmdline_copy, for the
  449.      * next do_one_cmd() */
  450.     mch_memmove(cmdline_copy, next_cmdline, STRLEN(next_cmdline) + 1);
  451.     next_cmdline = cmdline_copy;
  452. }
  453. #ifdef WANT_EVAL
  454. /* reset did_emsg for a function that is not aborted by an error */
  455. if (did_emsg && getline == get_func_line && !func_has_abort(cookie))
  456.     did_emsg = FALSE;
  457. if (cstack.cs_whilelevel)
  458. {
  459.     ++current_line;
  460.     /*
  461.      * An ":endwhile" and ":continue" is handled here.
  462.      * If we were executing commands, jump back to the ":while".
  463.      * If we were not executing commands, decrement whilelevel.
  464.      */
  465.     if (cstack.cs_had_endwhile || cstack.cs_had_continue)
  466.     {
  467. if (cstack.cs_had_endwhile)
  468.     cstack.cs_had_endwhile = FALSE;
  469. else
  470.     cstack.cs_had_continue = FALSE;
  471. /* jump back to the matching ":while"? */
  472. if (!did_emsg && cstack.cs_idx >= 0
  473. && (cstack.cs_flags[cstack.cs_idx] & CSF_ACTIVE))
  474. {
  475.     current_line = cstack.cs_line[cstack.cs_idx];
  476.     cstack.cs_had_while = TRUE; /* note we jumped there */
  477.     line_breakcheck(); /* check if CTRL-C typed */
  478. }
  479. else /* can only get here with ":endwhile" */
  480. {
  481.     --cstack.cs_whilelevel;
  482.     if (cstack.cs_idx >= 0)
  483. --cstack.cs_idx;
  484. }
  485.     }
  486.     /*
  487.      * For a ":while" we need to remember the line number.
  488.      */
  489.     else if (cstack.cs_had_while)
  490.     {
  491. cstack.cs_had_while = FALSE;
  492. cstack.cs_line[cstack.cs_idx] = current_line - 1;
  493.     }
  494. }
  495. /*
  496.  * When not inside a ":while", clear remembered lines.
  497.  */
  498. if (!cstack.cs_whilelevel)
  499. {
  500.     free_cmdlines(&lines_ga);
  501.     current_line = 0;
  502. }
  503. #endif /* WANT_EVAL */
  504.     }
  505.     /*
  506.      * Continue executing command lines when:
  507.      * - no CTRL-C typed
  508.      * - didn't get an error message or lines are not typed
  509.      * - there is a command after '|', inside a :if or :while, or looping for
  510.      *  ":source" command.
  511.      */
  512.     while (!got_int
  513.     && !(did_emsg && (getline == getexmodeline || getline == getexline))
  514.     && (next_cmdline != NULL
  515. #ifdef WANT_EVAL
  516. || cstack.cs_idx >= 0
  517. #endif
  518. || (flags & DOCMD_REPEAT)));
  519.     vim_free(cmdline_copy);
  520. #ifdef WANT_EVAL
  521.     free_cmdlines(&lines_ga);
  522.     ga_clear(&lines_ga);
  523. #endif
  524.     /*
  525.      * If there was too much output to fit on the command line, ask the user to
  526.      * hit return before redrawing the screen. With the ":global" command we do
  527.      * this only once after the command is finished.
  528.      */
  529.     if (did_inc)
  530.     {
  531. --RedrawingDisabled;
  532. --no_wait_return;
  533. msg_scroll = FALSE;
  534. /*
  535.  * When just finished an ":if"-":else" which was typed, no need to
  536.  * wait for hit-return.  Also for an error situation.
  537.  */
  538. if (retval == FAIL
  539. #ifdef WANT_EVAL
  540. || (did_endif && KeyTyped && !did_emsg)
  541. #endif
  542.     )
  543. {
  544.     need_wait_return = FALSE;
  545.     msg_didany = FALSE; /* don't wait when restarting edit */
  546.     redraw_later(NOT_VALID);
  547. }
  548. else if ((need_wait_return || (msg_check() && !dont_wait_return)))
  549. {
  550.     /*
  551.      * The msg_start() above clears msg_didout. The wait_return we do
  552.      * here should not overwrite the command that may be shown before
  553.      * doing that.
  554.      */
  555.     msg_didout = msg_didout_before_start;
  556.     wait_return(FALSE);
  557. }
  558.     }
  559. #ifdef USE_BROWSE
  560.     browse = save_browse;
  561. #endif
  562. #if defined(GUI_DIALOG) || defined(CON_DIALOG)
  563.     confirm = save_confirm;
  564. #endif
  565.     return retval;
  566. }
  567. #ifdef WANT_EVAL
  568.     static void
  569. free_cmdlines(gap)
  570.     struct growarray *gap;
  571. {
  572.     while (gap->ga_len)
  573.     {
  574. vim_free(((char_u **)(gap->ga_data))[gap->ga_len - 1]);
  575. --gap->ga_len;
  576. ++gap->ga_room;
  577.     }
  578. }
  579. #endif
  580. /*
  581.  * Execute one Ex command.
  582.  *
  583.  * If 'sourcing' is TRUE, the command will be included in the error message.
  584.  *
  585.  * 2. skip comment lines and leading space
  586.  * 3. parse range
  587.  * 4. parse command
  588.  * 5. parse arguments
  589.  * 6. switch on command name
  590.  *
  591.  * Note: "getline" can be NULL.
  592.  *
  593.  * This function may be called recursively!
  594.  */
  595.     static char_u *
  596. do_one_cmd(cmdlinep, sourcing,
  597. #ifdef WANT_EVAL
  598.     cstack,
  599. #endif
  600.     getline, cookie)
  601.     char_u **cmdlinep;
  602.     int sourcing;
  603. #ifdef WANT_EVAL
  604.     struct condstack *cstack;
  605. #endif
  606.     char_u *(*getline) __ARGS((int, void *, int));
  607.     void *cookie; /* argument for getline() */
  608. {
  609.     char_u *p;
  610.     int i;
  611.     linenr_t lnum;
  612.     long n;
  613.     char_u *errormsg = NULL; /* error message */
  614.     EXARG ea; /* Ex command arguments */
  615.     vim_memset(&ea, 0, sizeof(ea));
  616.     ea.line1 = 1;
  617.     ea.line2 = 1;
  618. /* when not editing the last file :q has to be typed twice */
  619.     if (quitmore)
  620. --quitmore;
  621. /*
  622.  * 2. skip comment lines and leading space and colons
  623.  */
  624.     for (ea.cmd = *cmdlinep; *ea.cmd == ' ' || *ea.cmd == 't'
  625.   || *ea.cmd == ':'; ea.cmd++)
  626. ;
  627.     /* in ex mode, an empty line works like :+ */
  628.     if (*ea.cmd == NUL && exmode_active && getline == getexmodeline)
  629.     {
  630. ea.cmd = (char_u *)"+";
  631. ex_pressedreturn = TRUE;
  632.     }
  633.     if (*ea.cmd == '"' || *ea.cmd == NUL)   /* ignore comment and empty lines */
  634. goto doend;
  635. #ifdef WANT_EVAL
  636.     ea.skip = did_emsg || (cstack->cs_idx >= 0
  637.  && !(cstack->cs_flags[cstack->cs_idx] & CSF_ACTIVE));
  638. #else
  639.     ea.skip = FALSE;
  640. #endif
  641. /*
  642.  * 3. parse a range specifier of the form: addr [,addr] [;addr] ..
  643.  *
  644.  * where 'addr' is:
  645.  *
  646.  * %       (entire file)
  647.  * $  [+-NUM]
  648.  * 'x [+-NUM] (where x denotes a currently defined mark)
  649.  * .  [+-NUM]
  650.  * [+-NUM]..
  651.  * NUM
  652.  *
  653.  * The ea.cmd pointer is updated to point to the first character following the
  654.  * range spec. If an initial address is found, but no second, the upper bound
  655.  * is equal to the lower.
  656.  */
  657.     /* repeat for all ',' or ';' separated addresses */
  658.     for (;;)
  659.     {
  660. ea.line1 = ea.line2;
  661. ea.line2 = curwin->w_cursor.lnum;   /* default is current line number */
  662. ea.cmd = skipwhite(ea.cmd);
  663. lnum = get_address(&ea.cmd, ea.skip);
  664. if (ea.cmd == NULL)     /* error detected */
  665.     goto doend;
  666. if (lnum == MAXLNUM)
  667. {
  668.     if (*ea.cmd == '%')     /* '%' - all lines */
  669.     {
  670. ++ea.cmd;
  671. ea.line1 = 1;
  672. ea.line2 = curbuf->b_ml.ml_line_count;
  673. ++ea.addr_count;
  674.     }
  675.     /* '*' - visual area */
  676.     else if (*ea.cmd == '*' && vim_strchr(p_cpo, CPO_STAR) == NULL)
  677.     {
  678. FPOS     *fp;
  679. ++ea.cmd;
  680. #ifdef WANT_EVAL
  681. if (!ea.skip)
  682. #endif
  683. {
  684.     fp = getmark('<', FALSE);
  685.     if (check_mark(fp) == FAIL)
  686. goto doend;
  687.     ea.line1 = fp->lnum;
  688.     fp = getmark('>', FALSE);
  689.     if (check_mark(fp) == FAIL)
  690. goto doend;
  691.     ea.line2 = fp->lnum;
  692.     ++ea.addr_count;
  693. }
  694.     }
  695. }
  696. else
  697.     ea.line2 = lnum;
  698. ea.addr_count++;
  699. if (*ea.cmd == ';')
  700. {
  701. #ifdef WANT_EVAL
  702.     if (!ea.skip)
  703. #endif
  704. curwin->w_cursor.lnum = ea.line2;
  705. }
  706. else if (*ea.cmd != ',')
  707.     break;
  708. ++ea.cmd;
  709.     }
  710.     /* One address given: set start and end lines */
  711.     if (ea.addr_count == 1)
  712.     {
  713. ea.line1 = ea.line2;
  714.     /* ... but only implicit: really no address given */
  715. if (lnum == MAXLNUM)
  716.     ea.addr_count = 0;
  717.     }
  718.     /* Don't leave the cursor on an illegal line (caused by ';') */
  719.     check_cursor_lnum();
  720. /*
  721.  * 4. parse command
  722.  */
  723.     /*
  724.      * Skip ':' and any white space
  725.      */
  726.     ea.cmd = skipwhite(ea.cmd);
  727.     while (*ea.cmd == ':')
  728. ea.cmd = skipwhite(ea.cmd + 1);
  729.     /*
  730.      * If we got a line, but no command, then go to the line.
  731.      * If we find a '|' or 'n' we set ea.nextcmd.
  732.      */
  733.     if (*ea.cmd == NUL || *ea.cmd == '"' ||
  734.        (ea.nextcmd = check_nextcmd(ea.cmd)) != NULL)
  735.     {
  736. /*
  737.  * strange vi behaviour:
  738.  * ":3" jumps to line 3
  739.  * ":3|..." prints line 3
  740.  * ":|" prints current line
  741.  */
  742. #ifdef WANT_EVAL
  743. if (ea.skip)     /* skip this if inside :if */
  744.     goto doend;
  745. #endif
  746. if (*ea.cmd == '|')
  747. {
  748.     ea.cmdidx = CMD_print;
  749.     ea.argt = RANGE+COUNT+TRLBAR;
  750.     if ((errormsg = invalid_range(&ea)) == NULL)
  751.     {
  752. correct_range(&ea);
  753. do_print(&ea);
  754.     }
  755. }
  756. else if (ea.addr_count != 0)
  757. {
  758.     if (ea.line2 == 0)
  759. curwin->w_cursor.lnum = 1;
  760.     else if (ea.line2 > curbuf->b_ml.ml_line_count)
  761. curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
  762.     else
  763. curwin->w_cursor.lnum = ea.line2;
  764.     beginline(BL_SOL | BL_FIX);
  765. }
  766. goto doend;
  767.     }
  768.     /*
  769.      * Isolate the command and search for it in the command table.
  770.      * Exeptions:
  771.      * - the 'k' command can directly be followed by any character.
  772.      * - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
  773.      *     but :sre[wind] is another command, as is :sim[alt].
  774.      */
  775.     if (*ea.cmd == 'k')
  776.     {
  777. ea.cmdidx = CMD_k;
  778. p = ea.cmd + 1;
  779.     }
  780.     else if (ea.cmd[0] == 's'
  781.     && (ea.cmd[1] == 'c'
  782. || ea.cmd[1] == 'g'
  783. || (ea.cmd[1] == 'i' && ea.cmd[2] != 'm')
  784. || ea.cmd[1] == 'I'
  785. || (ea.cmd[1] == 'r' && ea.cmd[2] != 'e')))
  786.     {
  787. ea.cmdidx = CMD_substitute;
  788. p = ea.cmd + 1;
  789.     }
  790.     else
  791.     {
  792. p = ea.cmd;
  793. while (isalpha(*p))
  794.     ++p;
  795. /* check for non-alpha command */
  796. if (p == ea.cmd && vim_strchr((char_u *)"@*!=><&~#", *p) != NULL)
  797.     ++p;
  798. i = (int)(p - ea.cmd);
  799. if (*ea.cmd >= 'a' && *ea.cmd <= 'z')
  800.     ea.cmdidx = cmdidxs[*ea.cmd - 'a'];
  801. else
  802.     ea.cmdidx = cmdidxs[26];
  803. for ( ; (int)ea.cmdidx < (int)CMD_SIZE;
  804.      ea.cmdidx = (CMDIDX)((int)ea.cmdidx + 1))
  805.     if (STRNCMP(cmdnames[(int)ea.cmdidx].cmd_name, (char *)ea.cmd,
  806.       (size_t)i) == 0)
  807. break;
  808. #ifdef USER_COMMANDS
  809. /* Look for a user defined command as a last resort */
  810. if (ea.cmdidx == CMD_SIZE)
  811. {
  812.     UCMD    *cmd = USER_CMD(0);
  813.     int     j;
  814.     int     found = FALSE;
  815.     for (j = 0; j < ucmds.ga_len; ++j, ++cmd)
  816.     {
  817. if (STRNCMP(cmd->uc_name, (char *)ea.cmd, (size_t)i) == 0)
  818. {
  819.     if (found)
  820.     {
  821. errormsg = (char_u *)"Ambiguous use of user-defined command";
  822. goto doend;
  823.     }
  824.     found = TRUE;
  825.     ea.cmdidx = CMD_USER;
  826.     ea.argt = cmd->uc_argt;
  827.     ea.useridx = j;
  828.     /* Do not search for further abbreviations
  829.      * if this is an exact match
  830.      */
  831.     if ((size_t)i == STRLEN(cmd->uc_name))
  832. break;
  833. }
  834.     }
  835. }
  836. #endif
  837. if (i == 0 || ea.cmdidx == CMD_SIZE)
  838. {
  839. #ifdef WANT_EVAL
  840.     if (!ea.skip)
  841. #endif
  842.     {
  843. STRCPY(IObuff, "Not an editor command");
  844. if (!sourcing)
  845. {
  846.     STRCAT(IObuff, ": ");
  847.     STRNCAT(IObuff, *cmdlinep, 40);
  848. }
  849. errormsg = IObuff;
  850.     }
  851.     goto doend;
  852. }
  853.     }
  854.     if (*p == '!' && ea.cmdidx != CMD_substitute)    /* forced commands */
  855.     {
  856. ++p;
  857. ea.forceit = TRUE;
  858.     }
  859.     else
  860. ea.forceit = FALSE;
  861. /*
  862.  * 5. parse arguments
  863.  */
  864. #ifdef USER_COMMANDS
  865.     if (ea.cmdidx != CMD_USER)
  866. #endif
  867. ea.argt = cmdnames[(int)ea.cmdidx].cmd_argt;
  868.     if (!(ea.argt & RANGE) && ea.addr_count) /* no range allowed */
  869.     {
  870. errormsg = e_norange;
  871. goto doend;
  872.     }
  873.     if (!(ea.argt & BANG) && ea.forceit) /* no <!> allowed */
  874.     {
  875. errormsg = e_nobang;
  876. if (ea.cmdidx == CMD_help)
  877.     errormsg = (char_u *)"Don't panic!";
  878. goto doend;
  879.     }
  880.     /*
  881.      * If the range is backwards, ask for confirmation and, if given, swap
  882.      * ea.line1 & ea.line2 so it's forwards again.
  883.      * When global command is busy, don't ask, will fail below.
  884.      */
  885.     if (!global_busy && ea.line1 > ea.line2)
  886.     {
  887. if (sourcing)
  888. {
  889.     errormsg = (char_u *)"Backwards range given";
  890.     goto doend;
  891. }
  892. else if (ask_yesno((char_u *)
  893.    "Backwards range given, OK to swap", FALSE) != 'y')
  894.     goto doend;
  895. lnum = ea.line1;
  896. ea.line1 = ea.line2;
  897. ea.line2 = lnum;
  898.     }
  899.     /*
  900.      * don't complain about the range if it is not used
  901.      * (could happen if line_count is accidently set to 0)
  902.      */
  903.     if (!ea.skip && (errormsg = invalid_range(&ea)) != NULL)
  904. goto doend;
  905.     if ((ea.argt & NOTADR) && ea.addr_count == 0) /* default is 1, not cursor */
  906. ea.line2 = 1;
  907.     correct_range(&ea);
  908. #ifdef QUICKFIX
  909.     /*
  910.      * For the :make command we insert the 'makeprg' option here,
  911.      * so things like % get expanded.
  912.      */
  913.     if (ea.cmdidx == CMD_make || ea.cmdidx == CMD_grep)
  914.     {
  915. char_u *new_cmdline;
  916. char_u *program;
  917. program = (ea.cmdidx == CMD_grep) ? p_gp : p_mp;
  918. new_cmdline = alloc((int)(STRLEN(program) + STRLEN(p) + 2));
  919. if (new_cmdline == NULL)
  920.     goto doend;     /* out of memory */
  921. STRCPY(new_cmdline, program);
  922. STRCAT(new_cmdline, " ");
  923. STRCAT(new_cmdline, p);
  924. msg_make(p);
  925. /* 'ea.cmd' is not set here, because it is not used at CMD_make */
  926. vim_free(*cmdlinep);
  927. *cmdlinep = new_cmdline;
  928. p = new_cmdline;
  929.     }
  930. #endif
  931.     /*
  932.      * Skip to start of argument.
  933.      * Don't do this for the ":!" command, because ":!! -l" needs the space.
  934.      */
  935.     if (ea.cmdidx == CMD_bang)
  936. ea.arg = p;
  937.     else
  938. ea.arg = skipwhite(p);
  939.     if (ea.cmdidx == CMD_write || ea.cmdidx == CMD_update)
  940.     {
  941. if (*ea.arg == '>') /* append */
  942. {
  943.     if (*++ea.arg != '>') /* typed wrong */
  944.     {
  945. errormsg = (char_u *)"Use w or w>>";
  946. goto doend;
  947.     }
  948.     ea.arg = skipwhite(ea.arg + 1);
  949.     ea.append = TRUE;
  950. }
  951. else if (*ea.arg == '!' && ea.cmdidx == CMD_write)  /* :w !filter */
  952. {
  953.     ++ea.arg;
  954.     ea.usefilter = TRUE;
  955. }
  956.     }
  957.     if (ea.cmdidx == CMD_read)
  958.     {
  959. if (ea.forceit)
  960. {
  961.     ea.usefilter = TRUE; /* :r! filter if ea.forceit */
  962.     ea.forceit = FALSE;
  963. }
  964. else if (*ea.arg == '!') /* :r !filter */
  965. {
  966.     ++ea.arg;
  967.     ea.usefilter = TRUE;
  968. }
  969.     }
  970.     if (ea.cmdidx == CMD_lshift || ea.cmdidx == CMD_rshift)
  971.     {
  972. ea.amount = 1;
  973. while (*ea.arg == *ea.cmd) /* count number of '>' or '<' */
  974. {
  975.     ++ea.arg;
  976.     ++ea.amount;
  977. }
  978. ea.arg = skipwhite(ea.arg);
  979.     }
  980.     /*
  981.      * Check for "+command" argument, before checking for next command.
  982.      * Don't do this for ":read !cmd" and ":write !cmd".
  983.      */
  984.     if ((ea.argt & EDITCMD) && !ea.usefilter)
  985. ea.do_ecmd_cmd = getargcmd(&ea.arg);
  986.     /*
  987.      * Check for '|' to separate commands and '"' to start comments.
  988.      * Don't do this for ":read !cmd" and ":write !cmd".
  989.      */
  990.     if ((ea.argt & TRLBAR) && !ea.usefilter)
  991. separate_nextcmd(&ea);
  992.     /*
  993.      * Check for <newline> to end a shell command.
  994.      * Also do this for ":read !cmd" and ":write !cmd".
  995.      */
  996.     else if (ea.cmdidx == CMD_bang || ea.usefilter)
  997.     {
  998. for (p = ea.arg; *p; ++p)
  999. {
  1000.     if (*p == '\' && p[1])
  1001. ++p;
  1002.     else if (*p == 'n')
  1003.     {
  1004. ea.nextcmd = p + 1;
  1005. *p = NUL;
  1006. break;
  1007.     }
  1008. }
  1009.     }
  1010.     if ((ea.argt & DFLALL) && ea.addr_count == 0)
  1011.     {
  1012. ea.line1 = 1;
  1013. ea.line2 = curbuf->b_ml.ml_line_count;
  1014.     }
  1015.     /* accept numbered register only when no count allowed (:put) */
  1016.     if (       (ea.argt & REGSTR)
  1017.     && *ea.arg != NUL
  1018. #ifdef USER_COMMANDS
  1019.     && valid_yank_reg(*ea.arg, (ea.cmdidx != CMD_put
  1020.     && ea.cmdidx != CMD_USER))
  1021.     /* Do not allow register = for user commands */
  1022.     && (ea.cmdidx != CMD_USER || *ea.arg != '=')
  1023. #else
  1024.     && valid_yank_reg(*ea.arg, ea.cmdidx != CMD_put)
  1025. #endif
  1026.     && !((ea.argt & COUNT) && isdigit(*ea.arg)))
  1027.     {
  1028. ea.regname = *ea.arg++;
  1029. #ifdef WANT_EVAL
  1030. /* for '=' register: accept the rest of the line as an expression */
  1031. if (ea.arg[-1] == '=' && ea.arg[0] != NUL)
  1032. {
  1033.     set_expr_line(vim_strsave(ea.arg));
  1034.     ea.arg += STRLEN(ea.arg);
  1035. }
  1036. #endif
  1037. ea.arg = skipwhite(ea.arg);
  1038.     }
  1039.     /*
  1040.      * Check for a count.  When accepting a BUFNAME, don't use "123foo" as a
  1041.      * count, it's a buffer name.
  1042.      */
  1043.     if ((ea.argt & COUNT) && isdigit(*ea.arg)
  1044.     && (!(ea.argt & BUFNAME) || *(p = skipdigits(ea.arg)) == NUL
  1045.   || vim_iswhite(*p)))
  1046.     {
  1047. n = getdigits(&ea.arg);
  1048. ea.arg = skipwhite(ea.arg);
  1049. if (n <= 0)
  1050. {
  1051.     errormsg = e_zerocount;
  1052.     goto doend;
  1053. }
  1054. if (ea.argt & NOTADR) /* e.g. :buffer 2, :sleep 3 */
  1055. {
  1056.     ea.line2 = n;
  1057.     if (ea.addr_count == 0)
  1058. ea.addr_count = 1;
  1059. }
  1060. else
  1061. {
  1062.     ea.line1 = ea.line2;
  1063.     ea.line2 += n - 1;
  1064.     ++ea.addr_count;
  1065.     /*
  1066.      * Be vi compatible: no error message for out of range.
  1067.      */
  1068.     if (ea.line2 > curbuf->b_ml.ml_line_count)
  1069. ea.line2 = curbuf->b_ml.ml_line_count;
  1070. }
  1071.     }
  1072. /* no arguments allowed */
  1073.     if (!(ea.argt & EXTRA) && *ea.arg != NUL &&
  1074.  vim_strchr((char_u *)"|"", *ea.arg) == NULL)
  1075.     {
  1076. errormsg = e_trailing;
  1077. goto doend;
  1078.     }
  1079.     if ((ea.argt & NEEDARG) && *ea.arg == NUL)
  1080.     {
  1081. errormsg = e_argreq;
  1082. goto doend;
  1083.     }
  1084.     if (ea.argt & XFILE)
  1085.     {
  1086.  if (expand_filename(&ea, cmdlinep, &errormsg) == FAIL)
  1087.      goto doend;
  1088.     }
  1089. #ifdef WANT_EVAL
  1090.     /*
  1091.      * Skip the command when it's not going to be executed.
  1092.      * The commands like :if, :endif, etc. always need to be executed.
  1093.      * Also make an exception for commands that handle a trailing command
  1094.      * themselves.
  1095.      */
  1096.     if (ea.skip)
  1097.     {
  1098. switch (ea.cmdidx)
  1099. {
  1100.     /* commands that need evaluation */
  1101.     case CMD_while:
  1102.     case CMD_endwhile:
  1103.     case CMD_if:
  1104.     case CMD_elseif:
  1105.     case CMD_else:
  1106.     case CMD_endif:
  1107.     case CMD_function:
  1108. break;
  1109.     /* commands that handle '|' themselves */
  1110.     case CMD_call:
  1111.     case CMD_djump:
  1112.     case CMD_dlist:
  1113.     case CMD_dsearch:
  1114.     case CMD_dsplit:
  1115.     case CMD_echo:
  1116.     case CMD_echon:
  1117.     case CMD_execute:
  1118.     case CMD_help:
  1119.     case CMD_ijump:
  1120.     case CMD_ilist:
  1121.     case CMD_isearch:
  1122.     case CMD_isplit:
  1123.     case CMD_let:
  1124.     case CMD_return:
  1125.     case CMD_substitute:
  1126.     case CMD_smagic:
  1127.     case CMD_snomagic:
  1128.     case CMD_syntax:
  1129.     case CMD_and:
  1130.     case CMD_tilde:
  1131. break;
  1132.     default: goto doend;
  1133. }
  1134.     }
  1135. #endif
  1136.     /*
  1137.      * Accept buffer name.  Cannot be used at the same time with a buffer
  1138.      * number.
  1139.      */
  1140.     if ((ea.argt & BUFNAME) && *ea.arg && ea.addr_count == 0)
  1141.     {
  1142. /*
  1143.  * :bdelete and :bunload take several arguments, separated by spaces:
  1144.  * find next space (skipping over escaped characters).
  1145.  * The others take one argument: ignore trailing spaces.
  1146.  */
  1147. if (ea.cmdidx == CMD_bdelete || ea.cmdidx == CMD_bunload)
  1148.     p = skiptowhite_esc(ea.arg);
  1149. else
  1150. {
  1151.     p = ea.arg + STRLEN(ea.arg);
  1152.     while (p > ea.arg && vim_iswhite(p[-1]))
  1153. --p;
  1154. }
  1155. ea.line2 = buflist_findpat(ea.arg, p);
  1156. if (ea.line2 < 0)     /* failed */
  1157.     goto doend;
  1158. ea.addr_count = 1;
  1159. ea.arg = skipwhite(p);
  1160.     }
  1161. /*
  1162.  * 6. switch on command name
  1163.  *
  1164.  * The "ea" structure holds the arguments that can be used.
  1165.  */
  1166.     switch (ea.cmdidx)
  1167.     {
  1168. case CMD_quit:
  1169. do_quit(&ea);
  1170. break;
  1171. case CMD_qall:
  1172. do_quit_all(ea.forceit);
  1173. break;
  1174. case CMD_close:
  1175. do_close(&ea);
  1176. break;
  1177. case CMD_hide:
  1178. #ifdef USE_GUI
  1179. need_mouse_correct = TRUE;
  1180. #endif
  1181. close_window(curwin, FALSE); /* don't free buffer */
  1182. break;
  1183. case CMD_only:
  1184. #ifdef USE_GUI
  1185. need_mouse_correct = TRUE;
  1186. #endif
  1187. close_others(TRUE, ea.forceit);
  1188. break;
  1189. case CMD_stop:
  1190. case CMD_suspend:
  1191. do_suspend(ea.forceit);
  1192. break;
  1193. case CMD_exit:
  1194. case CMD_xit:
  1195. case CMD_wq:
  1196. do_exit(&ea);
  1197. break;
  1198. case CMD_xall:
  1199. case CMD_wqall:
  1200. exiting = TRUE;
  1201. /* FALLTHROUGH */
  1202. case CMD_wall:
  1203. do_wqall(&ea);
  1204. break;
  1205. case CMD_preserve:
  1206. ml_preserve(curbuf, TRUE);
  1207. break;
  1208. case CMD_recover:
  1209. do_recover(&ea);
  1210. break;
  1211. case CMD_args:
  1212. do_args(&ea);
  1213. break;
  1214. case CMD_wnext:
  1215. case CMD_wNext:
  1216. case CMD_wprevious:
  1217. do_wnext(&ea);
  1218. break;
  1219. case CMD_next:
  1220. case CMD_snext:
  1221. do_next(&ea);
  1222. break;
  1223. case CMD_previous:
  1224. case CMD_sprevious:
  1225. case CMD_Next:
  1226. case CMD_sNext:
  1227. do_argfile(&ea, curwin->w_arg_idx - (int)ea.line2);
  1228. break;
  1229. case CMD_rewind:
  1230. case CMD_srewind:
  1231. do_argfile(&ea, 0);
  1232. break;
  1233. case CMD_last:
  1234. case CMD_slast:
  1235. do_argfile(&ea, arg_file_count - 1);
  1236. break;
  1237. case CMD_argument:
  1238. case CMD_sargument:
  1239. if (ea.addr_count)
  1240.     i = ea.line2 - 1;
  1241. else
  1242.     i = curwin->w_arg_idx;
  1243. do_argfile(&ea, i);
  1244. break;
  1245. case CMD_all:
  1246. case CMD_sall:
  1247. if (ea.addr_count == 0)
  1248.     ea.line2 = 9999;
  1249. do_arg_all((int)ea.line2, ea.forceit);
  1250. break;
  1251. case CMD_buffer: /* :[N]buffer [N] to buffer N */
  1252. case CMD_sbuffer: /* :[N]sbuffer [N] to buffer N */
  1253. if (*ea.arg)
  1254.     errormsg = e_trailing;
  1255. else
  1256. {
  1257.     if (ea.addr_count == 0) /* default is current buffer */
  1258. (void)do_buffer(*ea.cmd == 's' ? DOBUF_SPLIT
  1259.        : DOBUF_GOTO,
  1260.        DOBUF_CURRENT, FORWARD, 0, ea.forceit);
  1261.     else
  1262. (void)do_buffer(*ea.cmd == 's' ? DOBUF_SPLIT
  1263.        : DOBUF_GOTO,
  1264.      DOBUF_FIRST, FORWARD, (int)ea.line2, ea.forceit);
  1265. }
  1266. break;
  1267. case CMD_bmodified: /* :[N]bmod [N] to next mod. buffer */
  1268. case CMD_sbmodified: /* :[N]sbmod [N] to next mod. buffer */
  1269. (void)do_buffer(*ea.cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO,
  1270.        DOBUF_MOD, FORWARD, (int)ea.line2, ea.forceit);
  1271. break;
  1272. case CMD_bnext: /* :[N]bnext [N] to next buffer */
  1273. case CMD_sbnext: /* :[N]sbnext [N] to next buffer */
  1274. (void)do_buffer(*ea.cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO,
  1275.    DOBUF_CURRENT, FORWARD, (int)ea.line2, ea.forceit);
  1276. break;
  1277. case CMD_bNext: /* :[N]bNext [N] to previous buffer */
  1278. case CMD_bprevious: /* :[N]bprevious [N] to previous buffer */
  1279. case CMD_sbNext: /* :[N]sbNext [N] to previous buffer */
  1280. case CMD_sbprevious: /* :[N]sbprevious [N] to previous buffer */
  1281. (void)do_buffer(*ea.cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO,
  1282.   DOBUF_CURRENT, BACKWARD, (int)ea.line2, ea.forceit);
  1283. break;
  1284. case CMD_brewind: /* :brewind to first buffer */
  1285. case CMD_sbrewind: /* :sbrewind to first buffer */
  1286. (void)do_buffer(*ea.cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO,
  1287.  DOBUF_FIRST, FORWARD, 0, ea.forceit);
  1288. break;
  1289. case CMD_blast: /* :blast to last buffer */
  1290. case CMD_sblast: /* :sblast to last buffer */
  1291. (void)do_buffer(*ea.cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO,
  1292.   DOBUF_LAST, FORWARD, 0, ea.forceit);
  1293. break;
  1294. case CMD_bunload: /* :[N]bunload[!] [N] [bufname] unload buffer */
  1295. case CMD_bdelete: /* :[N]bdelete[!] [N] [bufname] delete buffer */
  1296. errormsg = do_bufdel(ea.cmdidx == CMD_bdelete ? DOBUF_DEL
  1297.       : DOBUF_UNLOAD,
  1298.  ea.arg, ea.addr_count, (int)ea.line1,
  1299.    (int)ea.line2, ea.forceit);
  1300. break;
  1301. case CMD_unhide:
  1302. case CMD_sunhide:
  1303. if (ea.addr_count == 0)
  1304.     ea.line2 = 9999;
  1305. (void)do_buffer_all((int)ea.line2, FALSE);
  1306. break;
  1307. case CMD_ball:
  1308. case CMD_sball:
  1309. if (ea.addr_count == 0)
  1310.     ea.line2 = 9999;
  1311. (void)do_buffer_all((int)ea.line2, TRUE);
  1312. break;
  1313. case CMD_buffers:
  1314. case CMD_files:
  1315. case CMD_ls:
  1316. buflist_list();
  1317. break;
  1318. case CMD_update:
  1319. if (curbuf_changed())
  1320.     (void)do_write(&ea);
  1321. break;
  1322. case CMD_write:
  1323. if (ea.usefilter) /* input lines to shell command */
  1324.     do_bang(1, ea.line1, ea.line2, FALSE, ea.arg, TRUE, FALSE);
  1325. else
  1326.     (void)do_write(&ea);
  1327. break;
  1328. /*
  1329.  * set screen mode
  1330.  * if no argument given, just get the screen size and redraw
  1331.  */
  1332. case CMD_mode:
  1333. if (*ea.arg == NUL || mch_screenmode(ea.arg) != FAIL)
  1334.     set_winsize(0, 0, FALSE);
  1335. break;
  1336. case CMD_resize:
  1337. do_resize(&ea);
  1338. break;
  1339. case CMD_sview:
  1340. case CMD_split:
  1341. case CMD_new:
  1342. do_splitview(&ea);
  1343. break;
  1344. case CMD_edit:
  1345. case CMD_ex:
  1346. case CMD_visual:
  1347. case CMD_view:
  1348. case CMD_badd:
  1349. do_exedit(&ea, NULL);
  1350. break;
  1351. #ifdef USE_GUI
  1352. /*
  1353.  * Change from the terminal version to the GUI version.  File names
  1354.  * may be given to redefine the args list -- webb
  1355.  */
  1356. case CMD_gvim:
  1357. case CMD_gui:
  1358. do_gui(&ea);
  1359. break;
  1360. #endif
  1361. #ifdef USE_GUI_WIN32
  1362. case CMD_tearoff:
  1363. gui_make_tearoff(ea.arg);
  1364. break;
  1365. #endif
  1366. case CMD_behave:
  1367. ex_behave(ea.arg);
  1368. break;
  1369. case CMD_browse:
  1370. #ifdef USE_BROWSE
  1371. /* don't browse in an xterm! */
  1372. if (gui.in_use)
  1373.     browse = TRUE;
  1374. #endif
  1375. ea.nextcmd = ea.arg;
  1376. break;
  1377. #ifdef USE_GUI_WIN32
  1378. case CMD_simalt:
  1379. gui_simulate_alt_key(ea.arg);
  1380. break;
  1381. case CMD_promptfind:
  1382. gui_mch_find_dialog(ea.arg);
  1383. break;
  1384. case CMD_promptrepl:
  1385. gui_mch_replace_dialog(ea.arg);
  1386. break;
  1387. #endif
  1388. case CMD_confirm:
  1389. #if defined(GUI_DIALOG) || defined(CON_DIALOG)
  1390. confirm = TRUE;
  1391. #endif
  1392. ea.nextcmd = ea.arg;
  1393. break;
  1394. case CMD_file:
  1395. do_file(ea.arg, ea.forceit);
  1396. break;
  1397. case CMD_swapname:
  1398. do_swapname();
  1399. break;
  1400. case CMD_read:
  1401. do_read(&ea);
  1402. break;
  1403. case CMD_cd:
  1404. case CMD_chdir:
  1405. do_cd(&ea);
  1406. break;
  1407. case CMD_pwd:
  1408. do_pwd();
  1409. break;
  1410. case CMD_equal:
  1411. smsg((char_u *)"line %ld", (long)ea.line2);
  1412. break;
  1413. case CMD_list:
  1414. i = curwin->w_p_list;
  1415. curwin->w_p_list = 1;
  1416. do_print(&ea);
  1417. curwin->w_p_list = i;
  1418. break;
  1419. case CMD_number:
  1420. case CMD_pound: /* :# */
  1421. case CMD_print:
  1422. case CMD_Print: /* ":Print" does as ":print" */
  1423. do_print(&ea);
  1424. break;
  1425. case CMD_shell:
  1426. do_shell(NULL, 0);
  1427. break;
  1428. case CMD_sleep:
  1429. do_sleep(&ea);
  1430. break;
  1431. case CMD_stag:
  1432. postponed_split = -1;
  1433. /*FALLTHROUGH*/
  1434. case CMD_tag:
  1435. #ifdef USE_CSCOPE
  1436. if (p_cst)
  1437.     do_cstag(&ea);
  1438. else
  1439. #endif
  1440.     do_tag(ea.arg, DT_TAG,
  1441. ea.addr_count ? (int)ea.line2 : 1, ea.forceit, TRUE);
  1442. break;
  1443. case CMD_stselect:
  1444. postponed_split = -1;
  1445. /*FALLTHROUGH*/
  1446. case CMD_tselect:
  1447. do_tag(ea.arg, DT_SELECT, 0, ea.forceit, TRUE);
  1448. break;
  1449. case CMD_stjump:
  1450. postponed_split = -1;
  1451. /*FALLTHROUGH*/
  1452. case CMD_tjump:
  1453. do_tag(ea.arg, DT_JUMP, 0, ea.forceit, TRUE);
  1454. break;
  1455. case CMD_pop: do_ex_tag(&ea, DT_POP); break;
  1456. case CMD_tnext: do_ex_tag(&ea, DT_NEXT); break;
  1457. case CMD_tNext:
  1458. case CMD_tprevious: do_ex_tag(&ea, DT_PREV); break;
  1459. case CMD_trewind: do_ex_tag(&ea, DT_FIRST); break;
  1460. case CMD_tlast: do_ex_tag(&ea, DT_LAST); break;
  1461. case CMD_tags:
  1462. do_tags();
  1463. break;
  1464. #ifdef USE_CSCOPE
  1465. case CMD_cscope:
  1466. do_cscope(&ea);
  1467. break;
  1468. case CMD_cstag:
  1469. do_cstag(&ea);
  1470. break;
  1471. #endif
  1472. case CMD_marks:
  1473. do_marks(ea.arg);
  1474. break;
  1475. case CMD_jumps:
  1476. do_jumps();
  1477. break;
  1478. case CMD_ascii:
  1479. do_ascii();
  1480. break;
  1481. #ifdef FIND_IN_PATH
  1482. case CMD_checkpath:
  1483. find_pattern_in_path(NULL, 0, 0, FALSE, FALSE, CHECK_PATH, 1L,
  1484.    ea.forceit ? ACTION_SHOW_ALL : ACTION_SHOW,
  1485.       (linenr_t)1, (linenr_t)MAXLNUM);
  1486. break;
  1487. #endif
  1488. case CMD_digraphs:
  1489. #ifdef DIGRAPHS
  1490. if (*ea.arg)
  1491.     putdigraph(ea.arg);
  1492. else
  1493.     listdigraphs();
  1494. #else
  1495. EMSG("No digraphs in this version");
  1496. #endif
  1497. break;
  1498. case CMD_set:
  1499. (void)do_set(ea.arg);
  1500. break;
  1501. case CMD_fixdel:
  1502. do_fixdel();
  1503. break;
  1504. #ifdef AUTOCMD
  1505. case CMD_augroup:
  1506. case CMD_autocmd:
  1507. /*
  1508.  * Disallow auto commands from .exrc and .vimrc in current
  1509.  * directory for security reasons.
  1510.  */
  1511. if (secure)
  1512. {
  1513.     secure = 2;
  1514.     errormsg = e_curdir;
  1515. }
  1516. else if (ea.cmdidx == CMD_autocmd)
  1517.     do_autocmd(ea.arg, ea.forceit);
  1518. else
  1519.     do_augroup(ea.arg);
  1520. break;
  1521. /*
  1522.  * Apply the automatic commands to all loaded buffers.
  1523.  */
  1524. case CMD_doautoall:
  1525. do_autoall(ea.arg);
  1526. break;
  1527. /*
  1528.  * Apply the automatic commands to the current buffer.
  1529.  */
  1530. case CMD_doautocmd:
  1531. (void)do_doautocmd(ea.arg, TRUE);
  1532. do_modelines();
  1533. break;
  1534. #endif
  1535. case CMD_abbreviate:
  1536. case CMD_noreabbrev:
  1537. case CMD_unabbreviate:
  1538. case CMD_cabbrev:
  1539. case CMD_cnoreabbrev:
  1540. case CMD_cunabbrev:
  1541. case CMD_iabbrev:
  1542. case CMD_inoreabbrev:
  1543. case CMD_iunabbrev:
  1544. do_exmap(&ea, TRUE);     /* almost the same as mapping */
  1545. break;
  1546. case CMD_map:
  1547. case CMD_nmap:
  1548. case CMD_vmap:
  1549. case CMD_omap:
  1550. case CMD_cmap:
  1551. case CMD_imap:
  1552. case CMD_noremap:
  1553. case CMD_nnoremap:
  1554. case CMD_vnoremap:
  1555. case CMD_onoremap:
  1556. case CMD_cnoremap:
  1557. case CMD_inoremap:
  1558. /*
  1559.  * If we are sourcing .exrc or .vimrc in current directory we
  1560.  * print the mappings for security reasons.
  1561.  */
  1562. if (secure)
  1563. {
  1564.     secure = 2;
  1565.     msg_outtrans(ea.cmd);
  1566.     msg_putchar('n');
  1567. }
  1568. case CMD_unmap:
  1569. case CMD_nunmap:
  1570. case CMD_vunmap:
  1571. case CMD_ounmap:
  1572. case CMD_cunmap:
  1573. case CMD_iunmap:
  1574. do_exmap(&ea, FALSE);
  1575. break;
  1576. case CMD_mapclear:
  1577. case CMD_nmapclear:
  1578. case CMD_vmapclear:
  1579. case CMD_omapclear:
  1580. case CMD_cmapclear:
  1581. case CMD_imapclear:
  1582. map_clear(ea.cmd, ea.forceit, FALSE);
  1583. break;
  1584. case CMD_abclear:
  1585. case CMD_iabclear:
  1586. case CMD_cabclear:
  1587. map_clear(ea.cmd, TRUE, TRUE);
  1588. break;
  1589. #ifdef USE_GUI
  1590. case CMD_menu:     case CMD_noremenu:     case CMD_unmenu:
  1591. case CMD_amenu:     case CMD_anoremenu:     case CMD_aunmenu:
  1592. case CMD_nmenu:     case CMD_nnoremenu:     case CMD_nunmenu:
  1593. case CMD_vmenu:     case CMD_vnoremenu:     case CMD_vunmenu:
  1594. case CMD_omenu:     case CMD_onoremenu:     case CMD_ounmenu:
  1595. case CMD_imenu:     case CMD_inoremenu:     case CMD_iunmenu:
  1596. case CMD_cmenu:     case CMD_cnoremenu:     case CMD_cunmenu:
  1597. case CMD_tmenu:     case CMD_tunmenu:
  1598. do_menu(&ea);
  1599. break;
  1600. #endif
  1601. case CMD_display:
  1602. case CMD_registers:
  1603. do_dis(ea.arg);
  1604. break;
  1605. case CMD_help:
  1606. do_help(&ea);
  1607. break;
  1608. case CMD_version:
  1609. do_version(ea.arg);
  1610. break;
  1611. case CMD_winsize:
  1612. do_winsize(ea.arg);
  1613. break;
  1614. case CMD_delete:
  1615. case CMD_yank:
  1616. case CMD_rshift:
  1617. case CMD_lshift:
  1618. do_exops(&ea);
  1619. break;
  1620. case CMD_put:
  1621. /* ":0put" works like ":1put!". */
  1622. if (ea.line2 == 0)
  1623. {
  1624.     ea.line2 = 1;
  1625.     ea.forceit = TRUE;
  1626. }
  1627. curwin->w_cursor.lnum = ea.line2;
  1628. do_put(ea.regname, ea.forceit ? BACKWARD : FORWARD, -1L, 0);
  1629. break;
  1630. case CMD_t:
  1631. case CMD_copy:
  1632. case CMD_move:
  1633. do_copymove(&ea);
  1634. break;
  1635. case CMD_and: /* :& */
  1636. case CMD_tilde: /* :~ */
  1637. case CMD_substitute: /* :s */
  1638. do_sub(&ea);
  1639. break;
  1640. case CMD_smagic:
  1641. i = p_magic;
  1642. p_magic = TRUE;
  1643. do_sub(&ea);
  1644. p_magic = i;
  1645. break;
  1646. case CMD_snomagic:
  1647. i = p_magic;
  1648. p_magic = FALSE;
  1649. do_sub(&ea);
  1650. p_magic = i;
  1651. break;
  1652. case CMD_join:
  1653. do_exjoin(&ea);
  1654. break;
  1655. case CMD_global:
  1656. if (ea.forceit)
  1657.     *ea.cmd = 'v';
  1658. case CMD_vglobal:
  1659. do_glob(&ea);
  1660. break;
  1661. case CMD_star:     /* :[addr]*r */
  1662. case CMD_at:     /* :[addr]@r */
  1663. do_exat(&ea);
  1664. break;
  1665. case CMD_bang:
  1666. do_bang(ea.addr_count, ea.line1, ea.line2,
  1667.       ea.forceit, ea.arg, TRUE, TRUE);
  1668. break;
  1669. case CMD_undo:
  1670. u_undo(1);
  1671. break;
  1672. case CMD_redo:
  1673. u_redo(1);
  1674. break;
  1675. case CMD_source:
  1676. #ifdef USE_BROWSE
  1677. if (browse)
  1678. {
  1679.     char_u *fname = NULL;
  1680.     fname = do_browse(FALSE, (char_u *)"Run Macro",
  1681.     NULL, NULL, ea.arg, BROWSE_FILTER_MACROS, curbuf);
  1682.     if (fname != NULL)
  1683.     {
  1684. cmd_source(fname, ea.forceit);
  1685. vim_free(fname);
  1686.     }
  1687.     break;
  1688. }
  1689. #endif /* USE_BROWSE */
  1690. if (*ea.arg == NUL)
  1691.     emsg(e_argreq);
  1692. else
  1693.     cmd_source(ea.arg, ea.forceit);
  1694. break;
  1695. #ifdef VIMINFO
  1696. case CMD_rviminfo:
  1697. p = p_viminfo;
  1698. if (*p_viminfo == NUL)
  1699.     p_viminfo = (char_u *)"'100";
  1700. if (read_viminfo(ea.arg, TRUE, TRUE, ea.forceit) == FAIL)
  1701.     EMSG("Cannot open viminfo file for reading");
  1702. p_viminfo = p;
  1703. break;
  1704. case CMD_wviminfo:
  1705. p = p_viminfo;
  1706. if (*p_viminfo == NUL)
  1707.     p_viminfo = (char_u *)"'100";
  1708. write_viminfo(ea.arg, ea.forceit);
  1709. p_viminfo = p;
  1710. break;
  1711. #endif /* VIMINFO */
  1712. case CMD_redir:
  1713. do_redir(&ea);
  1714. break;
  1715. case CMD_mksession:
  1716. do_mkrc(&ea, (char_u *)SESSION_FILE);
  1717. break;
  1718. case CMD_mkvimrc:
  1719. do_mkrc(&ea, (char_u *)VIMRC_FILE);
  1720. break;
  1721. case CMD_mkexrc:
  1722. do_mkrc(&ea, (char_u *)EXRC_FILE);
  1723. break;
  1724. #ifdef QUICKFIX
  1725. case CMD_cc:
  1726. qf_jump(0, ea.addr_count ? (int)ea.line2 : 0, ea.forceit);
  1727. break;
  1728. case CMD_cfile:
  1729. do_cfile(&ea);
  1730. break;
  1731. case CMD_clist:
  1732. qf_list(ea.forceit);
  1733. break;
  1734. case CMD_crewind:
  1735. qf_jump(0, ea.addr_count ? (int)ea.line2 : 1, ea.forceit);
  1736. break;
  1737. case CMD_clast:
  1738. qf_jump(0, ea.addr_count ? (int)ea.line2 : 32767, ea.forceit);
  1739. break;
  1740. case CMD_cnext:
  1741. qf_jump(FORWARD, ea.addr_count ? (int)ea.line2 : 1, ea.forceit);
  1742. break;
  1743. case CMD_colder:
  1744. qf_older(ea.addr_count ? (int)ea.line2 : 1);
  1745. break;
  1746. case CMD_cnewer:
  1747. qf_newer(ea.addr_count ? (int)ea.line2 : 1);
  1748. break;
  1749. case CMD_cNext:
  1750. case CMD_cprevious:
  1751. qf_jump(BACKWARD, ea.addr_count ? (int)ea.line2 : 1,
  1752.   ea.forceit);
  1753. break;
  1754. #endif
  1755. #ifdef USER_COMMANDS
  1756. case CMD_USER:
  1757. do_ucmd(USER_CMD(ea.useridx), &ea);
  1758. break;
  1759. case CMD_command:
  1760. do_command(&ea);
  1761. break;
  1762. case CMD_comclear:
  1763. do_comclear();
  1764. break;
  1765. case CMD_delcommand:
  1766. do_delcommand(&ea);
  1767. break;
  1768. #endif
  1769. case CMD_cquit:
  1770. getout(1); /* this does not always pass on the exit
  1771.    code to the Manx compiler. why? */
  1772. case CMD_mark:
  1773. case CMD_k:
  1774. do_setmark(&ea);
  1775. break;
  1776. #ifdef EX_EXTRA
  1777. case CMD_center:
  1778. case CMD_right:
  1779. case CMD_left:
  1780. do_align(&ea);
  1781. break;
  1782. case CMD_retab:
  1783. do_retab(&ea);
  1784. break;
  1785. case CMD_normal:
  1786. do_normal(&ea);
  1787. break;
  1788. #endif
  1789. #ifdef QUICKFIX
  1790. case CMD_grep:
  1791. do_make(ea.arg, p_gefm);
  1792. break;
  1793. case CMD_make:
  1794. do_make(ea.arg, p_efm);
  1795. break;
  1796. #endif
  1797. #ifdef FIND_IN_PATH
  1798. case CMD_isearch:
  1799. case CMD_dsearch:
  1800. errormsg = do_findpat(&ea, ACTION_SHOW);
  1801. break;
  1802. case CMD_ilist:
  1803. case CMD_dlist:
  1804. errormsg = do_findpat(&ea, ACTION_SHOW_ALL);
  1805. break;
  1806. case CMD_ijump:
  1807. case CMD_djump:
  1808. errormsg = do_findpat(&ea, ACTION_GOTO);
  1809. break;
  1810. case CMD_isplit:
  1811. case CMD_dsplit:
  1812. errormsg = do_findpat(&ea, ACTION_SPLIT);
  1813. break;
  1814. #endif
  1815. #ifdef SYNTAX_HL
  1816. case CMD_syntax:
  1817. do_syntax(&ea, cmdlinep);
  1818. break;
  1819. #endif
  1820. case CMD_highlight:
  1821. do_highlight(ea.arg, ea.forceit, FALSE);
  1822. break;
  1823. #ifdef WANT_EVAL
  1824. case CMD_echo:
  1825. case CMD_echon:
  1826. do_echo(&ea, ea.cmdidx == CMD_echo);
  1827. break;
  1828. case CMD_echohl:
  1829. do_echohl(ea.arg);
  1830. break;
  1831. case CMD_execute:
  1832. do_execute(&ea, getline, cookie);
  1833. break;
  1834. case CMD_call:
  1835. do_call(&ea);
  1836. break;
  1837. case CMD_if:
  1838. errormsg = do_if(&ea, cstack);
  1839. break;
  1840. case CMD_elseif:
  1841. case CMD_else:
  1842. errormsg = do_else(&ea, cstack);
  1843. break;
  1844. case CMD_endif:
  1845. did_endif = TRUE;
  1846. if (cstack->cs_idx < 0
  1847. || (cstack->cs_flags[cstack->cs_idx] & CSF_WHILE))
  1848.     errormsg = (char_u *)":endif without :if";
  1849. else
  1850.     --cstack->cs_idx;
  1851. break;
  1852. case CMD_while:
  1853. errormsg = do_while(&ea, cstack);
  1854. break;
  1855. case CMD_continue:
  1856. errormsg = do_continue(cstack);
  1857. break;
  1858. case CMD_break:
  1859. errormsg = do_break(cstack);
  1860. break;
  1861. case CMD_endwhile:
  1862. errormsg = do_endwhile(cstack);
  1863. break;
  1864. case CMD_let:
  1865. do_let(&ea);
  1866. break;
  1867. case CMD_unlet:
  1868. do_unlet(ea.arg, ea.forceit);
  1869. break;
  1870. case CMD_function:
  1871. do_function(&ea, getline, cookie);
  1872. break;
  1873. case CMD_delfunction:
  1874. do_delfunction(ea.arg);
  1875. break;
  1876. case CMD_return:
  1877. do_return(&ea);
  1878. break;
  1879. case CMD_endfunction:
  1880. EMSG(":endfunction not inside a function");
  1881. break;
  1882. #endif /* WANT_EVAL */
  1883. case CMD_insert:
  1884. do_append(ea.line2 - 1, getline, cookie);
  1885. ex_no_reprint = TRUE;
  1886. break;
  1887. case CMD_append:
  1888. do_append(ea.line2, getline, cookie);
  1889. ex_no_reprint = TRUE;
  1890. break;
  1891. case CMD_change:
  1892. do_change(ea.line1, ea.line2, getline, cookie);
  1893. ex_no_reprint = TRUE;
  1894. break;
  1895. case CMD_z:
  1896. do_z(ea.line2, ea.arg);
  1897. ex_no_reprint = TRUE;
  1898. break;
  1899. case CMD_intro:
  1900. do_intro();
  1901. break;
  1902. #ifdef HAVE_PERL_INTERP
  1903. case CMD_perl:
  1904. do_perl(&ea);
  1905. break;
  1906. case CMD_perldo:
  1907. do_perldo(&ea);
  1908. break;
  1909. #endif
  1910. #ifdef HAVE_PYTHON
  1911. case CMD_python:
  1912. do_python(&ea);
  1913. break;
  1914. case CMD_pyfile:
  1915. do_pyfile(&ea);
  1916. break;
  1917. #endif
  1918. #ifdef HAVE_TCL
  1919. case CMD_tcl:
  1920. do_tcl(&ea);
  1921. break;
  1922. case CMD_tcldo:
  1923. do_tcldo(&ea);
  1924. break;
  1925. case CMD_tclfile:
  1926. do_tclfile(&ea);
  1927. break;
  1928. #endif
  1929. #ifdef USE_SNIFF
  1930. case CMD_sniff:
  1931. do_sniff(ea.arg);
  1932. break;
  1933. #endif
  1934. case CMD_nohlsearch:
  1935. #ifdef EXTRA_SEARCH
  1936. no_hlsearch = TRUE;
  1937. redraw_all_later(NOT_VALID);
  1938. #endif
  1939. break;
  1940. default:
  1941. /* Illegal commands have already been handled */
  1942. errormsg = (char_u *)"Sorry, this command is not implemented";
  1943.     }
  1944. doend:
  1945.     if (curwin->w_cursor.lnum == 0) /* can happen with zero line number */
  1946. curwin->w_cursor.lnum = 1;
  1947.     if (errormsg != NULL && *errormsg != NUL && !did_emsg)
  1948.     {
  1949. emsg(errormsg);
  1950. if (sourcing)
  1951. {
  1952.     MSG_PUTS(": ");
  1953.     msg_outtrans(*cmdlinep);
  1954. }
  1955.     }
  1956.     if (ea.nextcmd && *ea.nextcmd == NUL) /* not really a next command */
  1957. ea.nextcmd = NULL;
  1958.     return ea.nextcmd;
  1959. }
  1960. /*
  1961.  * This is all pretty much copied from do_one_cmd(), with all the extra stuff
  1962.  * we don't need/want deleted. Maybe this could be done better if we didn't
  1963.  * repeat all this stuff.  The only problem is that they may not stay perfectly
  1964.  * compatible with each other, but then the command line syntax probably won't
  1965.  * change that much -- webb.
  1966.  */
  1967.     char_u *
  1968. set_one_cmd_context(buff)
  1969.     char_u *buff;     /* buffer for command string */
  1970. {
  1971.     char_u *p;
  1972.     char_u *cmd, *arg;
  1973.     int i = 0;
  1974.     CMDIDX cmdidx;
  1975.     long argt = 0;
  1976. #ifdef USER_COMMANDS
  1977.     int compl = EXPAND_NOTHING;
  1978. #endif
  1979.     char_u delim;
  1980.     int forceit = FALSE;
  1981.     int usefilter = FALSE;  /* filter instead of file name */
  1982.     expand_pattern = buff;
  1983.     expand_context = EXPAND_COMMANDS; /* Default until we get past command */
  1984.     expand_set_path = FALSE;
  1985. /*
  1986.  * 2. skip comment lines and leading space, colons or bars
  1987.  */
  1988.     for (cmd = buff; vim_strchr((char_u *)" t:|", *cmd) != NULL; cmd++)
  1989. ;
  1990.     expand_pattern = cmd;
  1991.     if (*cmd == NUL)
  1992. return NULL;
  1993.     if (*cmd == '"')     /* ignore comment lines */
  1994.     {
  1995. expand_context = EXPAND_NOTHING;
  1996. return NULL;
  1997.     }
  1998. /*
  1999.  * 3. parse a range specifier of the form: addr [,addr] [;addr] ..
  2000.  */
  2001.     /*
  2002.      * Backslashed delimiters after / or ? will be skipped, and commands will
  2003.      * not be expanded between /'s and ?'s or after "'". -- webb
  2004.      */
  2005.     while (*cmd != NUL && (vim_isspace(*cmd) || isdigit(*cmd) ||
  2006.     vim_strchr((char_u *)".$%'/?-+,;", *cmd) != NULL))
  2007.     {
  2008. if (*cmd == ''')
  2009. {
  2010.     if (*++cmd == NUL)
  2011. expand_context = EXPAND_NOTHING;
  2012. }
  2013. else if (*cmd == '/' || *cmd == '?')
  2014. {
  2015.     delim = *cmd++;
  2016.     while (*cmd != NUL && *cmd != delim)
  2017. if (*cmd++ == '\' && *cmd != NUL)
  2018.     ++cmd;
  2019.     if (*cmd == NUL)
  2020. expand_context = EXPAND_NOTHING;
  2021. }
  2022. if (*cmd != NUL)
  2023.     ++cmd;
  2024.     }
  2025. /*
  2026.  * 4. parse command
  2027.  */
  2028.     cmd = skipwhite(cmd);
  2029.     expand_pattern = cmd;
  2030.     if (*cmd == NUL)
  2031. return NULL;
  2032.     if (*cmd == '"')
  2033.     {
  2034. expand_context = EXPAND_NOTHING;
  2035. return NULL;
  2036.     }
  2037.     if (*cmd == '|' || *cmd == 'n')
  2038. return cmd + 1; /* There's another command */
  2039.     /*
  2040.      * Isolate the command and search for it in the command table.
  2041.      * Exceptions:
  2042.      * - the 'k' command can directly be followed by any character.
  2043.      * - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
  2044.      */
  2045.     if (*cmd == 'k')
  2046.     {
  2047. cmdidx = CMD_k;
  2048. p = cmd + 1;
  2049.     }
  2050.     else
  2051.     {
  2052. p = cmd;
  2053. while (isalpha(*p) || *p == '*')    /* Allow * wild card */
  2054.     ++p;
  2055.     /* check for non-alpha command */
  2056. if (p == cmd && vim_strchr((char_u *)"@*!=><&~#", *p) != NULL)
  2057.     ++p;
  2058. i = (int)(p - cmd);
  2059. if (i == 0)
  2060. {
  2061.     expand_context = EXPAND_UNSUCCESSFUL;
  2062.     return NULL;
  2063. }
  2064. for (cmdidx = (CMDIDX)0; (int)cmdidx < (int)CMD_SIZE;
  2065.    cmdidx = (CMDIDX)((int)cmdidx + 1))
  2066.     if (STRNCMP(cmdnames[(int)cmdidx].cmd_name, cmd, (size_t)i) == 0)
  2067. break;
  2068.     }
  2069.     /*
  2070.      * If the cursor is touching the command, and it ends in an alphabetic
  2071.      * character, complete the command name.
  2072.      */
  2073.     if (*p == NUL && isalpha(p[-1]))
  2074. return NULL;
  2075.     if (cmdidx == CMD_SIZE)
  2076.     {
  2077. if (*cmd == 's' && vim_strchr((char_u *)"cgriI", cmd[1]) != NULL)
  2078. {
  2079.     cmdidx = CMD_substitute;
  2080.     p = cmd + 1;
  2081. }
  2082. else
  2083. {
  2084. #ifdef USER_COMMANDS
  2085.     /* Look for a user defined command as a last resort */
  2086.     UCMD *c = USER_CMD(0);
  2087.     int j;
  2088.     int found = FALSE;
  2089.     for (j = 0; j < ucmds.ga_len; ++j, ++c)
  2090.     {
  2091. if (STRNCMP(c->uc_name, cmd, (size_t)i) == 0)
  2092. {
  2093.     if (found)
  2094.     {
  2095. /* Ambiguous abbreviation */
  2096. expand_context = EXPAND_UNSUCCESSFUL;
  2097. return NULL;
  2098.     }
  2099.     found = TRUE;
  2100.     cmdidx = CMD_USER;
  2101.     argt = c->uc_argt;
  2102.     compl = c->uc_compl;
  2103.     /* Do not search for further abbreviations
  2104.      * if this is an exact match
  2105.      */
  2106.     if ((size_t)i == STRLEN(c->uc_name))
  2107. break;
  2108. }
  2109.     }
  2110.     if (!found)
  2111. #endif
  2112.     {
  2113. /* Not still touching the command and it was an illegal one */
  2114. expand_context = EXPAND_UNSUCCESSFUL;
  2115. return NULL;
  2116.     }
  2117. }
  2118.     }
  2119.     expand_context = EXPAND_NOTHING; /* Default now that we're past command */
  2120.     if (*p == '!')     /* forced commands */
  2121.     {
  2122. forceit = TRUE;
  2123. ++p;
  2124.     }
  2125. /*
  2126.  * 5. parse arguments
  2127.  */
  2128. #ifdef USER_COMMANDS
  2129.     if (cmdidx != CMD_USER)
  2130. #endif
  2131. argt = cmdnames[(int)cmdidx].cmd_argt;
  2132.     arg = skipwhite(p);
  2133.     if (cmdidx == CMD_write || cmdidx == CMD_update)
  2134.     {
  2135. if (*arg == '>') /* append */
  2136. {
  2137.     if (*++arg == '>')
  2138. ++arg;
  2139.     arg = skipwhite(arg);
  2140. }
  2141. else if (*arg == '!' && cmdidx == CMD_write) /* :w !filter */
  2142. {
  2143.     ++arg;
  2144.     usefilter = TRUE;
  2145. }
  2146.     }
  2147.     if (cmdidx == CMD_read)
  2148.     {
  2149. usefilter = forceit; /* :r! filter if forced */
  2150. if (*arg == '!') /* :r !filter */
  2151. {
  2152.     ++arg;
  2153.     usefilter = TRUE;
  2154. }
  2155.     }
  2156.     if (cmdidx == CMD_lshift || cmdidx == CMD_rshift)
  2157.     {
  2158. while (*arg == *cmd)     /* allow any number of '>' or '<' */
  2159.     ++arg;
  2160. arg = skipwhite(arg);
  2161.     }
  2162.     /* Does command allow "+command"? */
  2163.     if ((argt & EDITCMD) && !usefilter && *arg == '+')
  2164.     {
  2165. /* Check if we're in the +command */
  2166. p = arg + 1;
  2167. arg = skip_cmd_arg(arg);
  2168. /* Still touching the command after '+'? */
  2169. if (*arg == NUL)
  2170.     return p;
  2171. /* Skip space(s) after +command to get to the real argument */
  2172. arg = skipwhite(arg);
  2173.     }
  2174.     /*
  2175.      * Check for '|' to separate commands and '"' to start comments.
  2176.      * Don't do this for ":read !cmd" and ":write !cmd".
  2177.      */
  2178.     if ((argt & TRLBAR) && !usefilter)
  2179.     {
  2180. p = arg;
  2181. while (*p)
  2182. {
  2183.     if (*p == Ctrl('V'))
  2184.     {
  2185. if (p[1] != NUL)
  2186.     ++p;
  2187.     }
  2188.     else if ( (*p == '"' && !(argt & NOTRLCOM))
  2189.     || *p == '|' || *p == 'n')
  2190.     {
  2191. if (*(p - 1) != '\')
  2192. {
  2193.     if (*p == '|' || *p == 'n')
  2194. return p + 1;
  2195.     return NULL;    /* It's a comment */
  2196. }
  2197.     }
  2198.     ++p;
  2199. }
  2200.     }
  2201. /* no arguments allowed */
  2202.     if (!(argt & EXTRA) && *arg != NUL &&
  2203.     vim_strchr((char_u *)"|"", *arg) == NULL)
  2204. return NULL;
  2205.     /* Find start of last argument (argument just before cursor): */
  2206.     p = buff + STRLEN(buff);
  2207.     while (p != arg && *p != ' ' && *p != TAB)
  2208. p--;
  2209.     if (*p == ' ' || *p == TAB)
  2210. p++;
  2211.     expand_pattern = p;
  2212.     if (argt & XFILE)
  2213.     {
  2214. int in_quote = FALSE;
  2215. char_u *bow = NULL; /* Beginning of word */
  2216. /*
  2217.  * Allow spaces within back-quotes to count as part of the argument
  2218.  * being expanded.
  2219.  */
  2220. expand_pattern = skipwhite(arg);
  2221. for (p = expand_pattern; *p; ++p)
  2222. {
  2223.     if (*p == '\' && p[1])
  2224. ++p;
  2225. #ifdef SPACE_IN_FILENAME
  2226.     else if (vim_iswhite(*p) && (!(argt & NOSPC) || usefilter))
  2227. #else
  2228.     else if (vim_iswhite(*p))
  2229. #endif
  2230.     {
  2231. p = skipwhite(p);
  2232. if (in_quote)
  2233.     bow = p;
  2234. else
  2235.     expand_pattern = p;
  2236. --p;
  2237.     }
  2238.     else if (*p == '`')
  2239.     {
  2240. if (!in_quote)
  2241. {
  2242.     expand_pattern = p;
  2243.     bow = p + 1;
  2244. }
  2245. in_quote = !in_quote;
  2246.     }
  2247. }
  2248. /*
  2249.  * If we are still inside the quotes, and we passed a space, just
  2250.  * expand from there.
  2251.  */
  2252. if (bow != NULL && in_quote)
  2253.     expand_pattern = bow;
  2254. expand_context = EXPAND_FILES;
  2255.     }
  2256. /*
  2257.  * 6. switch on command name
  2258.  */
  2259.     switch (cmdidx)
  2260.     {
  2261. case CMD_cd:
  2262. case CMD_chdir:
  2263.     expand_context = EXPAND_DIRECTORIES;
  2264.     break;
  2265. #ifdef USE_BROWSE
  2266. case CMD_browse:
  2267. #endif
  2268. case CMD_confirm:
  2269.     return arg;
  2270. case CMD_global:
  2271. case CMD_vglobal:
  2272.     delim = *arg;     /* get the delimiter */
  2273.     if (delim)
  2274. ++arg;     /* skip delimiter if there is one */
  2275.     while (arg[0] != NUL && arg[0] != delim)
  2276.     {
  2277. if (arg[0] == '\' && arg[1] != NUL)
  2278.     ++arg;
  2279. ++arg;
  2280.     }
  2281.     if (arg[0] != NUL)
  2282. return arg + 1;
  2283.     break;
  2284. case CMD_and:
  2285. case CMD_substitute:
  2286.     delim = *arg;
  2287.     if (delim)
  2288. ++arg;
  2289.     for (i = 0; i < 2; i++)
  2290.     {
  2291. while (arg[0] != NUL && arg[0] != delim)
  2292. {
  2293.     if (arg[0] == '\' && arg[1] != NUL)
  2294. ++arg;
  2295.     ++arg;
  2296. }
  2297. if (arg[0] != NUL) /* skip delimiter */
  2298.     ++arg;
  2299.     }
  2300.     while (arg[0] && vim_strchr((char_u *)"|"#", arg[0]) == NULL)
  2301. ++arg;
  2302.     if (arg[0] != NUL)
  2303. return arg;
  2304.     break;
  2305. case CMD_isearch:
  2306. case CMD_dsearch:
  2307. case CMD_ilist:
  2308. case CMD_dlist:
  2309. case CMD_ijump:
  2310. case CMD_djump:
  2311. case CMD_isplit:
  2312. case CMD_dsplit:
  2313.     arg = skipwhite(skipdigits(arg));     /* skip count */
  2314.     if (*arg == '/') /* Match regexp, not just whole words */
  2315.     {
  2316. for (++arg; *arg && *arg != '/'; arg++)
  2317.     if (*arg == '\' && arg[1] != NUL)
  2318. arg++;
  2319. if (*arg)
  2320. {
  2321.     arg = skipwhite(arg + 1);
  2322.     /* Check for trailing illegal characters */
  2323.     if (*arg && vim_strchr((char_u *)"|"n", *arg) == NULL)
  2324. expand_context = EXPAND_NOTHING;
  2325.     else
  2326. return arg;
  2327. }
  2328.     }
  2329.     break;
  2330. #ifdef AUTOCMD
  2331. case CMD_autocmd:
  2332.     return set_context_in_autocmd(arg, FALSE);
  2333. case CMD_doautocmd:
  2334.     return set_context_in_autocmd(arg, TRUE);
  2335. #endif
  2336. case CMD_set:
  2337.     set_context_in_set_cmd(arg);
  2338.     break;
  2339. case CMD_tag:
  2340. case CMD_stag:
  2341. case CMD_tselect:
  2342. case CMD_stselect:
  2343. case CMD_tjump:
  2344. case CMD_stjump:
  2345.     expand_context = EXPAND_TAGS;
  2346.     expand_pattern = arg;
  2347.     break;
  2348. case CMD_help:
  2349.     expand_context = EXPAND_HELP;
  2350.     expand_pattern = arg;
  2351.     break;
  2352. case CMD_augroup:
  2353.     expand_context = EXPAND_AUGROUP;
  2354.     expand_pattern = arg;
  2355.     break;
  2356. #ifdef SYNTAX_HL
  2357. case CMD_syntax:
  2358.     set_context_in_syntax_cmd(arg);
  2359.     break;
  2360. #endif
  2361. #ifdef WANT_EVAL
  2362. case CMD_unlet:
  2363.     while ((expand_pattern = vim_strchr(arg, ' ')) != NULL)
  2364. arg = expand_pattern + 1;
  2365.     expand_context = EXPAND_USER_VARS;
  2366.     expand_pattern = arg;
  2367.     break;
  2368. case CMD_echohl:
  2369.     expand_context = EXPAND_HIGHLIGHT;
  2370.     expand_pattern = arg;
  2371.     break;
  2372. #endif
  2373. case CMD_highlight:
  2374.     set_context_in_highlight_cmd(arg);
  2375.     break;
  2376. case CMD_bdelete:
  2377. case CMD_bunload:
  2378.     while ((expand_pattern = vim_strchr(arg, ' ')) != NULL)
  2379. arg = expand_pattern + 1;
  2380. case CMD_buffer:
  2381. case CMD_sbuffer:
  2382.     expand_context = EXPAND_BUFFERS;
  2383.     expand_pattern = arg;
  2384.     break;
  2385. #ifdef USER_COMMANDS
  2386. case CMD_USER:
  2387.     if (compl != EXPAND_NOTHING)
  2388.     {
  2389. #ifdef USE_GUI
  2390. if (compl == EXPAND_MENUS)
  2391.     return gui_set_context_in_menu_cmd(cmd, arg, forceit);
  2392. #endif
  2393. if (compl == EXPAND_COMMANDS)
  2394.     return arg;
  2395. while ((expand_pattern = vim_strchr(arg, ' ')) != NULL)
  2396.     arg = expand_pattern + 1;
  2397. expand_context = compl;
  2398. expand_pattern = arg;
  2399.     }
  2400.     break;
  2401. #endif
  2402. #ifdef USE_GUI
  2403. case CMD_menu:     case CMD_noremenu:     case CMD_unmenu:
  2404. case CMD_amenu:     case CMD_anoremenu:     case CMD_aunmenu:
  2405. case CMD_nmenu:     case CMD_nnoremenu:     case CMD_nunmenu:
  2406. case CMD_vmenu:     case CMD_vnoremenu:     case CMD_vunmenu:
  2407. case CMD_omenu:     case CMD_onoremenu:     case CMD_ounmenu:
  2408. case CMD_imenu:     case CMD_inoremenu:     case CMD_iunmenu:
  2409. case CMD_cmenu:     case CMD_cnoremenu:     case CMD_cunmenu:
  2410. case CMD_tmenu:     case CMD_tunmenu:
  2411. case CMD_tearoff:
  2412.     return gui_set_context_in_menu_cmd(cmd, arg, forceit);
  2413. #endif
  2414. default:
  2415.     break;
  2416.     }
  2417.     return NULL;
  2418. }
  2419. /*
  2420.  * get a single EX address
  2421.  *
  2422.  * Set ptr to the next character after the part that was interpreted.
  2423.  * Set ptr to NULL when an error is encountered.
  2424.  *
  2425.  * Return MAXLNUM when no Ex address was found.
  2426.  */
  2427.     static linenr_t
  2428. get_address(ptr, skip)
  2429.     char_u **ptr;
  2430.     int skip;     /* only skip the address, don't use it */
  2431. {
  2432.     int c;
  2433.     int i;
  2434.     long n;
  2435.     char_u *cmd;
  2436.     FPOS pos;
  2437.     FPOS *fp;
  2438.     linenr_t lnum;
  2439.     cmd = skipwhite(*ptr);
  2440.     lnum = MAXLNUM;
  2441.     do
  2442.     {
  2443. switch (*cmd)
  2444. {
  2445.     case '.':     /* '.' - Cursor position */
  2446. ++cmd;
  2447. lnum = curwin->w_cursor.lnum;
  2448. break;
  2449.     case '$':     /* '$' - last line */
  2450. ++cmd;
  2451. lnum = curbuf->b_ml.ml_line_count;
  2452. break;
  2453.     case ''':     /* ''' - mark */
  2454. if (*++cmd == NUL)
  2455. {
  2456.     cmd = NULL;
  2457.     goto error;
  2458. }
  2459. if (!skip)
  2460. {
  2461.     fp = getmark(*cmd, FALSE);
  2462.     ++cmd;
  2463.     if (check_mark(fp) == FAIL)
  2464.     {
  2465. cmd = NULL;
  2466. goto error;
  2467.     }
  2468.     lnum = fp->lnum;
  2469. }
  2470. break;
  2471.     case '/':
  2472.     case '?': /* '/' or '?' - search */
  2473. c = *cmd++;
  2474. if (skip) /* skip "/pat/" */
  2475. {
  2476.     cmd = skip_regexp(cmd, c, (int)p_magic);
  2477.     if (*cmd == c)
  2478. ++cmd;
  2479. }
  2480. else
  2481. {
  2482.     pos = curwin->w_cursor; /* save curwin->w_cursor */
  2483.     /*
  2484.      * When '/' or '?' follows another address, start
  2485.      * from there.
  2486.      */
  2487.     if (lnum != MAXLNUM)
  2488. curwin->w_cursor.lnum = lnum;
  2489.     /*
  2490.      * Start a forward search at the end of the line.
  2491.      * Start a backward search at the start of the line.
  2492.      * This makes sure we never match in the current
  2493.      * line, and can match anywhere in the
  2494.      * next/previous line.
  2495.      */
  2496.     if (c == '/')
  2497. curwin->w_cursor.col = MAXCOL;
  2498.     else
  2499. curwin->w_cursor.col = 0;
  2500.     searchcmdlen = 0;
  2501.     if (!do_search(NULL, c, cmd, 1L,
  2502.       SEARCH_HIS + SEARCH_MSG + SEARCH_START))
  2503.     {
  2504. curwin->w_cursor = pos;
  2505. cmd = NULL;
  2506. goto error;
  2507.     }
  2508.     lnum = curwin->w_cursor.lnum;
  2509.     curwin->w_cursor = pos;
  2510.     /* adjust command string pointer */
  2511.     cmd += searchcmdlen;
  2512. }
  2513. break;
  2514.     case '\':     /* "?", "/" or "&", repeat search */
  2515. ++cmd;
  2516. if (*cmd == '&')
  2517.     i = RE_SUBST;
  2518. else if (*cmd == '?' || *cmd == '/')
  2519.     i = RE_SEARCH;
  2520. else
  2521. {
  2522.     emsg(e_backslash);
  2523.     cmd = NULL;
  2524.     goto error;
  2525. }
  2526. if (!skip)
  2527. {
  2528.     /*
  2529.      * When search follows another address, start from
  2530.      * there.
  2531.      */
  2532.     if (lnum != MAXLNUM)
  2533. pos.lnum = lnum;
  2534.     else
  2535. pos.lnum = curwin->w_cursor.lnum;
  2536.     /*
  2537.      * Start the search just like for the above
  2538.      * do_search().
  2539.      */
  2540.     if (*cmd != '?')
  2541. pos.col = MAXCOL;
  2542.     else
  2543. pos.col = 0;
  2544.     if (searchit(curbuf, &pos,
  2545. *cmd == '?' ? BACKWARD : FORWARD,
  2546. (char_u *)"", 1L,
  2547. SEARCH_MSG + SEARCH_START, i) == OK)
  2548. lnum = pos.lnum;
  2549.     else
  2550.     {
  2551. cmd = NULL;
  2552. goto error;
  2553.     }
  2554. }
  2555. ++cmd;
  2556. break;
  2557.     default:
  2558. if (isdigit(*cmd)) /* absolute line number */
  2559.     lnum = getdigits(&cmd);
  2560. }
  2561. for (;;)
  2562. {
  2563.     cmd = skipwhite(cmd);
  2564.     if (*cmd != '-' && *cmd != '+' && !isdigit(*cmd))
  2565. break;
  2566.     if (lnum == MAXLNUM)
  2567. lnum = curwin->w_cursor.lnum; /* "+1" is same as ".+1" */
  2568.     if (isdigit(*cmd))
  2569. i = '+'; /* "number" is same as "+number" */
  2570.     else
  2571. i = *cmd++;
  2572.     if (!isdigit(*cmd)) /* '+' is '+1', but '+0' is not '+1' */
  2573. n = 1;
  2574.     else
  2575. n = getdigits(&cmd);
  2576.     if (i == '-')
  2577. lnum -= n;
  2578.     else
  2579. lnum += n;
  2580. }
  2581.     } while (*cmd == '/' || *cmd == '?');
  2582. error:
  2583.     *ptr = cmd;
  2584.     return lnum;
  2585. }
  2586. /*
  2587.  * Check range in Ex command for validity.
  2588.  * Return NULL when valid, error message when invalid.
  2589.  */
  2590.     static char_u *
  2591. invalid_range(eap)
  2592.     EXARG *eap;
  2593. {
  2594.     if (       eap->line1 < 0
  2595.     || eap->line2 < 0
  2596.     || eap->line1 > eap->line2
  2597.     || ((eap->argt & RANGE)
  2598. && !(eap->argt & NOTADR)
  2599. && eap->line2 > curbuf->b_ml.ml_line_count))
  2600. return e_invrange;
  2601.     return NULL;
  2602. }
  2603. /*
  2604.  * Corect the range for zero line number, if required.
  2605.  */
  2606.     static void
  2607. correct_range(eap)
  2608.     EXARG *eap;
  2609. {
  2610.     if (!(eap->argt & ZEROR))     /* zero in range not allowed */
  2611.     {
  2612. if (eap->line1 == 0)
  2613.     eap->line1 = 1;
  2614. if (eap->line2 == 0)
  2615.     eap->line2 = 1;
  2616.     }
  2617. }
  2618. /*
  2619.  * Expand file name in Ex command argument.
  2620.  * Return FAIL for failure, OK otherwise.
  2621.  */
  2622.     int
  2623. expand_filename(eap, cmdlinep, errormsgp)
  2624.     EXARG *eap;
  2625.     char_u **cmdlinep;
  2626.     char_u **errormsgp;
  2627. {
  2628.     int has_wildcards; /* need to expand wildcards */
  2629.     char_u *repl;
  2630.     int srclen;
  2631.     char_u *p;
  2632.     char_u *new_cmdline;
  2633.     int len;
  2634.     int i;
  2635.     int n;
  2636.     /*
  2637.      * Decide to expand wildcards *before* replacing '%', '#', etc.  If
  2638.      * the file name contains a wildcard it should not cause expanding.
  2639.      * (it will be expanded anyway if there is a wildcard before replacing).
  2640.      */
  2641.     has_wildcards = mch_has_wildcard(eap->arg);
  2642.     for (p = eap->arg; *p; )
  2643.     {
  2644. /*
  2645.  * Quick check if this cannot be the start of a special string.
  2646.  */
  2647. if (vim_strchr((char_u *)"%#<", *p) == NULL)
  2648. {
  2649.     ++p;
  2650.     continue;
  2651. }
  2652. /*
  2653.  * Try to find a match at this position.
  2654.  */
  2655. repl = eval_vars(p, &srclen, &(eap->do_ecmd_lnum), errormsgp, eap->arg);
  2656. if (*errormsgp != NULL) /* error detected */
  2657.     return FAIL;
  2658. if (repl == NULL) /* no match found */
  2659. {
  2660.     p += srclen;
  2661.     continue;
  2662. }
  2663. /*
  2664.  * The new command line is build in new_cmdline[].
  2665.  * First allocate it.
  2666.  */
  2667. len = STRLEN(repl);
  2668. i = STRLEN(*cmdlinep) + len + 3;
  2669. if (eap->nextcmd)
  2670.     i += STRLEN(eap->nextcmd); /* add space for next command */
  2671. if ((new_cmdline = alloc(i)) == NULL)
  2672. {
  2673.     vim_free(repl);
  2674.     return FAIL; /* out of memory! */
  2675. }
  2676. /*
  2677.  * Copy the stuff before the expanded part.
  2678.  * Copy the expanded stuff.
  2679.  * Copy what came after the expanded part.
  2680.  * Copy the next commands, if there are any.
  2681.  */
  2682. i = p - *cmdlinep;     /* length of part before match */
  2683. mch_memmove(new_cmdline, *cmdlinep, (size_t)i);
  2684. mch_memmove(new_cmdline + i, repl, (size_t)len);
  2685. vim_free(repl);
  2686. i += len;     /* remember the end of the string */
  2687. STRCPY(new_cmdline + i, p + srclen);
  2688. p = new_cmdline + i;     /* remember where to continue */
  2689. if (eap->nextcmd)     /* append next command */
  2690. {
  2691.     i = STRLEN(new_cmdline) + 1;
  2692.     STRCPY(new_cmdline + i, eap->nextcmd);
  2693.     eap->nextcmd = new_cmdline + i;
  2694. }
  2695. eap->cmd = new_cmdline + (eap->cmd - *cmdlinep);
  2696. eap->arg = new_cmdline + (eap->arg - *cmdlinep);
  2697. if (eap->do_ecmd_cmd != NULL)
  2698.     eap->do_ecmd_cmd = new_cmdline + (eap->do_ecmd_cmd - *cmdlinep);
  2699. vim_free(*cmdlinep);
  2700. *cmdlinep = new_cmdline;
  2701.     }
  2702.     /*
  2703.      * One file argument: Expand wildcards.
  2704.      * Don't do this with ":r !command" or ":w !command".
  2705.      */
  2706.     if ((eap->argt & NOSPC) && !eap->usefilter)
  2707.     {
  2708. /*
  2709.  * May do this twice:
  2710.  * 1. Replace environment variables.
  2711.  * 2. Replace any other wildcards, remove backslashes.
  2712.  */
  2713. for (n = 1; n <= 2; ++n)
  2714. {
  2715.     if (n == 2)
  2716.     {
  2717. #if defined(UNIX)
  2718. /*
  2719.  * Only for Unix we check for more than one file name.
  2720.  * For other systems spaces are considered to be part
  2721.  * of the file name.
  2722.  * Only check here if there is no wildcard, otherwise
  2723.  * ExpandOne will check for errors. This allows
  2724.  * ":e `ls ve*.c`" on Unix.
  2725.  */
  2726. if (!has_wildcards)
  2727.     for (p = eap->arg; *p; ++p)
  2728.     {
  2729. /* skip escaped characters */
  2730. if (p[1] && (*p == '\' || *p == Ctrl('V')))
  2731.     ++p;
  2732. else if (vim_iswhite(*p))
  2733. {
  2734.     *errormsgp = (char_u *)"Only one file name allowed";
  2735.     return FAIL;
  2736. }
  2737.     }
  2738. #endif
  2739. /*
  2740.  * halve the number of backslashes (this is Vi compatible)
  2741.  */
  2742. backslash_halve(eap->arg, has_wildcards);
  2743. #ifdef macintosh
  2744. /*
  2745.  * translate unix-like path components
  2746.  */
  2747. slash_n_colon_adjust (eap->arg);
  2748. #endif
  2749.     }
  2750.     if (has_wildcards)
  2751.     {
  2752. if (n == 1)
  2753. {
  2754.     /*
  2755.      * First loop: May expand environment variables.  This
  2756.      * can be done much faster with expand_env() than with
  2757.      * something else (e.g., calling a shell).
  2758.      * After expanding environment variables, check again
  2759.      * if there are still wildcards present.
  2760.      */
  2761.     if (vim_strchr(eap->arg, '$') || vim_strchr(eap->arg, '~'))
  2762.     {
  2763. expand_env(eap->arg, NameBuff, MAXPATHL);
  2764. has_wildcards = mch_has_wildcard(NameBuff);
  2765. p = NameBuff;
  2766.     }
  2767.     else
  2768. p = NULL;
  2769. }
  2770. else /* n == 2 */
  2771. {
  2772.     if ((p = ExpandOne(eap->arg, NULL, WILD_LIST_NOTFOUND,
  2773.        WILD_EXPAND_FREE)) == NULL)
  2774. return FAIL;
  2775. }
  2776. if (p != NULL)
  2777. {
  2778.     /*
  2779.      * The tricky bit here is to replace the argument,
  2780.      * while keeping the "eap->cmd" and "eap->nextcmd" the
  2781.      * pointers correct.
  2782.      */
  2783.     len = eap->arg - *cmdlinep;
  2784.     i = STRLEN(p) + len;
  2785.     if (eap->nextcmd)
  2786. i += STRLEN(eap->nextcmd);
  2787.     if ((new_cmdline = alloc((unsigned)i + 2)) != NULL)
  2788.     {
  2789. STRNCPY(new_cmdline, *cmdlinep, len);
  2790. STRCPY(new_cmdline + len, p);
  2791. if (eap->nextcmd)     /* append next command */
  2792. {
  2793.     i = STRLEN(new_cmdline) + 1;
  2794.     STRCPY(new_cmdline + i, eap->nextcmd);
  2795.     eap->nextcmd = new_cmdline + i;
  2796. }
  2797. eap->cmd = new_cmdline + (eap->cmd - *cmdlinep);
  2798. eap->arg = new_cmdline + len;
  2799. vim_free(*cmdlinep);
  2800. *cmdlinep = new_cmdline;
  2801.     }
  2802.     if (n == 2) /* p came from ExpandOne() */
  2803. vim_free(p);
  2804. }
  2805.     }
  2806. }
  2807.     }
  2808.     return OK;
  2809. }
  2810. /*
  2811.  * Check for '|' to separate commands and '"' to start comments.
  2812.  */
  2813.     void
  2814. separate_nextcmd(eap)
  2815.     EXARG *eap;
  2816. {
  2817.     char_u *p;
  2818.     for (p = eap->arg; *p; ++p)
  2819.     {
  2820. if (*p == Ctrl('V'))
  2821. {
  2822.     if (eap->argt & (USECTRLV | XFILE))
  2823. ++p; /* skip CTRL-V and next char */
  2824.     else
  2825. STRCPY(p, p + 1); /* remove CTRL-V and skip next char */
  2826.     if (*p == NUL) /* stop at NUL after CTRL-V */
  2827. break;
  2828. }
  2829. else if ((*p == '"' && !(eap->argt & NOTRLCOM))
  2830. || *p == '|' || *p == 'n')
  2831. {
  2832.     /*
  2833.      * We remove the '' before the '|', unless USECTRLV is used
  2834.      * AND 'b' is present in 'cpoptions'.
  2835.      */
  2836.     if ((vim_strchr(p_cpo, CPO_BAR) == NULL
  2837.       || !(eap->argt & USECTRLV)) && *(p - 1) == '\')
  2838.     {
  2839. mch_memmove(p - 1, p, STRLEN(p) + 1); /* remove the '' */
  2840. --p;
  2841.     }
  2842.     else
  2843.     {
  2844. eap->nextcmd = check_nextcmd(p);
  2845. *p = NUL;
  2846. break;
  2847.     }
  2848. }
  2849.     }
  2850.     if (!(eap->argt & NOTRLCOM)) /* remove trailing spaces */
  2851. del_trailing_spaces(eap->arg);
  2852. }
  2853. /*
  2854.  * If 'autowrite' option set, try to write the file.
  2855.  *
  2856.  * return FAIL for failure, OK otherwise
  2857.  */
  2858.     int
  2859. autowrite(buf, forceit)
  2860.     BUF     *buf;
  2861.     int     forceit;
  2862. {
  2863.     if (!p_aw || (!forceit && buf->b_p_ro) || buf->b_ffname == NULL)
  2864. return FAIL;
  2865.     return buf_write_all(buf);
  2866. }
  2867. /*
  2868.  * flush all buffers, except the ones that are readonly
  2869.  */
  2870.     void
  2871. autowrite_all()
  2872. {
  2873.     BUF     *buf;
  2874.     if (!p_aw)
  2875. return;
  2876.     for (buf = firstbuf; buf; buf = buf->b_next)
  2877. if (buf_changed(buf) && !buf->b_p_ro)
  2878. {
  2879.     (void)buf_write_all(buf);
  2880. #ifdef AUTOCMD
  2881.     /* an autocommand may have deleted the buffer */
  2882.     if (!buf_valid(buf))
  2883. buf = firstbuf;
  2884. #endif
  2885. }
  2886. }
  2887.     static int
  2888. check_readonly(forceit)
  2889.     int     *forceit;
  2890. {
  2891.     if (!*forceit && curbuf->b_p_ro)
  2892.     {
  2893. #if defined(GUI_DIALOG) || defined(CON_DIALOG)
  2894. if ((p_confirm || confirm) && curbuf->b_fname != NULL)
  2895. {
  2896.     char_u buff[IOSIZE];
  2897.     dialog_msg(buff, "'readonly' option is set for "%.*s".nDo you wish to override it?",
  2898.     curbuf->b_fname);
  2899.     if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 0) == VIM_YES)
  2900.     {
  2901. /* Set forceit, to force the writing of a readonly file */
  2902. *forceit = TRUE;
  2903. return FALSE;
  2904.     }
  2905.     else
  2906. return TRUE;
  2907. }
  2908. else
  2909. #endif
  2910.     emsg(e_readonly);
  2911. return TRUE;
  2912.     }
  2913.     return FALSE;
  2914. }
  2915. /*
  2916.  * return TRUE if buffer was changed and cannot be abandoned.
  2917.  */
  2918.     static int
  2919. check_changed(buf, checkaw, mult_win, forceit, allbuf)
  2920.     BUF *buf;
  2921.     int checkaw; /* do autowrite if buffer was changed */
  2922.     int mult_win; /* check also when several wins for the buf */
  2923.     int forceit;
  2924.     int allbuf; /* may write all buffers */
  2925. {
  2926.     if (       !forceit
  2927.     && buf_changed(buf)
  2928.     && (mult_win || buf->b_nwindows <= 1)
  2929.     && (!checkaw || autowrite(buf, forceit) == FAIL))
  2930.     {
  2931. #if defined(GUI_DIALOG) || defined(CON_DIALOG)
  2932. if (p_confirm || confirm)
  2933. {
  2934.     BUF *buf2;
  2935.     int count = 0;
  2936.     if (allbuf)
  2937. for (buf2 = firstbuf; buf2 != NULL; buf2 = buf2->b_next)
  2938.     if (buf_changed(buf2)
  2939.      && (buf2->b_ffname != NULL
  2940. # ifdef USE_BROWSE
  2941.  || browse
  2942. # endif
  2943. ))
  2944. ++count;
  2945.     dialog_changed(buf, count > 1);
  2946.     return buf_changed(buf);
  2947. }
  2948. #endif
  2949. emsg(e_nowrtmsg);
  2950. return TRUE;
  2951.     }
  2952.     return FALSE;
  2953. }
  2954. #if defined(GUI_DIALOG) || defined(CON_DIALOG)
  2955. /*
  2956.  * Ask the user what to do when abondoning a changed buffer.
  2957.  */
  2958.     static void
  2959. dialog_changed(buf, checkall)
  2960.     BUF *buf;
  2961.     int checkall; /* may abandon all changed buffers */
  2962. {
  2963.     char_u buff[IOSIZE];
  2964.     int ret;
  2965.     BUF *buf2;
  2966.     dialog_msg(buff, "Save changes to "%.*s"?",
  2967. (buf->b_fname != NULL) ?
  2968. buf->b_fname : (char_u *)"Untitled");
  2969.     if (checkall)
  2970. ret = vim_dialog_yesnoallcancel(VIM_QUESTION, NULL, buff, 1);
  2971.     else
  2972. ret = vim_dialog_yesnocancel(VIM_QUESTION, NULL, buff, 1);
  2973.     if (ret == VIM_YES)
  2974.     {
  2975. #ifdef USE_BROWSE
  2976. /* May get file name, when there is none */
  2977. browse_save_fname(buf);
  2978. #endif
  2979. if (buf->b_fname != NULL)   /* didn't hit Cancel */
  2980.     (void)buf_write_all(buf);
  2981.     }
  2982.     else if (ret == VIM_NO)
  2983.     {
  2984. unchanged(buf, TRUE);
  2985.     }
  2986.     else if (ret == VIM_ALL)
  2987.     {
  2988. /*
  2989.  * Write all modified files that can be written.
  2990.  * Skip readonly buffers, these need to be confirmed
  2991.  * individually.
  2992.  */
  2993. for (buf2 = firstbuf; buf2 != NULL; buf2 = buf2->b_next)
  2994. {
  2995.     if (buf_changed(buf2)
  2996.     && (buf2->b_ffname != NULL
  2997. #ifdef USE_BROWSE
  2998. || browse
  2999. #endif
  3000. )
  3001.     && !buf2->b_p_ro)
  3002.     {
  3003. #ifdef USE_BROWSE
  3004. /* May get file name, when there is none */
  3005. browse_save_fname(buf2);
  3006. #endif
  3007. if (buf2->b_fname != NULL)   /* didn't hit Cancel */
  3008.     (void)buf_write_all(buf2);
  3009. #ifdef AUTOCMD
  3010. /* an autocommand may have deleted the buffer */
  3011. if (!buf_valid(buf2))
  3012.     buf2 = firstbuf;
  3013. #endif
  3014.     }
  3015. }
  3016.     }
  3017.     else if (ret == VIM_DISCARDALL)
  3018.     {
  3019. /*
  3020.  * mark all buffers as unchanged
  3021.  */
  3022. for (buf2 = firstbuf; buf2 != NULL; buf2 = buf2->b_next)
  3023.     unchanged(buf2, TRUE);
  3024.     }
  3025. }
  3026. #endif
  3027. #if defined(USE_BROWSE) && (defined(GUI_DIALOG) || defined(CON_DIALOG))
  3028. /*
  3029.  * When wanting to write a file without a file name, ask the user for a name.
  3030.  */
  3031.     static void
  3032. browse_save_fname(buf)
  3033.     BUF *buf;
  3034. {
  3035.     if (buf->b_fname == NULL)
  3036.     {
  3037. char_u *fname;
  3038. fname = do_browse(TRUE, (char_u *)"Save As", NULL, NULL, NULL,
  3039.    NULL, buf);
  3040. if (fname != NULL)
  3041. {
  3042.     setfname(fname, NULL, TRUE);
  3043.     vim_free(fname);
  3044. }
  3045.     }
  3046. }
  3047. #endif
  3048. /*
  3049.  * Return TRUE if the buffer "buf" can be abandoned, either by making it
  3050.  * hidden, autowriting it or unloading it.
  3051.  */
  3052.     int
  3053. can_abandon(buf, forceit)
  3054.     BUF     *buf;
  3055.     int     forceit;
  3056. {
  3057.     return (    p_hid
  3058. || !buf_changed(buf)
  3059. || buf->b_nwindows > 1
  3060. || autowrite(buf, forceit) == OK
  3061. || forceit);
  3062. }
  3063. /*
  3064.  * Return TRUE if any buffer was changed and cannot be abandoned.
  3065.  * That changed buffer becomes the current buffer.
  3066.  */
  3067.     int
  3068. check_changed_any(hidden)
  3069.     int hidden; /* Only check hidden buffers */
  3070. {
  3071.     BUF *buf;
  3072.     int save;
  3073. #if defined(GUI_DIALOG) || defined(CON_DIALOG)
  3074.     for (;;)
  3075.     {
  3076. #endif
  3077. /* check curbuf first: if it was changed we can't abandon it */
  3078. if (!hidden && buf_changed(curbuf))
  3079.     buf = curbuf;
  3080. else
  3081. {
  3082.     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  3083. if ((!hidden || buf->b_nwindows == 0) && buf_changed(buf))
  3084.     break;
  3085. }
  3086. if (buf == NULL)    /* No buffers changed */
  3087.     return FALSE;
  3088. #if defined(GUI_DIALOG) || defined(CON_DIALOG)
  3089. if (p_confirm || confirm)
  3090. {
  3091.     if (check_changed(buf, FALSE, TRUE, FALSE, TRUE))
  3092. break;     /* didn't save - still changes */
  3093. }
  3094. else
  3095.     break;     /* confirm not active - has changes */
  3096.     }
  3097. #endif
  3098.     exiting = FALSE;
  3099. #if defined(GUI_DIALOG) || defined(CON_DIALOG)
  3100.     /*
  3101.      * When ":confirm" used, don't give an error message.
  3102.      */
  3103.     if (!(p_confirm || confirm))
  3104. #endif
  3105.     {
  3106. /* There must be a wait_return for this message, do_buffer()
  3107.  * may cause a redraw.  But wait_return() is a no-op when vgetc()
  3108.  * is busy (Quit used from window menu), then make sure we don't
  3109.  * cause a scroll up. */
  3110. if (vgetc_busy)
  3111. {
  3112.     msg_row = cmdline_row;
  3113.     msg_col = 0;
  3114.     msg_didout = FALSE;
  3115. }
  3116. if (EMSG2("No write since last change for buffer "%s"",
  3117.     buf->b_fname == NULL ? (char_u *)"No File" :
  3118.     buf->b_fname))
  3119. {
  3120.     save = no_wait_return;
  3121.     no_wait_return = FALSE;
  3122.     wait_return(FALSE);
  3123.     no_wait_return = save;
  3124. }
  3125.     }
  3126.     (void)do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, buf->b_fnum, 0);
  3127.     return TRUE;
  3128. }
  3129. /*
  3130.  * return FAIL if there is no file name, OK if there is one
  3131.  * give error message for FAIL
  3132.  */
  3133.     int
  3134. check_fname()
  3135. {
  3136.     if (curbuf->b_ffname == NULL)
  3137.     {
  3138. emsg(e_noname);
  3139. return FAIL;
  3140.     }
  3141.     return OK;
  3142. }
  3143. /*
  3144.  * flush the contents of a buffer, unless it has no file name
  3145.  *
  3146.  * return FAIL for failure, OK otherwise
  3147.  */
  3148.     static int
  3149. buf_write_all(buf)
  3150.     BUF     *buf;
  3151. {
  3152.     int     retval;
  3153. #ifdef AUTOCMD
  3154.     BUF     *old_curbuf = curbuf;
  3155. #endif
  3156.     retval = (buf_write(buf, buf->b_ffname, buf->b_fname,
  3157.  (linenr_t)1, buf->b_ml.ml_line_count,
  3158.   FALSE, FALSE, TRUE, FALSE));
  3159. #ifdef AUTOCMD
  3160.     if (curbuf != old_curbuf)
  3161. MSG("Warning: Entered other buffer unexpectedly (check autocommands)");
  3162. #endif
  3163.     return retval;
  3164. }
  3165. /*
  3166.  * get + command from ex argument
  3167.  */
  3168.     static char_u *
  3169. getargcmd(argp)
  3170.     char_u **argp;
  3171. {
  3172.     char_u *arg = *argp;
  3173.     char_u *command = NULL;
  3174.     if (*arg == '+')     /* +[command] */
  3175.     {
  3176. ++arg;
  3177. if (vim_isspace(*arg))
  3178.     command = (char_u *)"$";
  3179. else
  3180. {
  3181.     command = arg;
  3182.     arg = skip_cmd_arg(command);
  3183.     if (*arg)
  3184. *arg++ = NUL; /* terminate command with NUL */
  3185. }
  3186. arg = skipwhite(arg); /* skip over spaces */
  3187. *argp = arg;
  3188.     }
  3189.     return command;
  3190. }
  3191. /*
  3192.  * Find end of "+command" argument.  Skip over " " and "\".
  3193.  */
  3194.     static char_u *
  3195. skip_cmd_arg(p)
  3196.     char_u *p;
  3197. {
  3198.     while (*p && !vim_isspace(*p))
  3199.     {
  3200. if (*p == '\' && p[1] != NUL)
  3201.     ++p;
  3202. ++p;
  3203.     }
  3204.     return p;
  3205. }
  3206. /*
  3207.  * Return TRUE if "str" starts with a backslash that should be removed.
  3208.  * For MS-DOS, WIN32 and OS/2 this is only done when the character after the
  3209.  * backslash is not a normal file name character.
  3210.  * Although '$' is a valid file name character, we remove the backslash before
  3211.  * it, to be able to disginguish between a file name that starts with '$' and
  3212.  * the name of an environment variable.
  3213.  * Make sure that "\mchfile" isn't translated into "mchfile".
  3214.  */
  3215.     static int
  3216. rem_backslash(str)
  3217.     char_u  *str;
  3218. {
  3219. #ifdef BACKSLASH_IN_FILENAME
  3220.     return (str[0] == '\'
  3221.     && (str[1] == '$'
  3222. || (str[1] != NUL
  3223.     && str[1] != '*'
  3224.     && str[1] != '?'
  3225.     && !vim_isfilec(str[1]))));
  3226. #else
  3227.     return (str[0] == '\' && str[1] != NUL);
  3228. #endif
  3229. }
  3230. /*
  3231.  * Halve the number of backslashes in a file name argument.
  3232.  * For MS-DOS we only do this if the character after the backslash
  3233.  * is not a normal file character.
  3234.  * For Unix, when wildcards are going to be expanded, don't remove
  3235.  * backslashes before special characters.
  3236.  */
  3237.     void
  3238. backslash_halve(p, has_wildcards)
  3239.     char_u  *p;
  3240.     int     has_wildcards; /* going to expand wildcards later */
  3241. {
  3242.     for ( ; *p; ++p)
  3243. if (rem_backslash(p)
  3244. #if defined(UNIX) || defined(OS2)
  3245. && !(has_wildcards &&
  3246. vim_strchr((char_u *)" *?[{`'~$\", p[1]) != NULL)
  3247. #endif
  3248.        )
  3249.     STRCPY(p, p + 1);
  3250. }
  3251. /*
  3252.  * write current buffer to file 'eap->arg'
  3253.  * if 'eap->append' is TRUE, append to the file
  3254.  *
  3255.  * if *eap->arg == NUL write to current file
  3256.  * if b_notedited is TRUE, check for overwriting current file
  3257.  *
  3258.  * return FAIL for failure, OK otherwise
  3259.  */
  3260.     static int
  3261. do_write(eap)
  3262.     EXARG *eap;
  3263. {
  3264.     int     other;
  3265.     char_u  *fname = NULL; /* init to shut up gcc */
  3266.     char_u  *ffname;
  3267.     int     retval = FAIL;
  3268.     char_u  *free_fname = NULL;
  3269. #ifdef USE_BROWSE
  3270.     char_u  *browse_file = NULL;
  3271. #endif
  3272.     ffname = eap->arg;
  3273. #ifdef USE_BROWSE
  3274.     if (browse)
  3275.     {
  3276. browse_file = do_browse(TRUE, (char_u *)"Save As", NULL,
  3277.   NULL, ffname, NULL, curbuf);
  3278. if (browse_file == NULL)
  3279.     goto theend;
  3280. ffname = browse_file;
  3281.     }
  3282. #endif
  3283.     if (*ffname == NUL)
  3284. other = FALSE;
  3285.     else
  3286.     {
  3287. fname = ffname;
  3288. free_fname = fix_fname(ffname);
  3289. /*
  3290.  * When out-of-memory, keep unexpanded file name, because we MUST be
  3291.  * able to write the file in this situation.
  3292.  */
  3293. if (free_fname != NULL)
  3294.     ffname = free_fname;
  3295. other = otherfile(ffname);
  3296.     }
  3297.     /*
  3298.      * If we have a new file, name put it in the list of alternate file names.
  3299.      */
  3300.     if (other && vim_strchr(p_cpo, CPO_ALTWRITE) != NULL)
  3301. setaltfname(ffname, fname, (linenr_t)1);
  3302.     /*
  3303.      * writing to the current file is not allowed in readonly mode
  3304.      * and need a file name
  3305.      */
  3306.     if (!other && (check_readonly(&eap->forceit) || check_fname() == FAIL))
  3307. goto theend;
  3308.     if (!other)
  3309.     {
  3310. ffname = curbuf->b_ffname;
  3311. fname = curbuf->b_fname;
  3312. /*
  3313.  * Not writing the whole file is only allowed with '!'.
  3314.  */
  3315. if (    (eap->line1 != 1
  3316.     || eap->line2 != curbuf->b_ml.ml_line_count)
  3317. && !eap->forceit
  3318. && !eap->append
  3319. && !p_wa)
  3320. {
  3321. #if defined(GUI_DIALOG) || defined(CON_DIALOG)
  3322.     if (p_confirm || confirm)
  3323.     {
  3324. if (vim_dialog_yesno(VIM_QUESTION, NULL,
  3325.        (char_u *)"Write partial file?", 2) != VIM_YES)
  3326.     goto theend;
  3327. eap->forceit = TRUE;
  3328. dont_wait_return = FALSE; /* show write message */
  3329.     }
  3330.     else
  3331. #endif
  3332.     {
  3333. EMSG("Use ! to write partial buffer");
  3334. goto theend;
  3335.     }
  3336. }
  3337.     }
  3338.     /*
  3339.      * write to other file or b_notedited set or not writing the whole file:
  3340.      * overwriting only allowed with '!'
  3341.      */
  3342.     if (       (other
  3343. || curbuf->b_notedited)
  3344.     && !eap->forceit
  3345.     && !eap->append
  3346.     && !p_wa
  3347.     && vim_fexists(ffname))
  3348.     {
  3349. #ifdef UNIX
  3350.     /* with UNIX it is possible to open a directory */
  3351. if (mch_isdir(ffname))
  3352. {
  3353.     EMSG2(""%s" is a directory", ffname);
  3354.     goto theend;
  3355. }
  3356. else
  3357. #endif
  3358. #if defined(GUI_DIALOG) || defined(CON_DIALOG)
  3359.      if (p_confirm || confirm)
  3360. {
  3361.     char_u buff[IOSIZE];
  3362.     dialog_msg(buff, "Overwrite existing file "%.*s"?", fname);
  3363.     if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) != VIM_YES)
  3364. goto theend;
  3365.     eap->forceit = TRUE;
  3366.     dont_wait_return = FALSE; /* show write message */
  3367. }
  3368. else
  3369. #endif
  3370. {
  3371.     emsg(e_exists);
  3372.     goto theend;
  3373. }
  3374.     }
  3375.     retval = (buf_write(curbuf, ffname, fname, eap->line1, eap->line2,
  3376.      eap->append, eap->forceit, TRUE, FALSE));
  3377. theend:
  3378. #ifdef USE_BROWSE
  3379.     vim_free(browse_file);
  3380. #endif
  3381.     vim_free(free_fname);
  3382.     return retval;
  3383. }
  3384. /*
  3385.  * try to abandon current file and edit a new or existing file
  3386.  * 'fnum' is the number of the file, if zero use ffname/sfname
  3387.  *
  3388.  * return 1 for "normal" error, 2 for "not written" error, 0 for success
  3389.  * -1 for succesfully opening another file
  3390.  * 'lnum' is the line number for the cursor in the new file (if non-zero).
  3391.  */
  3392.     int
  3393. getfile(fnum, ffname, sfname, setpm, lnum, forceit)
  3394.     int fnum;
  3395.     char_u *ffname;
  3396.     char_u *sfname;
  3397.     int setpm;
  3398.     linenr_t lnum;
  3399.     int forceit;
  3400. {
  3401.     int other;
  3402.     int retval;
  3403.     char_u *free_me = NULL;
  3404.     if (fnum == 0)
  3405.     {
  3406. fname_expand(&ffname, &sfname); /* make ffname full path, set sfname */
  3407. other = otherfile(ffname);
  3408. free_me = ffname; /* has been allocated, free() later */
  3409.     }
  3410.     else
  3411. other = (fnum != curbuf->b_fnum);
  3412.     if (other)
  3413. ++no_wait_return;     /* don't wait for autowrite message */
  3414.     if (other && !forceit && curbuf->b_nwindows == 1 && !p_hid
  3415.     && curbuf_changed() && autowrite(curbuf, forceit) == FAIL)
  3416.     {
  3417. if (other)
  3418.     --no_wait_return;
  3419. emsg(e_nowrtmsg);
  3420. retval = 2; /* file has been changed */
  3421. goto theend;
  3422.     }
  3423.     if (other)
  3424. --no_wait_return;
  3425.     if (setpm)
  3426. setpcmark();
  3427.     if (!other)
  3428.     {
  3429. if (lnum != 0)
  3430.     curwin->w_cursor.lnum = lnum;
  3431. check_cursor_lnum();
  3432. beginline(BL_SOL | BL_FIX);
  3433. retval = 0; /* it's in the same file */
  3434.     }
  3435.     else if (do_ecmd(fnum, ffname, sfname, NULL, lnum,
  3436. (p_hid ? ECMD_HIDE : 0) + (forceit ? ECMD_FORCEIT : 0)) == OK)
  3437. retval = -1; /* opened another file */
  3438.     else
  3439. retval = 1; /* error encountered */
  3440. theend:
  3441.     vim_free(free_me);
  3442.     return retval;
  3443. }