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

编辑器/阅读器

开发平台:

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. #define EXTERN
  9. #include "vim.h"
  10. #ifdef SPAWNO
  11. # include <spawno.h> /* special MSDOS swapping library */
  12. #endif
  13. static void mainerr __ARGS((int, char_u *));
  14. static void main_msg __ARGS((char *s));
  15. static void usage __ARGS((void));
  16. static int get_number_arg __ARGS((char_u *p, int *idx, int def));
  17. /*
  18.  * Type of error message.  These must match with errors[] in mainerr().
  19.  */
  20. #define ME_UNKNOWN_OPTION 0
  21. #define ME_TOO_MANY_ARGS 1
  22. #define ME_ARG_MISSING 2
  23. #define ME_GARBAGE 3
  24. #define ME_EXTRA_CMD 4
  25.     static void
  26. mainerr(n, str)
  27.     int     n;
  28.     char_u  *str;
  29. {
  30.     static char *(errors[]) =
  31.     {
  32. "Unknown option",
  33. "Too many edit arguments",
  34. "Argument missing after",
  35. "Garbage after option",
  36. "Too many "+command" or "-c command" arguments",
  37.     };
  38. #if defined(UNIX) || defined(__EMX__)
  39.     reset_signals(); /* kill us with CTRL-C here, if you like */
  40. #endif
  41.     mch_errmsg(longVersion);
  42.     mch_errmsg("n");
  43.     mch_errmsg(errors[n]);
  44.     if (str != NULL)
  45.     {
  46. mch_errmsg(": "");
  47. mch_errmsg((char *)str);
  48. mch_errmsg(""");
  49.     }
  50.     mch_errmsg("nMore info with: "vim -h"n");
  51.     mch_windexit(1);
  52. }
  53. /*
  54.  * print a message with three spaces prepended and 'n' appended.
  55.  */
  56.     static void
  57. main_msg(s)
  58.     char *s;
  59. {
  60.     mch_msg("   ");
  61.     mch_msg(s);
  62.     mch_msg("n");
  63. }
  64.     static void
  65. usage()
  66. {
  67.     int     i;
  68.     static char_u *(use[]) =
  69.     {
  70. (char_u *)"[file ..]       edit specified file(s)",
  71. (char_u *)"-               read from stdin",
  72. (char_u *)"-t tag          edit file where tag is defined",
  73. #ifdef QUICKFIX
  74. (char_u *)"-q [errorfile]  edit file with first error"
  75. #endif
  76.     };
  77. #if defined(UNIX) || defined(__EMX__)
  78.     reset_signals(); /* kill us with CTRL-C here, if you like */
  79. #endif
  80.     mch_msg(longVersion);
  81.     mch_msg("nusage:");
  82.     for (i = 0; ; ++i)
  83.     {
  84. mch_msg(" vim [options] ");
  85. mch_msg((char *)use[i]);
  86. if (i == (sizeof(use) / sizeof(char_u *)) - 1)
  87.     break;
  88. mch_msg("n   or:");
  89.     }
  90.     mch_msg("nnOptions:n");
  91.     main_msg("--tttEnd of options");
  92. #ifdef HAVE_OLE
  93.     main_msg("-registerttRegister this gvim for OLE");
  94.     main_msg("-unregisterttUnregister gvim for OLE");
  95. #endif
  96. #ifdef USE_GUI
  97.     main_msg("-gtttRun using GUI (like "gvim")");
  98.     main_msg("-ftttForeground: Don't fork when starting GUI");
  99. #endif
  100.     main_msg("-vtttVi mode (like "vi")");
  101.     main_msg("-etttEx mode (like "ex")");
  102.     main_msg("-stttSilent (batch) mode (only for "ex")");
  103.     main_msg("-RtttReadonly mode (like "view")");
  104.     main_msg("-ZtttRestricted mode (like "rvim")");
  105.     main_msg("-btttBinary mode");
  106. #ifdef LISPINDENT
  107.     main_msg("-ltttLisp mode");
  108. #endif
  109.     main_msg("-CtttCompatible with Vi: 'compatible'");
  110.     main_msg("-NtttNot fully Vi compatible: 'nocompatible'");
  111.     main_msg("-V[N]ttVerbose level");
  112.     main_msg("-ntttNo swap file, use memory only");
  113.     main_msg("-rtttList swap files and exit");
  114.     main_msg("-r (with file name)tRecover crashed session");
  115.     main_msg("-LtttSame as -r");
  116. #ifdef AMIGA
  117.     main_msg("-ftttDon't use newcli to open window");
  118.     main_msg("-d <device>ttUse <device> for I/O");
  119. #endif
  120. #ifdef RIGHTLEFT
  121.     main_msg("-Htttstart in Hebrew mode");
  122. #endif
  123. #ifdef FKMAP
  124.     main_msg("-Ftttstart in Farsi mode");
  125. #endif
  126.     main_msg("-T <terminal>tSet terminal type to <terminal>");
  127.     main_msg("-o[N]ttOpen N windows (default: one for each file)");
  128.     main_msg("+tttStart at end of file");
  129.     main_msg("+<lnum>ttStart at line <lnum>");
  130.     main_msg("-c <command>ttExecute <command> first");
  131.     main_msg("-s <scriptin>tRead commands from script file <scriptin>");
  132.     main_msg("-w <scriptout>tAppend commands to script file <scriptout>");
  133.     main_msg("-W <scriptout>tWrite commands to script file <scriptout>");
  134.     main_msg("-u <vimrc>ttUse <vimrc> instead of any .vimrc");
  135. #ifdef USE_GUI
  136.     main_msg("-U <gvimrc>ttUse <gvimrc> instead of any .gvimrc");
  137. #endif
  138. #ifdef VIMINFO
  139.     main_msg("-i <viminfo>ttUse <viminfo> instead of .viminfo");
  140. #endif
  141.     main_msg("-htttprint Help (this message) and exit");
  142.     main_msg("--versionttprint version information and exit");
  143. #ifdef USE_GUI_X11
  144. # ifdef USE_GUI_MOTIF
  145.     mch_msg("nOptions recognised by gvim (Motif version):n");
  146. # else
  147. #  ifdef USE_GUI_ATHENA
  148.     mch_msg("nOptions recognised by gvim (Athena version):n");
  149. #  endif /* USE_GUI_ATHENA */
  150. # endif /* USE_GUI_MOTIF */
  151.     main_msg("-display <display>tRun vim on <display>");
  152.     main_msg("-iconicttStart vim iconified");
  153. # if 0
  154.     main_msg("-name <name>ttUse resource as if vim was <name>");
  155.     mch_msg("ttt  (Unimplemented)n");
  156. # endif
  157.     main_msg("-background <color>tUse <color> for the background (also: -bg)");
  158.     main_msg("-foreground <color>tUse <color> for normal text (also: -fg)");
  159.     main_msg("-font <font>ttUse <font> for normal text (also: -fn)");
  160.     main_msg("-boldfont <font>tUse <font> for bold text");
  161.     main_msg("-italicfont <font>tUse <font> for italic text");
  162.     main_msg("-geometry <geom>tUse <geom> for initial geometry (also: -geom)");
  163.     main_msg("-borderwidth <width>tUse a border width of <width> (also: -bw)");
  164.     main_msg("-scrollbarwidth <width>tUse a scrollbar width of <width> (also: -sw)");
  165.     main_msg("-menuheight <height>tUse a menu bar height of <height> (also: -mh)");
  166.     main_msg("-reversettUse reverse video (also: -rv)");
  167.     main_msg("+reversettDon't use reverse video (also: +rv)");
  168.     main_msg("-xrm <resource>tSet the specified resource");
  169. #endif /* USE_GUI_X11 */
  170.     mch_windexit(1);
  171. }
  172. #ifdef HAVE_LOCALE_H
  173. # include <locale.h>
  174. #endif
  175. /* Maximum number of commands from + or -c options */
  176. #define MAX_ARG_CMDS 10
  177. #ifndef PROTO     /* don't want a prototype for main() */
  178.     int
  179. #ifdef VIMDLL
  180. _export
  181. #endif
  182. main(argc, argv)
  183.     int     argc;
  184.     char   **argv;
  185. {
  186.     char_u    *initstr;     /* init string from environment */
  187.     char_u    *term = NULL;     /* specified terminal name */
  188.     char_u    *fname = NULL;     /* file name from command line */
  189.     char_u    *tagname = NULL;     /* tag from -t option */
  190.     char_u    *use_vimrc = NULL;     /* vimrc from -u option */
  191. #ifdef QUICKFIX
  192.     char_u    *use_ef = NULL;     /* 'errorfile' from -q option */
  193. #endif
  194.     int     n_commands = 0;     /* no. of commands from + or -c */
  195.     char_u    *commands[MAX_ARG_CMDS]; /* commands from + or -c option */
  196.     int     no_swap_file = FALSE;   /* "-n" option used */
  197.     int     c;
  198.     int     i;
  199.     int     bin_mode = FALSE;     /* -b option used */
  200.     int     window_count = 1;     /* number of windows to use */
  201.     int     arg_idx = 0;     /* index for arg_files[] */
  202.     int     had_minmin = FALSE;     /* found "--" option */
  203.     int     argv_idx;     /* index in argv[n][] */
  204.     int     want_full_screen = TRUE;
  205.     int     want_argument;     /* option with argument */
  206. #define EDIT_NONE   0     /* no edit type yet */
  207. #define EDIT_FILE   1     /* file name argument[s] given, use arg_files[] */
  208. #define EDIT_STDIN  2     /* read file from stdin */
  209. #define EDIT_TAG    3     /* tag name argument given, use tagname */
  210. #define EDIT_QF     4     /* start in quickfix mode */
  211.     int     edit_type = EDIT_NONE;  /* type of editing to do */
  212.     int     stdout_isatty;     /* is stdout a terminal? */
  213.     int     input_isatty;     /* is active input a terminal? */
  214.     OPARG     oa;     /* operator arguments */
  215. #ifdef RISCOS
  216.     /* Turn off all the horrible filename munging in UnixLib. */
  217.     __uname_control = __UNAME_NO_PROCESS;
  218. #endif
  219. #if defined(MSDOS) || defined(WIN32) || defined(OS2)
  220.     /*
  221.      * Default mappings for some often used keys.
  222.      * Use the Windows (CUA) keybindings.
  223.      */
  224.     static struct initmap
  225.     {
  226. char_u     *arg;
  227. int     mode;
  228.     } initmappings[] =
  229.     {
  230. # ifdef USE_GUI
  231. {(char_u *)"<C-PageUp> H", NORMAL+VISUAL},
  232. {(char_u *)"<C-PageUp> <C-O>H",INSERT},
  233. {(char_u *)"<C-PageDown> L$", NORMAL+VISUAL},
  234. {(char_u *)"<C-PageDown> <C-O>L<C-O>$", INSERT},
  235. /* paste, copy and cut */
  236. {(char_u *)"<S-Insert> "*P", NORMAL},
  237. {(char_u *)"<S-Insert> "-d"*P", VISUAL},
  238. {(char_u *)"<S-Insert> <C-R>*", INSERT+CMDLINE},
  239. {(char_u *)"<C-Insert> "*y", VISUAL},
  240. {(char_u *)"<S-Del> "*d", VISUAL},
  241. {(char_u *)"<C-Del> "*d", VISUAL},
  242. {(char_u *)"<C-X> "*d", VISUAL},
  243. /* Missing: CTRL-C (can't be mapped) and CTRL-V (means something) */
  244. # else
  245. {(char_u *)"316204 H", NORMAL+VISUAL},    /* CTRL-PageUp is "H" */
  246. {(char_u *)"316204 17H",INSERT},     /* CTRL-PageUp is "^OH"*/
  247. {(char_u *)"316v L$", NORMAL+VISUAL},     /* CTRL-PageDown is "L$" */
  248. {(char_u *)"316v 17L17$", INSERT},     /* CTRL-PageDown ="^OL^O$"*/
  249. {(char_u *)"316w <C-Home>", NORMAL+VISUAL},
  250. {(char_u *)"316w <C-Home>", INSERT+CMDLINE},
  251. {(char_u *)"316u <C-End>", NORMAL+VISUAL},
  252. {(char_u *)"316u <C-End>", INSERT+CMDLINE},
  253. /* paste, copy and cut */
  254. #  ifdef USE_CLIPBOARD
  255. {(char_u *)"316324 "*P", NORMAL},     /* SHIFT-Insert is "*P */
  256. {(char_u *)"316324 "-d"*P", VISUAL},    /* SHIFT-Insert is "-d"*P */
  257. {(char_u *)"316324 17"*P", INSERT},    /* SHIFT-Insert is ^O"*P */
  258. {(char_u *)"316325 "*y", VISUAL},     /* CTRL-Insert is "*y */
  259. {(char_u *)"316327 "*d", VISUAL},     /* SHIFT-Del is "*d */
  260. {(char_u *)"316330 "*d", VISUAL},     /* CTRL-Del is "*d */
  261. {(char_u *)"30 "-d", VISUAL},     /* CTRL-X is "-d */
  262. #  else
  263. {(char_u *)"316324 P", NORMAL},     /* SHIFT-Insert is P */
  264. {(char_u *)"316324 d"0P", VISUAL},     /* SHIFT-Insert is d"0P */
  265. {(char_u *)"316324 17P", INSERT},     /* SHIFT-Insert is ^OP */
  266. {(char_u *)"316325 y", VISUAL},     /* CTRL-Insert is y */
  267. {(char_u *)"316327 d", VISUAL},     /* SHIFT-Del is d */
  268. {(char_u *)"316330 d", VISUAL},     /* CTRL-Del is d */
  269. #  endif
  270. # endif
  271.     };
  272. #endif
  273. #if defined(macintosh)
  274.     /*
  275.      * Default mappings for some often used keys.
  276.      * Use the Standard MacOS binding.
  277.      */
  278.     static struct initmap
  279.     {
  280. char_u     *arg;
  281. int     mode;
  282.     } initmappings[] =
  283.     {
  284. /* paste, copy and cut */
  285. {(char_u *)"<D-v> "*P", NORMAL},
  286. {(char_u *)"<D-v> "-d"*P", VISUAL},
  287. {(char_u *)"<D-v> <C-R>*", INSERT+CMDLINE},
  288. {(char_u *)"<D-c> "*y", VISUAL},
  289. {(char_u *)"<D-x> "*d", VISUAL},
  290. {(char_u *)"<Backspace> "-d", VISUAL},
  291.     };
  292. #endif
  293. #ifdef MEM_PROFILE
  294.     atexit(vim_mem_profile_dump);
  295. #endif
  296. #ifdef __EMX__
  297.     _wildcard(&argc, &argv);
  298. #endif
  299. #ifdef HAVE_LOCALE_H
  300.     setlocale(LC_ALL, ""); /* for ctype() and the like */
  301. #endif
  302. #if defined(USE_GUI_WIN32) && defined(HAVE_OLE)
  303.     /* Check for special OLE command line parameters */
  304.     if (argc == 2 && (argv[1][0] == '-' || argv[1][0] == '/'))
  305.     {
  306. /* Register Vim as an OLE Automation server */
  307. if (STRICMP(argv[1] + 1, "register") == 0)
  308. {
  309.     RegisterMe();
  310.     mch_windexit(0);
  311. }
  312. /* Unregister Vim as an OLE Automation server */
  313. if (STRICMP(argv[1] + 1, "unregister") == 0)
  314. {
  315.     UnregisterMe(TRUE);
  316.     mch_windexit(0);
  317. }
  318. /* Ignore an -embedding argument. It is only relevant if the
  319.  * application wants to treat the case when it is started manually
  320.  * differently from the case where it is started via automation (and
  321.  * we don't).
  322.  */
  323. if (STRICMP(argv[1] + 1, "embedding") == 0)
  324.     argc = 1;
  325.     }
  326.     {
  327. int bDoRestart = FALSE;
  328. InitOLE(&bDoRestart);
  329. /* automatically exit after registering */
  330. if (bDoRestart)
  331.     mch_windexit(0);
  332.     }
  333. #endif
  334. #ifdef USE_GUI
  335.     gui_prepare(&argc, argv); /* Prepare for possibly starting GUI sometime */
  336. #endif
  337. #ifdef USE_CLIPBOARD
  338.     clip_init(FALSE); /* Initialise clipboard stuff */
  339. #endif
  340.     /*
  341.      * Check if we have an interactive window.
  342.      * On the Amiga: If there is no window, we open one with a newcli command
  343.      * (needed for :! to * work). mch_check_win() will also handle the -d
  344.      * argument.
  345.      */
  346.     stdout_isatty = (mch_check_win(argc, argv) != FAIL);
  347.     /*
  348.      * allocate the first window and buffer. Can't do anything without it
  349.      */
  350.     if ((curwin = win_alloc(NULL)) == NULL ||
  351. (curbuf = buflist_new(NULL, NULL, 1L, FALSE)) == NULL)
  352. mch_windexit(0);
  353.     curwin->w_buffer = curbuf;
  354.     curbuf->b_nwindows = 1; /* there is one window */
  355.     win_init(curwin); /* init current window */
  356.     init_yank(); /* init yank buffers */
  357.     /*
  358.      * Allocate space for the generic buffers (needed for set_init_1()).
  359.      */
  360.     if ((IObuff = alloc(IOSIZE)) == NULL ||
  361.     (NameBuff = alloc(MAXPATHL)) == NULL)
  362. mch_windexit(0);
  363.     /*
  364.      * Set the default values for the options.
  365.      * First find out the home directory, needed to expand "~" in options.
  366.      */
  367.     init_homedir(); /* find real value of $HOME */
  368.     set_init_1();
  369.     /*
  370.      * If the executable name starts with "r" we disable shell commands.
  371.      * If the next character is "g" we run the GUI version.
  372.      * If the next characters are "view" we start in readonly mode.
  373.      * If the next characters are "ex" we start in ex mode.
  374.      */
  375.     initstr = gettail((char_u *)argv[0]);
  376.     if (initstr[0] == 'r')
  377.     {
  378. restricted = TRUE;
  379. ++initstr;
  380.     }
  381.     if (initstr[0] == 'g')
  382.     {
  383. #ifdef USE_GUI
  384. gui.starting = TRUE;
  385. ++initstr;
  386. #else
  387. mch_errmsg((char *)e_nogvim);
  388. mch_windexit(2);
  389. #endif
  390.     }
  391.     if (STRNCMP(initstr, "view", 4) == 0)
  392.     {
  393. readonlymode = TRUE;
  394. curbuf->b_p_ro = TRUE;
  395. p_uc = 10000; /* don't update very often */
  396.     }
  397.     if (STRNCMP(initstr, "ex", 2) == 0)
  398.     {
  399. exmode_active = TRUE;
  400. change_compatible(TRUE); /* set 'compatible' */
  401.     }
  402.     /*
  403.      * On some systems, when we compile with the GUI, we always use it.  On Mac
  404.      * there is no terminal version, and on Windows we can't figure out how to
  405.      * fork one off with :gui.
  406.      */
  407. #ifdef ALWAYS_USE_GUI
  408.     gui.starting = TRUE;
  409. #endif
  410.     ++argv;
  411.     --argc;
  412. #ifndef macintosh
  413.     /*
  414.      * Allocate arg_files[], big enough to hold all potential file name
  415.      * arguments.
  416.      */
  417.     arg_files = (char_u **)alloc((unsigned)(sizeof(char_u *) * (argc + 1)));
  418.     if (arg_files == NULL)
  419. mch_windexit(2);
  420. #else
  421.     arg_files = NULL;
  422. #endif
  423.     arg_file_count = 0;
  424.     /*
  425.      * Process the command line arguments.
  426.      */
  427.     argv_idx = 1;     /* active option letter is argv[0][argv_idx] */
  428.     while (argc > 0)
  429.     {
  430. /*
  431.  * "+" or "+{number}" or "+/{pat}" or "+{command}" argument.
  432.  */
  433. if (argv[0][0] == '+' && !had_minmin)
  434. {
  435.     if (n_commands >= MAX_ARG_CMDS)
  436. mainerr(ME_EXTRA_CMD, NULL);
  437.     argv_idx = -1;     /* skip to next argument */
  438.     if (argv[0][1] == NUL)
  439. commands[n_commands++] = (char_u *)"$";
  440.     else
  441. commands[n_commands++] = (char_u *)&(argv[0][1]);
  442. }
  443. /*
  444.  * Option argument.
  445.  */
  446. else if (argv[0][0] == '-' && !had_minmin)
  447. {
  448.     want_argument = FALSE;
  449.     c = argv[0][argv_idx++];
  450.     switch (c)
  451.     {
  452.     case NUL: /* "-"  read from stdin */
  453. if (edit_type != EDIT_NONE)
  454.     mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
  455. edit_type = EDIT_STDIN;
  456. read_cmd_fd = 2; /* read from stderr instead of stdin */
  457. argv_idx = -1; /* skip to next argument */
  458. break;
  459.     case '-': /* "--" don't take any more options */
  460. /* "--help" give help message */
  461. /* "--version" give version message */
  462. if (STRCMP(argv[0] + argv_idx, "help") == 0)
  463.     usage();
  464. if (STRCMP(argv[0] + argv_idx, "version") == 0)
  465. {
  466.     Columns = 80; /* need to init Columns */
  467.     do_version((char_u *)"");
  468.     mch_windexit(1);
  469. }
  470. if (argv[0][argv_idx])
  471.     mainerr(ME_UNKNOWN_OPTION, (char_u *)argv[0]);
  472. had_minmin = TRUE;
  473. argv_idx = -1; /* skip to next argument */
  474. break;
  475.     case 'b': /* "-b" binary mode */
  476. bin_mode = TRUE;    /* postpone to after reading .exrc files */
  477. break;
  478.     case 'C': /* "-C"  Compatible */
  479. change_compatible(TRUE);
  480. break;
  481.     case 'e': /* "-e" Ex mode */
  482. exmode_active = TRUE;
  483. break;
  484.     case 'f': /* "-f"  GUI: run in foreground.  Amiga: open
  485. window directly, not with newcli */
  486. #ifdef USE_GUI
  487. gui.dofork = FALSE; /* don't fork() when starting GUI */
  488. #endif
  489. break;
  490.     case 'g': /* "-g" start GUI */
  491. #ifdef USE_GUI
  492. gui.starting = TRUE; /* start GUI a bit later */
  493. #else
  494. mch_errmsg((char *)e_nogvim);
  495. mch_windexit(2);
  496. #endif
  497. break;
  498.     case 'F': /* "-F" start in Farsi mode: rl + fkmap set */
  499. #ifdef FKMAP
  500. curwin->w_p_rl = p_fkmap = TRUE;
  501. #else
  502. mch_errmsg((char *)e_nofarsi);
  503. mch_windexit(2);
  504. #endif
  505. break;
  506.     case 'h': /* "-h" give help message */
  507. usage();
  508. break;
  509.     case 'H': /* "-H" start in Hebrew mode: rl + hkmap set */
  510. #ifdef RIGHTLEFT
  511. curwin->w_p_rl = p_hkmap = TRUE;
  512. #else
  513. mch_errmsg((char *)e_nohebrew);
  514. mch_windexit(2);
  515. #endif
  516. break;
  517.     case 'l': /* "-l" lisp mode, 'lisp' and 'showmatch' on */
  518. #ifdef LISPINDENT
  519. curbuf->b_p_lisp = TRUE;
  520. p_sm = TRUE;
  521. #endif
  522. break;
  523.     case 'N': /* "-N"  Nocompatible */
  524. change_compatible(FALSE);
  525. break;
  526.     case 'n': /* "-n" no swap file */
  527. no_swap_file = TRUE;
  528. break;
  529.     case 'o': /* "-o[N]" open N windows */
  530. /* default is 0: open window for each file */
  531. window_count = get_number_arg((char_u *)argv[0], &argv_idx, 0);
  532. break;
  533. #ifdef QUICKFIX
  534.     case 'q': /* "-q" QuickFix mode */
  535. if (edit_type != EDIT_NONE)
  536.     mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
  537. edit_type = EDIT_QF;
  538. if (argv[0][argv_idx]) /* "-q{errorfile}" */
  539. {
  540.     use_ef = (char_u *)argv[0] + argv_idx;
  541.     argv_idx = -1;
  542. }
  543. else if (argc > 1) /* "-q {errorfile}" */
  544.     want_argument = TRUE;
  545. break;
  546. #endif
  547.     case 'R': /* "-R" readonly mode */
  548. readonlymode = TRUE;
  549. curbuf->b_p_ro = TRUE;
  550. p_uc = 10000; /* don't update very often */
  551. break;
  552.     case 'r': /* "-r" recovery mode */
  553.     case 'L': /* "-L" recovery mode */
  554. recoverymode = 1;
  555. break;
  556.     case 's':
  557. if (exmode_active) /* "-s" silent (batch) mode */
  558.     silent_mode = TRUE;
  559. else /* "-s {scriptin}" read from script file */
  560.     want_argument = TRUE;
  561. break;
  562.     case 't': /* "-t {tag}" or "-t{tag}" jump to tag */
  563. if (edit_type != EDIT_NONE)
  564.     mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
  565. edit_type = EDIT_TAG;
  566. if (argv[0][argv_idx]) /* "-t{tag}" */
  567. {
  568.     tagname = (char_u *)argv[0] + argv_idx;
  569.     argv_idx = -1;
  570. }
  571. else /* "-t {tag}" */
  572.     want_argument = TRUE;
  573. break;
  574.     case 'V': /* "-V{N}" Verbose level */
  575. /* default is 10: a little bit verbose */
  576. p_verbose = get_number_arg((char_u *)argv[0], &argv_idx, 10);
  577. break;
  578.     case 'v': /* "-v"  Vi-mode (as if called "vi") */
  579. exmode_active = FALSE;
  580. break;
  581.     case 'w': /* "-w{number}" set window height */
  582. /* "-w {scriptout}" write to script */
  583. if (isdigit(((char_u *)argv[0])[argv_idx]))
  584. {
  585.     argv_idx = -1;
  586.     break; /* not implemented, ignored */
  587. }
  588. want_argument = TRUE;
  589. break;
  590.     case 'x':     /* "-x"  use "crypt" for reading/writing files. */
  591. /* TODO */
  592. break;
  593.     case 'Z': /* "-Z"  restricted mode */
  594. restricted = TRUE;
  595. break;
  596.     case 'c': /* "-c {command}" execute command */
  597.     case 'd': /* "-d {device}" device (for Amiga) */
  598.     case 'i': /* "-i {viminfo}" use for viminfo */
  599.     case 'T': /* "-T {terminal}" terminal name */
  600.     case 'u': /* "-u {vimrc}" vim inits file */
  601.     case 'U': /* "-U {gvimrc}" gvim inits file */
  602.     case 'W': /* "-W {scriptout}" overwrite */
  603. want_argument = TRUE;
  604. break;
  605.     default:
  606. mainerr(ME_UNKNOWN_OPTION, (char_u *)argv[0]);
  607.     }
  608.     /*
  609.      * Handle options with argument.
  610.      */
  611.     if (want_argument)
  612.     {
  613. /*
  614.  * Check for garbage immediately after the option letter.
  615.  */
  616. if (argv[0][argv_idx] != NUL)
  617.     mainerr(ME_GARBAGE, (char_u *)argv[0]);
  618. --argc;
  619. if (argc < 1)
  620.     mainerr(ME_ARG_MISSING, (char_u *)argv[0]);
  621. ++argv;
  622. argv_idx = -1;
  623. switch (c)
  624. {
  625. case 'c': /* "-c {command}" execute command */
  626.     if (n_commands >= MAX_ARG_CMDS)
  627. mainerr(ME_EXTRA_CMD, NULL);
  628.     commands[n_commands++] = (char_u *)argv[0];
  629.     break;
  630.     /* case 'd':   This is handled in mch_check_win() */
  631. #ifdef QUICKFIX
  632. case 'q': /* "-q {errorfile}" QuickFix mode */
  633.     use_ef = (char_u *)argv[0];
  634.     break;
  635. #endif
  636. case 'i': /* "-i {viminfo}" use for viminfo */
  637.     use_viminfo = (char_u *)argv[0];
  638.     break;
  639. case 's': /* "-s {scriptin}" read from script file */
  640.     if (scriptin[0] != NULL)
  641.     {
  642. mch_errmsg("Attempt to open script file again: "");
  643. mch_errmsg(argv[-1]);
  644. mch_errmsg(" ");
  645. mch_errmsg(argv[0]);
  646. mch_errmsg(""n");
  647. mch_windexit(2);
  648.     }
  649.     if ((scriptin[0] = fopen(argv[0], READBIN)) == NULL)
  650.     {
  651. mch_errmsg("Cannot open "");
  652. mch_errmsg(argv[0]);
  653. mch_errmsg("" for readingn");
  654. mch_windexit(2);
  655.     }
  656.     if (save_typebuf() == FAIL)
  657. mch_windexit(2); /* out of memory */
  658.     break;
  659. case 't': /* "-t {tag}" */
  660.     tagname = (char_u *)argv[0];
  661.     break;
  662. case 'T': /* "-T {terminal}" terminal name */
  663.     /*
  664.      * The -T term option is always available and when
  665.      * HAVE_TERMLIB is supported it overrides the environment
  666.      * variable TERM.
  667.      */
  668. #ifdef USE_GUI
  669.     if (term_is_gui((char_u *)argv[0]))
  670. gui.starting = TRUE; /* start GUI a bit later */
  671.     else
  672. #endif
  673. term = (char_u *)argv[0];
  674.     break;
  675. case 'u': /* "-u {vimrc}" vim inits file */
  676.     use_vimrc = (char_u *)argv[0];
  677.     break;
  678. case 'U': /* "-U {gvimrc}" gvim inits file */
  679.     use_gvimrc = (char_u *)argv[0];
  680.     break;
  681. case 'w': /* "-w {scriptout}" append to script file */
  682. case 'W': /* "-W {scriptout}" overwrite script file */
  683.     if (scriptout != NULL)
  684.     {
  685. mch_errmsg("Attempt to open script file again: "");
  686. mch_errmsg(argv[-1]);
  687. mch_errmsg(" ");
  688. mch_errmsg(argv[0]);
  689. mch_errmsg(""n");
  690. mch_windexit(2);
  691.     }
  692.     if ((scriptout = fopen(argv[0],
  693.     c == 'w' ? APPENDBIN : WRITEBIN)) == NULL)
  694.     {
  695. mch_errmsg("cannot open "");
  696. mch_errmsg(argv[0]);
  697. mch_errmsg("" for outputn");
  698. mch_windexit(2);
  699.     }
  700.     break;
  701. }
  702.     }
  703. }
  704. /*
  705.  * File name argument.
  706.  */
  707. else
  708. {
  709.     argv_idx = -1;     /* skip to next argument */
  710.     if (edit_type != EDIT_NONE && edit_type != EDIT_FILE)
  711. mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
  712.     edit_type = EDIT_FILE;
  713.     arg_files[arg_file_count] = vim_strsave((char_u *)argv[0]);
  714.     if (arg_files[arg_file_count] != NULL)
  715. ++arg_file_count;
  716. }
  717. /*
  718.  * If there are no more letters after the current "-", go to next
  719.  * argument.  argv_idx is set to -1 when the current argument is to be
  720.  * skipped.
  721.  */
  722. if (argv_idx <= 0 || argv[0][argv_idx] == NUL)
  723. {
  724.     --argc;
  725.     ++argv;
  726.     argv_idx = 1;
  727. }
  728.     }
  729.     /*
  730.      * May expand wildcards in file names.
  731.      */
  732.     if (arg_file_count > 0)
  733.     {
  734. #if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
  735. char_u     **new_arg_files;
  736. int     new_arg_file_count;
  737. if (expand_wildcards(arg_file_count, arg_files, &new_arg_file_count,
  738.     &new_arg_files, EW_FILE|EW_NOTFOUND) == OK
  739. && new_arg_file_count != 0)
  740. {
  741.     FreeWild(arg_file_count, arg_files);
  742.     arg_file_count = new_arg_file_count;
  743.     arg_files = new_arg_files;
  744. }
  745. #endif
  746. fname = arg_files[0];
  747.     }
  748.     if (arg_file_count > 1)
  749. printf("%d files to editn", arg_file_count);
  750. #ifdef WIN32
  751.     else if (arg_file_count == 1)
  752.     {
  753. /*
  754.  * If there is one filename, fully qualified, we have very probably
  755.  * been invoked from explorer, so change to the file's directory.
  756.  */
  757. if (fname[0] != NUL && fname[1] == ':' && fname[2] == '\')
  758. {
  759.     /* If the cd fails, it doesn't matter.. */
  760.     (void)vim_chdirfile(fname);
  761. }
  762.     }
  763. #endif
  764.     RedrawingDisabled = TRUE;
  765.     /*
  766.      * When listing swap file names, don't do cursor positioning et. al.
  767.      */
  768.     if (recoverymode && fname == NULL)
  769. want_full_screen = FALSE;
  770.     /*
  771.      * When starting the GUI, don't need to check capabilities of terminal.
  772.      */
  773. #ifdef USE_GUI
  774.     if (gui.starting)
  775. want_full_screen = FALSE;
  776. #endif
  777.     /*
  778.      * mch_windinit() sets up the terminal (window) for use.  This must be
  779.      * done after resetting full_screen, otherwise it may move the cursor
  780.      * (MSDOS).
  781.      * Note that we may use mch_windexit() before mch_windinit()!
  782.      */
  783.     mch_windinit();
  784.     /*
  785.      * Print a warning if stdout is not a terminal.
  786.      * When starting in Ex mode and commands come from a file, set Silent mode.
  787.      */
  788.     input_isatty = mch_input_isatty();
  789.     if (exmode_active)
  790.     {
  791. if (!input_isatty)
  792.     silent_mode = TRUE;
  793.     }
  794.     else if (want_full_screen && (!stdout_isatty || !input_isatty))
  795.     {
  796. if (!stdout_isatty)
  797.     mch_errmsg("Vim: Warning: Output is not to a terminaln");
  798. if (!input_isatty)
  799.     mch_errmsg("Vim: Warning: Input is not from a terminaln");
  800. ui_delay(2000L, TRUE);
  801.     }
  802.     if (want_full_screen)
  803.     {
  804. termcapinit(term); /* set terminal name and get terminal
  805.    capabilities (will set full_screen) */
  806. screen_start(); /* don't know where cursor is now */
  807.     }
  808.     screenclear(); /* clear screen (just inits screen structures,
  809.     because starting is TRUE) */
  810.     /*
  811.      * Set the default values for the options that use Rows and Columns.
  812.      */
  813.     ui_get_winsize(); /* inits Rows and Columns */
  814.     set_init_2();
  815.     firstwin->w_height = Rows - 1;
  816.     cmdline_row = Rows - 1;
  817.     if (full_screen)
  818. msg_start();     /* in case a mapping or error message is printed */
  819.     msg_scroll = TRUE;
  820.     no_wait_return = TRUE;
  821. #if defined(MSDOS) || defined(WIN32) || defined(OS2) || defined(macintosh)
  822.     /*
  823.      * Default mappings for some often used keys.
  824.      * Need to put string in allocated memory, because do_map() will modify it.
  825.      */
  826.     {
  827. char_u *cpo_save = p_cpo;
  828. p_cpo = (char_u *)""; /* Allow <> notation */
  829. for (i = 0; i < sizeof(initmappings) / sizeof(struct initmap); ++i)
  830. {
  831.     initstr = vim_strsave(initmappings[i].arg);
  832.     if (initstr != NULL)
  833.     {
  834. do_map(0, initstr, initmappings[i].mode, FALSE);
  835. vim_free(initstr);
  836.     }
  837. }
  838. p_cpo = cpo_save;
  839.     }
  840. #endif
  841.     init_highlight(TRUE); /* set the default highlight groups */
  842. #ifdef CURSOR_SHAPE
  843.     parse_guicursor(); /* set cursor shapes from 'guicursor' */
  844. #endif
  845.     /*
  846.      * If -u option given, use only the initializations from that file and
  847.      * nothing else.
  848.      */
  849.     if (use_vimrc != NULL)
  850.     {
  851. if (STRCMP(use_vimrc, "NONE") == 0)
  852. {
  853.     if (use_gvimrc == NULL)     /* don't load gvimrc either */
  854. use_gvimrc = use_vimrc;
  855. }
  856. else
  857. {
  858.     if (do_source(use_vimrc, FALSE, FALSE) != OK)
  859. EMSG2("Cannot read from "%s"", use_vimrc);
  860. }
  861.     }
  862.     else if (!silent_mode)
  863.     {
  864. /*
  865.  * Get system wide defaults, if the file name is defined.
  866.  */
  867. #ifdef SYS_VIMRC_FILE
  868. (void)do_source((char_u *)SYS_VIMRC_FILE, TRUE, FALSE);
  869. #endif
  870. /*
  871.  * Try to read initialization commands from the following places:
  872.  * - environment variable VIMINIT
  873.  * - user vimrc file (s:.vimrc for Amiga, ~/.vimrc otherwise)
  874.  * - second user vimrc file ($VIM/.vimrc for Dos)
  875.  * - environment variable EXINIT
  876.  * - user exrc file (s:.exrc for Amiga, ~/.exrc otherwise)
  877.  * - second user exrc file ($VIM/.exrc for Dos)
  878.  * The first that exists is used, the rest is ignored.
  879.  */
  880. if (process_env((char_u *)"VIMINIT") == OK)
  881.     vimrc_found();
  882. else
  883. {
  884.     if (do_source((char_u *)USR_VIMRC_FILE, TRUE, TRUE) == FAIL
  885. #ifdef USR_VIMRC_FILE2
  886. && do_source((char_u *)USR_VIMRC_FILE2, TRUE, TRUE) == FAIL
  887. #endif
  888. && process_env((char_u *)"EXINIT") == FAIL
  889. && do_source((char_u *)USR_EXRC_FILE, FALSE, FALSE) == FAIL)
  890.     {
  891. #ifdef USR_EXRC_FILE2
  892. (void)do_source((char_u *)USR_EXRC_FILE2, FALSE, FALSE);
  893. #endif
  894.     }
  895. }
  896. /*
  897.  * Read initialization commands from ".vimrc" or ".exrc" in current
  898.  * directory.  This is only done if the 'exrc' option is set.
  899.  * Because of security reasons we disallow shell and write commands
  900.  * now, except for unix if the file is owned by the user or 'secure'
  901.  * option has been reset in environmet of global ".exrc" or ".vimrc".
  902.  * Only do this if VIMRC_FILE is not the same as USR_VIMRC_FILE or
  903.  * SYS_VIMRC_FILE.
  904.  */
  905. if (p_exrc)
  906. {
  907. #ifdef UNIX
  908.     {
  909. struct stat s;
  910. /* if ".vimrc" file is not owned by user, set 'secure' mode */
  911. if (stat(VIMRC_FILE, &s) || s.st_uid != getuid())
  912.     secure = p_secure;
  913.     }
  914. #else
  915.     secure = p_secure;
  916. #endif
  917.     i = FAIL;
  918.     if (fullpathcmp((char_u *)USR_VIMRC_FILE,
  919.       (char_u *)VIMRC_FILE, FALSE) != FPC_SAME
  920. #ifdef USR_VIMRC_FILE2
  921.     && fullpathcmp((char_u *)USR_VIMRC_FILE2,
  922.       (char_u *)VIMRC_FILE, FALSE) != FPC_SAME
  923. #endif
  924. #ifdef SYS_VIMRC_FILE
  925.     && fullpathcmp((char_u *)SYS_VIMRC_FILE,
  926.       (char_u *)VIMRC_FILE, FALSE) != FPC_SAME
  927. #endif
  928. )
  929. i = do_source((char_u *)VIMRC_FILE, TRUE, TRUE);
  930.     if (i == FAIL)
  931.     {
  932. #ifdef UNIX
  933. struct stat s;
  934. /* if ".exrc" is not owned by user set 'secure' mode */
  935. if (stat(EXRC_FILE, &s) || s.st_uid != getuid())
  936.     secure = p_secure;
  937. else
  938.     secure = 0;
  939. #endif
  940. if (    fullpathcmp((char_u *)USR_EXRC_FILE,
  941.       (char_u *)EXRC_FILE, FALSE) != FPC_SAME
  942. #ifdef USR_EXRC_FILE2
  943. && fullpathcmp((char_u *)USR_EXRC_FILE2,
  944.       (char_u *)EXRC_FILE, FALSE) != FPC_SAME
  945. #endif
  946. )
  947.     (void)do_source((char_u *)EXRC_FILE, FALSE, FALSE);
  948.     }
  949. }
  950. if (secure == 2)
  951.     need_wait_return = TRUE;
  952. secure = 0;
  953.     }
  954.     /*
  955.      * Recovery mode without a file name: List swap files.
  956.      * This uses the 'dir' option, therefore it must be after the
  957.      * initializations.
  958.      */
  959.     if (recoverymode && fname == NULL)
  960.     {
  961. recover_names(NULL, TRUE, 0);
  962. mch_windexit(0);
  963.     }
  964.     /*
  965.      * Set a few option defaults after reading .vimrc files:
  966.      * 'title' and 'icon', Unix: 'shellpipe' and 'shellredir'.
  967.      */
  968.     set_init_3();
  969.     /*
  970.      * "-n" argument: Disable swap file by setting 'updatecount' to 0.
  971.      * Note that this overrides anything from a vimrc file.
  972.      */
  973.     if (no_swap_file)
  974. p_uc = 0;
  975. #ifdef FKMAP
  976.     if (curwin->w_p_rl && p_altkeymap)
  977.     {
  978. p_hkmap = FALSE; /* Reset the Hebrew keymap mode */
  979. p_fkmap = TRUE; /* Set the Farsi keymap mode */
  980.     }
  981. #endif
  982.     if (bin_mode)     /* "-b" argument used */
  983.     {
  984. set_options_bin(curbuf->b_p_bin, 1);
  985. curbuf->b_p_bin = 1;     /* binary file I/O */
  986.     }
  987. #ifdef USE_GUI
  988.     if (gui.starting)
  989. gui_start(); /* will set full_screen to TRUE */
  990. #endif
  991. #ifdef VIMINFO
  992.     /*
  993.      * Read in registers, history etc, but not marks, from the viminfo file
  994.      */
  995.     if (*p_viminfo != NUL)
  996. read_viminfo(NULL, TRUE, FALSE, FALSE);
  997. #endif /* VIMINFO */
  998. #ifdef SPAWNO /* special MSDOS swapping library */
  999.     init_SPAWNO("", SWAP_ANY);
  1000. #endif
  1001. #ifdef QUICKFIX
  1002.     /*
  1003.      * "-q errorfile": Load the error file now.
  1004.      * If the error file can't be read, exit before doing anything else.
  1005.      */
  1006.     if (edit_type == EDIT_QF)
  1007.     {
  1008. if (use_ef != NULL)
  1009.     set_string_option_direct((char_u *)"ef", -1, use_ef, TRUE);
  1010. if (qf_init(p_ef, p_efm) < 0)
  1011. {
  1012.     out_char('n');
  1013.     mch_windexit(3);
  1014. }
  1015.     }
  1016. #endif
  1017.     /*
  1018.      * Don't set the file name if there was a command in .vimrc that already
  1019.      * loaded the file
  1020.      */
  1021.     if (curbuf->b_ffname == NULL)
  1022.     {
  1023. (void)setfname(fname, NULL, TRUE);  /* includes maketitle() */
  1024. ++arg_idx;     /* used first argument name */
  1025.     }
  1026.     if (window_count == 0)
  1027. window_count = arg_file_count;
  1028.     if (window_count > 1)
  1029.     {
  1030. /* Don't change the windows if there was a command in .vimrc that
  1031.  * already split some windows */
  1032. if (firstwin->w_next == NULL)
  1033.     window_count = make_windows(window_count);
  1034. else
  1035.     window_count = win_count();
  1036.     }
  1037.     else
  1038. window_count = 1;
  1039.     /*
  1040.      * Start putting things on the screen.
  1041.      * Scroll screen down before drawing over it
  1042.      * Clear screen now, so file message will not be cleared.
  1043.      */
  1044.     starting = FALSE;
  1045.     no_wait_return = FALSE;
  1046.     msg_scroll = FALSE;
  1047. #ifdef USE_GUI
  1048.     /*
  1049.      * This seems to be required to make callbacks to be called now, instead
  1050.      * of after things have been put on the screen, which then may be deleted
  1051.      * when getting a resize callback.
  1052.      */
  1053.     if (gui.in_use)
  1054. gui_wait_for_chars(50L);
  1055. #endif
  1056.     /*
  1057.      * When done something that is not allowed or error message call
  1058.      * wait_return.  This must be done before starttermcap(), because it may
  1059.      * switch to another screen. It must be done after settmode(TMODE_RAW),
  1060.      * because we want to react on a single key stroke.
  1061.      * Call settmode and starttermcap here, so the T_KS and T_TI may be
  1062.      * defined by termcapinit and redifined in .exrc.
  1063.      */
  1064.     settmode(TMODE_RAW);
  1065.     if (need_wait_return || msg_didany)
  1066. wait_return(TRUE);
  1067.     starttermcap();     /* start termcap if not done by wait_return() */
  1068. #ifdef USE_MOUSE
  1069.     setmouse(); /* may start using the mouse */
  1070. #endif
  1071.     if (scroll_region)
  1072. scroll_region_reset(); /* In case Rows changed */
  1073.     scroll_start();
  1074.     /*
  1075.      * Don't clear the screen when starting in Ex mode, unless using the GUI.
  1076.      */
  1077.     if (exmode_active
  1078. #ifdef USE_GUI
  1079. && !gui.in_use
  1080. #endif
  1081. )
  1082. must_redraw = CLEAR;
  1083.     else
  1084. screenclear(); /* clear screen */
  1085.     no_wait_return = TRUE;
  1086.     if (recoverymode) /* do recover */
  1087.     {
  1088. msg_scroll = TRUE; /* scroll message up */
  1089. ml_recover();
  1090. msg_scroll = FALSE;
  1091. if (curbuf->b_ml.ml_mfp == NULL) /* failed */
  1092.     getout(1);
  1093. do_modelines(); /* do modelines */
  1094.     }
  1095.     else
  1096.     {
  1097. /*
  1098.  * If "-" argument given: read file from stdin.
  1099.  * Need to stop Raw mode for terminal in case stdin and stderr are the
  1100.  * same terminal: "cat | vim -".
  1101.  */
  1102. if (edit_type == EDIT_STDIN)
  1103. {
  1104.     stoptermcap();
  1105.     settmode(TMODE_COOK); /* set to normal mode */
  1106.     (void)open_buffer(TRUE); /* create memfile and read file */
  1107.     if (!termcap_active) /* if readfile() didn't do it already */
  1108.     {
  1109. settmode(TMODE_RAW); /* set to raw mode */
  1110. starttermcap();
  1111.     }
  1112. }
  1113. /*
  1114.  * Open a buffer for windows that don't have one yet.
  1115.  * Commands in the .vimrc might have loaded a file or split the window.
  1116.  * Watch out for autocommands that delete a window.
  1117.  */
  1118. #ifdef AUTOCMD
  1119. /*
  1120.  * Don't execute Win/Buf Enter/Leave autocommands here
  1121.  */
  1122. ++autocmd_no_enter;
  1123. ++autocmd_no_leave;
  1124. #endif
  1125. for (curwin = firstwin; curwin != NULL; curwin = curwin->w_next)
  1126. {
  1127.     curbuf = curwin->w_buffer;
  1128.     if (curbuf->b_ml.ml_mfp == NULL)
  1129.     {
  1130. (void)open_buffer(FALSE);   /* create memfile and read file */
  1131. #ifdef AUTOCMD
  1132. curwin = firstwin;     /* start again */
  1133. #endif
  1134.     }
  1135.     ui_breakcheck();
  1136.     if (got_int)
  1137.     {
  1138. (void)vgetc(); /* only break the file loading, not the rest */
  1139. break;
  1140.     }
  1141. }
  1142. #ifdef AUTOCMD
  1143. --autocmd_no_enter;
  1144. --autocmd_no_leave;
  1145. #endif
  1146. curwin = firstwin;
  1147. curbuf = curwin->w_buffer;
  1148.     }
  1149.     /* Ex starts at last line of the file */
  1150.     if (exmode_active)
  1151. curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
  1152. #ifdef AUTOCMD
  1153.     apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
  1154. #endif
  1155.     setpcmark();
  1156. #ifdef QUICKFIX
  1157.     /*
  1158.      * When started with "-q errorfile" jump to first error now.
  1159.      */
  1160.     if (edit_type == EDIT_QF)
  1161. qf_jump(0, 0, FALSE);
  1162. #endif
  1163.     /*
  1164.      * If opened more than one window, start editing files in the other
  1165.      * windows.  Make_windows() has already opened the windows.
  1166.      */
  1167. #ifdef AUTOCMD
  1168.     /*
  1169.      * Don't execute Win/Buf Enter/Leave autocommands here
  1170.      */
  1171.     ++autocmd_no_enter;
  1172.     ++autocmd_no_leave;
  1173. #endif
  1174.     for (i = 1; i < window_count; ++i)
  1175.     {
  1176. if (curwin->w_next == NULL)     /* just checking */
  1177.     break;
  1178. win_enter(curwin->w_next, FALSE);
  1179. /* Only open the file if there is no file in this window yet (that can
  1180.  * happen when .vimrc contains ":sall") */
  1181. if (curbuf == firstwin->w_buffer || curbuf->b_ffname == NULL)
  1182. {
  1183.     curwin->w_arg_idx = arg_idx;
  1184.     /* edit file from arg list, if there is one */
  1185.     (void)do_ecmd(0,
  1186.  arg_idx < arg_file_count ? arg_files[arg_idx] : NULL,
  1187.   NULL, NULL, (linenr_t)0, ECMD_HIDE);
  1188.     if (arg_idx == arg_file_count - 1)
  1189. arg_had_last = TRUE;
  1190.     ++arg_idx;
  1191. }
  1192. ui_breakcheck();
  1193. if (got_int)
  1194. {
  1195.     (void)vgetc(); /* only break the file loading, not the rest */
  1196.     break;
  1197. }
  1198.     }
  1199. #ifdef AUTOCMD
  1200.     --autocmd_no_enter;
  1201. #endif
  1202.     win_enter(firstwin, FALSE);     /* back to first window */
  1203. #ifdef AUTOCMD
  1204.     --autocmd_no_leave;
  1205. #endif
  1206.     if (window_count > 1)
  1207. win_equal(curwin, FALSE);     /* adjust heights */
  1208.     /*
  1209.      * If there are more file names in the argument list than windows,
  1210.      * put the rest of the names in the buffer list.
  1211.      */
  1212.     while (arg_idx < arg_file_count)
  1213. (void)buflist_add(arg_files[arg_idx++]);
  1214.     /*
  1215.      * Now shorten any of the filenames if possible
  1216.      */
  1217.     shorten_fnames();
  1218.     /*
  1219.      * Need to jump to the tag before executing the '-c command'.
  1220.      * Makes "vim -c '/return' -t main" work.
  1221.      */
  1222.     if (tagname)
  1223.     {
  1224. STRCPY(IObuff, "ta ");
  1225. STRCAT(IObuff, tagname);
  1226. do_cmdline(IObuff, NULL, NULL, DOCMD_NOWAIT|DOCMD_VERBOSE);
  1227.     }
  1228.     if (n_commands > 0)
  1229.     {
  1230. /*
  1231.  * We start commands on line 0, make "vim +/pat file" match a
  1232.  * pattern on line 1.
  1233.  */
  1234. curwin->w_cursor.lnum = 0;
  1235. sourcing_name = (char_u *)"command line";
  1236. for (i = 0; i < n_commands; ++i)
  1237.     do_cmdline(commands[i], NULL, NULL, DOCMD_NOWAIT|DOCMD_VERBOSE);
  1238. sourcing_name = NULL;
  1239. if (curwin->w_cursor.lnum == 0)
  1240.     curwin->w_cursor.lnum = 1;
  1241. #ifdef QUICKFIX
  1242. /* When started with "-q errorfile" jump to first again. */
  1243. if (edit_type == EDIT_QF)
  1244.     qf_jump(0, 0, FALSE);
  1245. #endif
  1246.     }
  1247.     RedrawingDisabled = FALSE;
  1248.     redraw_later(NOT_VALID);
  1249.     no_wait_return = FALSE;
  1250.     /* start in insert mode */
  1251.     if (p_im)
  1252. need_start_insertmode = TRUE;
  1253. #ifdef AUTOCMD
  1254.     apply_autocmds(EVENT_VIMENTER, NULL, NULL, FALSE, curbuf);
  1255. #endif
  1256. #if defined(WIN32) && !defined(USE_GUI_WIN32)
  1257.     mch_set_winsize_now();     /* Allow winsize changes from now on */
  1258. #endif
  1259.     /*
  1260.      * main command loop
  1261.      */
  1262.     clear_oparg(&oa);
  1263.     for (;;)
  1264.     {
  1265. if (stuff_empty())
  1266. {
  1267.     if (need_check_timestamps)
  1268. check_timestamps();
  1269.     if (need_wait_return) /* if wait_return still needed ... */
  1270. wait_return(FALSE); /* ... call it now */
  1271.     if (need_start_insertmode && goto_im())
  1272.     {
  1273. need_start_insertmode = FALSE;
  1274. stuffReadbuff((char_u *)"i"); /* start insert mode next */
  1275. /* skip the fileinfo message now, because it would be shown
  1276.  * after insert mode finishes! */
  1277. need_fileinfo = FALSE;
  1278.     }
  1279. }
  1280. dont_wait_return = FALSE;
  1281. if (got_int && !global_busy)
  1282. {
  1283.     (void)vgetc(); /* flush all buffers */
  1284.     got_int = FALSE;
  1285. }
  1286. msg_scroll = FALSE;
  1287. quit_more = FALSE;
  1288. /*
  1289.  * If skip redraw is set (for ":" in wait_return()), don't redraw now.
  1290.  * If there is nothing in the stuff_buffer or do_redraw is TRUE,
  1291.  * update cursor and redraw.
  1292.  */
  1293. if (skip_redraw || exmode_active)
  1294.     skip_redraw = FALSE;
  1295. else if (do_redraw || stuff_empty())
  1296. {
  1297.     /*
  1298.      * Before redrawing, make sure w_topline is correct, and w_leftcol
  1299.      * if lines don't wrap, and w_skipcol if lines wrap.
  1300.      */
  1301.     update_topline();
  1302.     validate_cursor();
  1303.     if (VIsual_active)
  1304. update_curbuf(INVERTED);/* update inverted part */
  1305.     else if (must_redraw)
  1306. update_screen(must_redraw);
  1307.     else if (redraw_cmdline || clear_cmdline)
  1308. showmode();
  1309.     redraw_statuslines();
  1310.     /* display message after redraw */
  1311.     if (keep_msg != NULL)
  1312. msg_attr(keep_msg, keep_msg_attr);
  1313.     if (need_fileinfo) /* show file info after redraw */
  1314.     {
  1315. fileinfo(FALSE, TRUE, FALSE);
  1316. need_fileinfo = FALSE;
  1317.     }
  1318.     emsg_on_display = FALSE; /* can delete error message now */
  1319.     msg_didany = FALSE; /* reset lines_left in msg_start() */
  1320.     do_redraw = FALSE;
  1321.     showruler(FALSE);
  1322.     setcursor();
  1323.     cursor_on();
  1324. }
  1325. #ifdef USE_GUI
  1326. if (need_mouse_correct)
  1327.     gui_mouse_correct();
  1328. #endif
  1329. /*
  1330.  * Update w_curswant if w_set_curswant has been set.
  1331.  * Postponed until here to avoid computing w_virtcol too often.
  1332.  */
  1333. update_curswant();
  1334. /*
  1335.  * If we're invoked as ex, do a round of ex commands.
  1336.  * Otherwise, get and execute a normal mode command.
  1337.  */
  1338. if (exmode_active)
  1339.     do_exmode();
  1340. else
  1341.     normal_cmd(&oa, TRUE);
  1342.     }
  1343.     /*NOTREACHED*/
  1344. #if !defined(MSDOS) || defined(DJGPP)
  1345.     return 0; /* Borland C++ gives a "not reached" error message here */
  1346. #endif
  1347. }
  1348. #endif /* PROTO */
  1349. /*
  1350.  * Get a (optional) count for a Vim argument.
  1351.  */
  1352.     static int
  1353. get_number_arg(p, idx, def)
  1354.     char_u *p;     /* pointer to argument */
  1355.     int *idx;     /* index in argument, is incremented */
  1356.     int def;     /* default value */
  1357. {
  1358.     if (isdigit(p[*idx]))
  1359.     {
  1360. def = atoi((char *)&(p[*idx]));
  1361. while (isdigit(p[*idx]))
  1362.     *idx = *idx + 1;
  1363.     }
  1364.     return def;
  1365. }
  1366. /*
  1367.  * Get an evironment variable, and execute it as Ex commands.
  1368.  * Returns FAIL if the environment variable was not executed, OK otherwise.
  1369.  */
  1370.     int
  1371. process_env(env)
  1372.     char_u *env;
  1373. {
  1374.     char_u *initstr;
  1375.     char_u *save_sourcing_name;
  1376.     if ((initstr = mch_getenv(env)) != NULL && *initstr != NUL)
  1377.     {
  1378. save_sourcing_name = sourcing_name;
  1379. sourcing_name = env;
  1380. do_cmdline(initstr, NULL, NULL, DOCMD_NOWAIT|DOCMD_VERBOSE);
  1381. sourcing_name = save_sourcing_name;
  1382. return OK;
  1383.     }
  1384.     return FAIL;
  1385. }
  1386.     void
  1387. getout(r)
  1388.     int     r;
  1389. {
  1390.     exiting = TRUE;
  1391.     /* Position the cursor on the last screen line, below all the text */
  1392. #ifdef USE_GUI
  1393.     if (!gui.in_use)
  1394. #endif
  1395. windgoto((int)Rows - 1, 0);
  1396. #ifdef AUTOCMD
  1397.     apply_autocmds(EVENT_VIMLEAVEPRE, NULL, NULL, FALSE, curbuf);
  1398. #endif
  1399. #ifdef VIMINFO
  1400.     if (*p_viminfo != NUL)
  1401.     {
  1402. /* Write out the registers, history, marks etc, to the viminfo file */
  1403. msg_didany = FALSE;
  1404. write_viminfo(NULL, FALSE);
  1405. if (msg_didany) /* make the user read the error message */
  1406. {
  1407.     no_wait_return = FALSE;
  1408.     wait_return(FALSE);
  1409. }
  1410.     }
  1411. #endif /* VIMINFO */
  1412. #ifdef AUTOCMD
  1413.     apply_autocmds(EVENT_VIMLEAVE, NULL, NULL, FALSE, curbuf);
  1414.     /* Position the cursor again, the autocommands may have moved it */
  1415. # ifdef USE_GUI
  1416.     if (!gui.in_use)
  1417. # endif
  1418. windgoto((int)Rows - 1, 0);
  1419. #endif
  1420. #ifdef HAVE_PERL_INTERP
  1421.     perl_end();
  1422. #endif
  1423.     mch_windexit(r);
  1424. }
  1425. /*
  1426.  * When FKMAP is defined, also compile the Farsi source code.
  1427.  */
  1428. #if defined(FKMAP) || defined(PROTO)
  1429. # include "farsi.c"
  1430. #endif