home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / unix / vim-6.2.tar.bz2 / vim-6.2.tar / vim62 / src / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  2003-05-29  |  79.0 KB  |  3,079 lines

  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.  * See README.txt for an overview of the Vim source code.
  8.  */
  9.  
  10. #if defined(MSDOS) || defined(WIN32) || defined(_WIN64)
  11. # include <io.h>        /* for close() and dup() */
  12. #endif
  13.  
  14. #define EXTERN
  15. #include "vim.h"
  16.  
  17. #ifdef SPAWNO
  18. # include <spawno.h>        /* special MSDOS swapping library */
  19. #endif
  20.  
  21. #ifdef HAVE_FCNTL_H
  22. # include <fcntl.h>
  23. #endif
  24.  
  25. #ifdef __CYGWIN__
  26. # ifndef WIN32
  27. #  include <sys/cygwin.h>    /* for cygwin_conv_to_posix_path() */
  28. # endif
  29. # include <limits.h>
  30. #endif
  31.  
  32. #if defined(UNIX) || defined(VMS)
  33. static int file_owned __ARGS((char *fname));
  34. #endif
  35. static void mainerr __ARGS((int, char_u *));
  36. static void main_msg __ARGS((char *s));
  37. static void usage __ARGS((void));
  38. static int get_number_arg __ARGS((char_u *p, int *idx, int def));
  39. static void main_start_gui __ARGS((void));
  40. #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
  41. static void check_swap_exists_action __ARGS((void));
  42. #endif
  43. #ifdef FEAT_CLIENTSERVER
  44. static void cmdsrv_main __ARGS((int *argc, char **argv, char_u *serverName_arg, char_u **serverStr));
  45. static char_u *serverMakeName __ARGS((char_u *arg, char *cmd));
  46. #endif
  47.  
  48.  
  49. #ifdef STARTUPTIME
  50. static FILE *time_fd = NULL;
  51. #endif
  52.  
  53. #define FEAT_PRECOMMANDS
  54.  
  55. /*
  56.  * Different types of error messages.
  57.  */
  58. static char *(main_errors[]) =
  59. {
  60.     N_("Unknown option"),
  61. #define ME_UNKNOWN_OPTION    0
  62.     N_("Too many edit arguments"),
  63. #define ME_TOO_MANY_ARGS    1
  64.     N_("Argument missing after"),
  65. #define ME_ARG_MISSING        2
  66.     N_("Garbage after option"),
  67. #define ME_GARBAGE        3
  68.     N_("Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"),
  69. #define ME_EXTRA_CMD        4
  70.     N_("Invalid argument for"),
  71. #define ME_INVALID_ARG        5
  72. };
  73.  
  74. /* Maximum number of commands from + or -c options */
  75. #define MAX_ARG_CMDS 10
  76.  
  77. #ifndef PROTO        /* don't want a prototype for main() */
  78.     int
  79. # ifdef VIMDLL
  80. _export
  81. # endif
  82. # ifdef FEAT_GUI_MSWIN
  83. #  ifdef __BORLANDC__
  84. _cdecl
  85. #  endif
  86. VimMain
  87. # else
  88. main
  89. # endif
  90. (argc, argv)
  91.     int        argc;
  92.     char    **argv;
  93. {
  94.     char_u    *initstr;        /* init string from environment */
  95.     char_u    *term = NULL;        /* specified terminal name */
  96.     char_u    *fname = NULL;        /* file name from command line */
  97.     char_u    *tagname = NULL;    /* tag from -t option */
  98.     char_u    *use_vimrc = NULL;    /* vimrc from -u option */
  99. #ifdef FEAT_QUICKFIX
  100.     char_u    *use_ef = NULL;        /* 'errorfile' from -q option */
  101. #endif
  102. #ifdef FEAT_CRYPT
  103.     int        ask_for_key = FALSE;    /* -x argument */
  104. #endif
  105.     int        n_commands = 0;        /* no. of commands from + or -c */
  106.     char_u    *commands[MAX_ARG_CMDS]; /* commands from + or -c option */
  107. #ifdef FEAT_PRECOMMANDS
  108.     int        p_commands = 0;        /* no. of commands from --cmd */
  109.     char_u    *pre_commands[MAX_ARG_CMDS]; /* commands from --cmd option */
  110. #endif
  111.     int        no_swap_file = FALSE;   /* "-n" option used */
  112.     int        c;
  113.     int        i;
  114.     char_u    *p = NULL;
  115.     int        bin_mode = FALSE;    /* -b option used */
  116. #ifdef FEAT_WINDOWS
  117.     int        window_count = -1;    /* number of windows to use */
  118.     int        arg_idx;        /* index in argument list */
  119.     int        vert_windows = MAYBE;   /* "-O" used instead of "-o" */
  120. #endif
  121.     int        had_minmin = FALSE;    /* found "--" option */
  122.     int        argv_idx;        /* index in argv[n][] */
  123.     int        want_full_screen = TRUE;
  124.     int        want_argument;        /* option with argument */
  125. #define EDIT_NONE   0        /* no edit type yet */
  126. #define EDIT_FILE   1        /* file name argument[s] given, use argument list */
  127. #define EDIT_STDIN  2        /* read file from stdin */
  128. #define EDIT_TAG    3        /* tag name argument given, use tagname */
  129. #define EDIT_QF        4        /* start in quickfix mode */
  130.     int        edit_type = EDIT_NONE;  /* type of editing to do */
  131. #ifdef FEAT_DIFF
  132.     int        diff_mode = FALSE;    /* start with 'diff' set */
  133. #endif
  134.     int        evim_mode = FALSE;    /* started as "evim" */
  135.     int        stdout_isatty;        /* is stdout a terminal? */
  136.     int        input_isatty;        /* is active input a terminal? */
  137. #ifdef MSWIN
  138.     int        full_path = FALSE;
  139. #endif
  140. #ifdef FEAT_CLIENTSERVER
  141.     char_u    *serverStr = NULL;
  142.     char_u    *serverName_arg = NULL;    /* cmdline arg for server name */
  143.     int        serverArg = FALSE;    /* TRUE when argument for a server */
  144.     char_u    *servername = NULL;    /* allocated name for our server */
  145. #endif
  146. #if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
  147.     int        literal = FALSE;    /* don't expand file names */
  148. #endif
  149.  
  150. # ifdef NBDEBUG
  151.     nbdebug_wait(WT_ENV | WT_WAIT | WT_STOP, "SPRO_GVIM_WAIT", 20);
  152.     nbdebug_log_init("SPRO_GVIM_DEBUG", "SPRO_GVIM_DLEVEL");
  153. # endif
  154.  
  155.     /*
  156.      * Do any system-specific initialisations.  These can NOT use IObuff or
  157.      * NameBuff.  Thus emsg2() cannot be called!
  158.      */
  159.     mch_early_init();
  160.  
  161. #ifdef FEAT_TCL
  162.     vim_tcl_init(argv[0]);
  163. #endif
  164.  
  165. #ifdef MEM_PROFILE
  166.     atexit(vim_mem_profile_dump);
  167. #endif
  168.  
  169. #ifdef STARTUPTIME
  170.     time_fd = fopen(STARTUPTIME, "a");
  171.     TIME_MSG("--- VIM STARTING ---");
  172. #endif
  173.  
  174. #ifdef __EMX__
  175.     _wildcard(&argc, &argv);
  176. #endif
  177.  
  178. #ifdef FEAT_MBYTE
  179.     (void)mb_init();    /* init mb_bytelen_tab[] to ones */
  180. #endif
  181.  
  182. #ifdef __QNXNTO__
  183.     qnx_init();        /* PhAttach() for clipboard, (and gui) */
  184. #endif
  185.  
  186. #ifdef MAC_OS_CLASSIC
  187.     /* Macintosh needs this before any memory is allocated. */
  188.     gui_prepare(&argc, argv);    /* Prepare for possibly starting GUI sometime */
  189.     TIME_MSG("GUI prepared");
  190. #endif
  191.  
  192.     /* Init the table of Normal mode commands. */
  193.     init_normal_cmds();
  194.  
  195. #if defined(HAVE_DATE_TIME) && defined(VMS) && defined(VAXC)
  196.     make_version();
  197. #endif
  198.  
  199.     /*
  200.      * Allocate space for the generic buffers (needed for set_init_1() and
  201.      * EMSG2()).
  202.      */
  203.     if ((IObuff = alloc(IOSIZE)) == NULL
  204.         || (NameBuff = alloc(MAXPATHL)) == NULL)
  205.     mch_exit(0);
  206.  
  207.     TIME_MSG("Allocated generic buffers");
  208.  
  209. #if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
  210.     /*
  211.      * Setup to use the current locale (for ctype() and many other things).
  212.      * NOTE: Translated messages with encodings other than latin1 will not
  213.      * work until set_init_1() has been called!
  214.      */
  215.     setlocale(LC_ALL, "");
  216.  
  217. # ifdef FEAT_GETTEXT
  218.     {
  219.     int    mustfree = FALSE;
  220.  
  221. #ifdef DYNAMIC_GETTEXT
  222.     /* Initialize the gettext library */
  223.     dyn_libintl_init(NULL);
  224. #endif
  225.     /* expand_env() doesn't work yet, because chartab[] is not initialized
  226.      * yet, call vim_getenv() directly */
  227.     p = vim_getenv((char_u *)"VIMRUNTIME", &mustfree);
  228.     if (p != NULL && *p != NUL)
  229.     {
  230.         STRCPY(NameBuff, p);
  231.         STRCAT(NameBuff, "/lang");
  232.         bindtextdomain(VIMPACKAGE, (char *)NameBuff);
  233.     }
  234.     if (mustfree)
  235.         vim_free(p);
  236.     textdomain(VIMPACKAGE);
  237.     }
  238. # endif
  239.     TIME_MSG("locale set");
  240. #endif
  241.  
  242. #ifdef FEAT_GUI
  243.     gui.dofork = TRUE;            /* default is to use fork() */
  244. #endif
  245.  
  246. #if defined(FEAT_XCLIPBOARD) || defined(FEAT_CLIENTSERVER)
  247.     /*
  248.      * Get the name of the display, before gui_prepare() removes it from
  249.      * argv[].  Used for the xterm-clipboard display.
  250.      *
  251.      * Also find the --server... arguments
  252.      */
  253.     for (i = 1; i < argc; i++)
  254.     {
  255.     if (STRCMP(argv[i], "--") == 0)
  256.         break;
  257. # ifdef FEAT_XCLIPBOARD
  258.     else if (STRICMP(argv[i], "-display") == 0
  259. #  ifdef FEAT_GUI_GTK
  260.         || STRICMP(argv[i], "--display") == 0
  261. #  endif
  262.         )
  263.     {
  264.         if (i == argc - 1)
  265.         mainerr_arg_missing((char_u *)argv[i]);
  266.         xterm_display = argv[++i];
  267.     }
  268. # endif
  269. # ifdef FEAT_CLIENTSERVER
  270.     else if (STRICMP(argv[i], "--servername") == 0)
  271.     {
  272.         if (i == argc - 1)
  273.         mainerr_arg_missing((char_u *)argv[i]);
  274.         serverName_arg = (char_u *)argv[++i];
  275.     }
  276.     else if (STRICMP(argv[i], "--serverlist") == 0
  277.          || STRICMP(argv[i], "--remote-send") == 0
  278.          || STRICMP(argv[i], "--remote-expr") == 0
  279.          || STRICMP(argv[i], "--remote") == 0
  280.          || STRICMP(argv[i], "--remote-silent") == 0)
  281.         serverArg = TRUE;
  282.     else if (STRICMP(argv[i], "--remote-wait") == 0
  283.         || STRICMP(argv[i], "--remote-wait-silent") == 0)
  284.     {
  285.         serverArg = TRUE;
  286. #ifdef FEAT_GUI
  287.         /* don't fork() when starting the GUI to edit the files ourself */
  288.         gui.dofork = FALSE;
  289. #endif
  290.     }
  291. # endif
  292. # ifdef FEAT_GUI_GTK
  293.     else if (STRICMP(argv[i], "--socketid") == 0)
  294.     {
  295.         unsigned int    socket_id;
  296.         int            count;
  297.  
  298.         if (i == argc - 1)
  299.         mainerr_arg_missing((char_u *)argv[i]);
  300.         if (STRNICMP(argv[i+1], "0x", 2) == 0)
  301.         count = sscanf(&(argv[i + 1][2]), "%x", &socket_id);
  302.         else
  303.         count = sscanf(argv[i+1], "%u", &socket_id);
  304.         if (count != 1)
  305.         mainerr(ME_INVALID_ARG, (char_u *)argv[i]);
  306.         else
  307.         gtk_socket_id = socket_id;
  308.         i++;
  309.     }
  310.     else if (STRICMP(argv[i], "--echo-wid") == 0)
  311.         echo_wid_arg = TRUE;
  312. # endif
  313.     }
  314. #endif
  315.  
  316. #ifdef FEAT_SUN_WORKSHOP
  317.     findYourself(argv[0]);
  318. #endif
  319. #ifdef FEAT_NETBEANS_INTG
  320.     netbeans_setRunDir(argv[0]);
  321. #endif
  322. #if defined(FEAT_GUI) && !defined(MAC_OS_CLASSIC)
  323.     gui_prepare(&argc, argv);    /* Prepare for possibly starting GUI sometime */
  324.     TIME_MSG("GUI prepared");
  325. #endif
  326.  
  327. #ifdef FEAT_CLIPBOARD
  328.     clip_init(FALSE);        /* Initialise clipboard stuff */
  329.     TIME_MSG("clipboard setup");
  330. #endif
  331.  
  332.     /*
  333.      * Check if we have an interactive window.
  334.      * On the Amiga: If there is no window, we open one with a newcli command
  335.      * (needed for :! to * work). mch_check_win() will also handle the -d or
  336.      * -dev argument.
  337.      */
  338.     stdout_isatty = (mch_check_win(argc, argv) != FAIL);
  339.     TIME_MSG("window checked");
  340.  
  341.     /*
  342.      * Allocate the first window and buffer. Can't do much without it.
  343.      */
  344.     win_alloc_first();
  345.  
  346.     init_yank();        /* init yank buffers */
  347.  
  348.     /* Init the argument list to empty. */
  349.     alist_init(&global_alist);
  350.  
  351.     /*
  352.      * Set the default values for the options.
  353.      * NOTE: Non-latin1 translated messages are working only after this,
  354.      * because this is where "has_mbyte" will be set, which is used by
  355.      * msg_outtrans_len_attr().
  356.      * First find out the home directory, needed to expand "~" in options.
  357.      */
  358.     init_homedir();        /* find real value of $HOME */
  359.     set_init_1();
  360.     TIME_MSG("inits 1");
  361.  
  362. #ifdef FEAT_EVAL
  363.     set_lang_var();        /* set v:lang and v:ctype */
  364. #endif
  365.  
  366. #ifdef FEAT_CLIENTSERVER
  367.     /*
  368.      * Do the client-server stuff, unless "--servername ''" was used.
  369.      */
  370.     if (serverName_arg == NULL || *serverName_arg != NUL)
  371.     {
  372. # ifdef WIN32
  373.     /* Initialise the client/server messaging infrastructure. */
  374.     serverInitMessaging();
  375. # endif
  376.  
  377.     /*
  378.      * When a command server argument was found, execute it.  This may
  379.      * exit Vim when it was successful.
  380.      */
  381.     if (serverArg)
  382.         cmdsrv_main(&argc, argv, serverName_arg, &serverStr);
  383.  
  384.     /* If we're still running, get the name to register ourselves.
  385.      * On Win32 can register right now, for X11 need to setup the
  386.      * clipboard first, it's further down. */
  387.     servername = serverMakeName(serverName_arg, argv[0]);
  388. # ifdef WIN32
  389.     if (servername != NULL)
  390.     {
  391.         serverSetName(servername);
  392.         vim_free(servername);
  393.     }
  394. # endif
  395.     }
  396. #endif
  397.  
  398.     /*
  399.      * Check for: [r][e][g][vi|vim|view][diff][ex[im]]
  400.      * If the executable name starts with "r" we disable shell commands.
  401.      * If the next character is "e" we run in Easy mode.
  402.      * If the next character is "g" we run the GUI version.
  403.      * If the next characters are "view" we start in readonly mode.
  404.      * If the next characters are "diff" or "vimdiff" we start in diff mode.
  405.      * If the next characters are "ex" we start in Ex mode.  If it's followed
  406.      * by "im" use improved Ex mode.
  407.      */
  408.     initstr = gettail((char_u *)argv[0]);
  409.  
  410. #ifdef MACOS_X_UNIX
  411.     /* An issue has been seen when launching Vim in such a way that
  412.      * $PWD/$ARGV[0] or $ARGV[0] is not the absolute path to the
  413.      * executable or a symbolic link of it. Until this issue is resolved
  414.      * we prohibit the GUI from being used.
  415.      */
  416.     if (STRCMP(initstr, argv[0]) == 0)
  417.     disallow_gui = TRUE;
  418. #endif
  419.  
  420. #ifdef FEAT_EVAL
  421.     set_vim_var_string(VV_PROGNAME, initstr, -1);
  422. #endif
  423.  
  424.     /* TODO: On MacOS X default to gui if argv[0] ends in:
  425.      *       /vim.app/Contents/MacOS/Vim */
  426.  
  427.     if (TOLOWER_ASC(initstr[0]) == 'r')
  428.     {
  429.     restricted = TRUE;
  430.     ++initstr;
  431.     }
  432.  
  433.     /* Avoid using evim mode for "editor". */
  434.     if (TOLOWER_ASC(initstr[0]) == 'e'
  435.         && (TOLOWER_ASC(initstr[1]) == 'v'
  436.                        || TOLOWER_ASC(initstr[1]) == 'g'))
  437.     {
  438. #ifdef FEAT_GUI
  439.     gui.starting = TRUE;
  440. #endif
  441.     evim_mode = TRUE;
  442.     ++initstr;
  443.     }
  444.  
  445.     if (TOLOWER_ASC(initstr[0]) == 'g')
  446.     {
  447.     main_start_gui();
  448. #ifdef FEAT_GUI
  449.     ++initstr;
  450. #endif
  451.     }
  452.  
  453.     if (STRNICMP(initstr, "view", 4) == 0)
  454.     {
  455.     readonlymode = TRUE;
  456.     curbuf->b_p_ro = TRUE;
  457.     p_uc = 10000;            /* don't update very often */
  458.     initstr += 4;
  459.     }
  460.     else if (STRNICMP(initstr, "vim", 3) == 0)
  461.     initstr += 3;
  462.  
  463.     /* Catch "[r][g]vimdiff" and "[r][g]viewdiff". */
  464.     if (STRICMP(initstr, "diff") == 0)
  465.     {
  466. #ifdef FEAT_DIFF
  467.     diff_mode = TRUE;
  468. #else
  469.     mch_errmsg(_("This Vim was not compiled with the diff feature."));
  470.     mch_errmsg("\n");
  471.     mch_exit(2);
  472. #endif
  473.     }
  474.  
  475.     if (STRNICMP(initstr, "ex", 2) == 0)
  476.     {
  477.     if (STRNICMP(initstr + 2, "im", 2) == 0)
  478.         exmode_active = EXMODE_VIM;
  479.     else
  480.         exmode_active = EXMODE_NORMAL;
  481.     change_compatible(TRUE);    /* set 'compatible' */
  482.     }
  483.  
  484.     initstr = gettail((char_u *)argv[0]);
  485.     ++argv;
  486.     --argc;
  487.  
  488.     /*
  489.      * Process the command line arguments.
  490.      */
  491.     argv_idx = 1;        /* active option letter is argv[0][argv_idx] */
  492.     while (argc > 0)
  493.     {
  494.     /*
  495.      * "+" or "+{number}" or "+/{pat}" or "+{command}" argument.
  496.      */
  497.     if (argv[0][0] == '+' && !had_minmin)
  498.     {
  499.         if (n_commands >= MAX_ARG_CMDS)
  500.         mainerr(ME_EXTRA_CMD, NULL);
  501.         argv_idx = -1;        /* skip to next argument */
  502.         if (argv[0][1] == NUL)
  503.         commands[n_commands++] = (char_u *)"$";
  504.         else
  505.         commands[n_commands++] = (char_u *)&(argv[0][1]);
  506.     }
  507.  
  508.     /*
  509.      * Optional argument.
  510.      */
  511.     else if (argv[0][0] == '-' && !had_minmin)
  512.     {
  513.         want_argument = FALSE;
  514.         c = argv[0][argv_idx++];
  515. #ifdef VMS
  516.         /*
  517.          * VMS only uses upper case command lines.  Interpret "-X" as "-x"
  518.          * and "-/X" as "-X".
  519.          */
  520.         if (c == '/')
  521.         {
  522.         c = argv[0][argv_idx++];
  523.         c = TOUPPER_ASC(c);
  524.         }
  525.         else
  526.         c = TOLOWER_ASC(c);
  527. #endif
  528.         switch (c)
  529.         {
  530.         case NUL:        /* "vim -"  read from stdin */
  531.                 /* "ex -" silent mode */
  532.         if (exmode_active)
  533.             silent_mode = TRUE;
  534.         else
  535.         {
  536.             if (edit_type != EDIT_NONE)
  537.             mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
  538.             edit_type = EDIT_STDIN;
  539.             read_cmd_fd = 2;    /* read from stderr instead of stdin */
  540.         }
  541.         argv_idx = -1;        /* skip to next argument */
  542.         break;
  543.  
  544.         case '-':        /* "--" don't take any more options */
  545.                 /* "--help" give help message */
  546.                 /* "--version" give version message */
  547.                 /* "--literal" take files literally */
  548.                 /* "--nofork" don't fork */
  549.                 /* "--noplugin[s]" skip plugins */
  550.                 /* "--cmd <cmd>" execute cmd before vimrc */
  551.         if (STRICMP(argv[0] + argv_idx, "help") == 0)
  552.             usage();
  553.         else if (STRICMP(argv[0] + argv_idx, "version") == 0)
  554.         {
  555.             Columns = 80;    /* need to init Columns */
  556.             info_message = TRUE; /* use mch_msg(), not mch_errmsg() */
  557.             list_version();
  558.             msg_putchar('\n');
  559.             msg_didout = FALSE;
  560.             mch_exit(0);
  561.         }
  562.         else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0)
  563.         {
  564. #if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
  565.             literal = TRUE;
  566. #endif
  567.         }
  568.         else if (STRNICMP(argv[0] + argv_idx, "nofork", 6) == 0)
  569.         {
  570. #ifdef FEAT_GUI
  571.             gui.dofork = FALSE;    /* don't fork() when starting GUI */
  572. #endif
  573.         }
  574.         else if (STRNICMP(argv[0] + argv_idx, "noplugin", 8) == 0)
  575.             p_lpl = FALSE;
  576. #ifdef FEAT_PRECOMMANDS
  577.         else if (STRNICMP(argv[0] + argv_idx, "cmd", 3) == 0)
  578.         {
  579.             want_argument = TRUE;
  580.             argv_idx += 3;
  581.         }
  582. #endif
  583. #ifdef FEAT_CLIENTSERVER
  584.         else if (STRNICMP(argv[0] + argv_idx, "serverlist", 10) == 0)
  585.             ; /* already processed -- no arg */
  586.         else if (STRNICMP(argv[0] + argv_idx, "servername", 10) == 0
  587.                || STRNICMP(argv[0] + argv_idx, "serversend", 10) == 0)
  588.         {
  589.             /* already processed -- snatch the following arg */
  590.             if (argc > 1)
  591.             {
  592.             --argc;
  593.             ++argv;
  594.             }
  595.         }
  596. #endif
  597. #ifdef FEAT_GUI_GTK
  598.         else if (STRNICMP(argv[0] + argv_idx, "socketid", 8) == 0)
  599.         {
  600.             /* already processed -- snatch the following arg */
  601.             if (argc > 1)
  602.             {
  603.             --argc;
  604.             ++argv;
  605.             }
  606.         }
  607.         else if (STRNICMP(argv[0] + argv_idx, "echo-wid", 8) == 0)
  608.         {
  609.             /* already processed, skip */
  610.         }
  611. #endif
  612.         else
  613.         {
  614.             if (argv[0][argv_idx])
  615.             mainerr(ME_UNKNOWN_OPTION, (char_u *)argv[0]);
  616.             had_minmin = TRUE;
  617.         }
  618.         if (!want_argument)
  619.             argv_idx = -1;    /* skip to next argument */
  620.         break;
  621.  
  622.         case 'A':        /* "-A" start in Arabic mode */
  623. #ifdef FEAT_ARABIC
  624.         set_option_value((char_u *)"arabic", 1L, NULL, 0);
  625. #else
  626.         mch_errmsg(_(e_noarabic));
  627.         mch_exit(2);
  628. #endif
  629.         break;
  630.  
  631.         case 'b':        /* "-b" binary mode */
  632.         bin_mode = TRUE;    /* postpone to after reading .exrc files */
  633.         break;
  634.  
  635.         case 'C':        /* "-C"  Compatible */
  636.         change_compatible(TRUE);
  637.         break;
  638.  
  639.         case 'e':        /* "-e" Ex mode */
  640.         exmode_active = EXMODE_NORMAL;
  641.         break;
  642.  
  643.         case 'E':        /* "-E" Improved Ex mode */
  644.         exmode_active = EXMODE_VIM;
  645.         break;
  646.  
  647.         case 'f':        /* "-f"  GUI: run in foreground.  Amiga: open
  648.                 window directly, not with newcli */
  649. #ifdef FEAT_GUI
  650.         gui.dofork = FALSE;    /* don't fork() when starting GUI */
  651. #endif
  652.         break;
  653.  
  654.         case 'g':        /* "-g" start GUI */
  655.         main_start_gui();
  656.         break;
  657.  
  658.         case 'F':        /* "-F" start in Farsi mode: rl + fkmap set */
  659. #ifdef FEAT_FKMAP
  660.         curwin->w_p_rl = p_fkmap = TRUE;
  661. #else
  662.         mch_errmsg(_(e_nofarsi));
  663.         mch_exit(2);
  664. #endif
  665.         break;
  666.  
  667.         case 'h':        /* "-h" give help message */
  668.         usage();
  669.         break;
  670.  
  671.         case 'H':        /* "-H" start in Hebrew mode: rl + hkmap set */
  672. #ifdef FEAT_RIGHTLEFT
  673.         curwin->w_p_rl = p_hkmap = TRUE;
  674. #else
  675.         mch_errmsg(_(e_nohebrew));
  676.         mch_exit(2);
  677. #endif
  678.         break;
  679.  
  680.         case 'l':        /* "-l" lisp mode, 'lisp' and 'showmatch' on */
  681. #ifdef FEAT_LISP
  682.         set_option_value((char_u *)"lisp", 1L, NULL, 0);
  683.         p_sm = TRUE;
  684. #endif
  685.         break;
  686.  
  687. #ifdef TARGET_API_MAC_OSX
  688.         /* For some reason on MacOS X, an argument like:
  689.            -psn_0_10223617 is passed in when invoke from Finder
  690.            or with the 'open' command */
  691.         case 'p':
  692.         argv_idx = -1; /* bypass full -psn */
  693.         main_start_gui();
  694.         break;
  695. #endif
  696.         case 'M':        /* "-M"  no changes or writing of files */
  697.         reset_modifiable();
  698.         /* FALLTRHOUGH */
  699.  
  700.         case 'm':        /* "-m"  no writing of files */
  701.         p_write = FALSE;
  702.         break;
  703.  
  704.         case 'y':        /* "-y"  easy mode */
  705. #ifdef FEAT_GUI
  706.         gui.starting = TRUE;    /* start GUI a bit later */
  707. #endif
  708.         evim_mode = TRUE;
  709.         break;
  710.  
  711.         case 'N':        /* "-N"  Nocompatible */
  712.         change_compatible(FALSE);
  713.         break;
  714.  
  715.         case 'n':        /* "-n" no swap file */
  716.         no_swap_file = TRUE;
  717.         break;
  718.  
  719.         case 'o':        /* "-o[N]" open N horizontal split windows */
  720. #ifdef FEAT_WINDOWS
  721.         /* default is 0: open window for each file */
  722.         window_count = get_number_arg((char_u *)argv[0], &argv_idx, 0);
  723.         vert_windows = FALSE;
  724. #endif
  725.         break;
  726.  
  727.         case 'O':    /* "-O[N]" open N vertical split windows */
  728. #if defined(FEAT_VERTSPLIT) && defined(FEAT_WINDOWS)
  729.         /* default is 0: open window for each file */
  730.         window_count = get_number_arg((char_u *)argv[0], &argv_idx, 0);
  731.         vert_windows = TRUE;
  732. #endif
  733.         break;
  734.  
  735. #ifdef FEAT_QUICKFIX
  736.         case 'q':        /* "-q" QuickFix mode */
  737.         if (edit_type != EDIT_NONE)
  738.             mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
  739.         edit_type = EDIT_QF;
  740.         if (argv[0][argv_idx])        /* "-q{errorfile}" */
  741.         {
  742.             use_ef = (char_u *)argv[0] + argv_idx;
  743.             argv_idx = -1;
  744.         }
  745.         else if (argc > 1)        /* "-q {errorfile}" */
  746.             want_argument = TRUE;
  747.         break;
  748. #endif
  749.  
  750.         case 'R':        /* "-R" readonly mode */
  751.         readonlymode = TRUE;
  752.         curbuf->b_p_ro = TRUE;
  753.         p_uc = 10000;            /* don't update very often */
  754.         break;
  755.  
  756.         case 'r':        /* "-r" recovery mode */
  757.         case 'L':        /* "-L" recovery mode */
  758.         recoverymode = 1;
  759.         break;
  760.  
  761.         case 's':
  762.         if (exmode_active)    /* "-s" silent (batch) mode */
  763.             silent_mode = TRUE;
  764.         else        /* "-s {scriptin}" read from script file */
  765.             want_argument = TRUE;
  766.         break;
  767.  
  768.         case 't':        /* "-t {tag}" or "-t{tag}" jump to tag */
  769.         if (edit_type != EDIT_NONE)
  770.             mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
  771.         edit_type = EDIT_TAG;
  772.         if (argv[0][argv_idx])        /* "-t{tag}" */
  773.         {
  774.             tagname = (char_u *)argv[0] + argv_idx;
  775.             argv_idx = -1;
  776.         }
  777.         else                /* "-t {tag}" */
  778.             want_argument = TRUE;
  779.         break;
  780.  
  781. #ifdef FEAT_EVAL
  782.         case 'D':        /* "-D"        Debugging */
  783.         debug_break_level = 9999;
  784.         break;
  785. #endif
  786. #ifdef FEAT_DIFF
  787.         case 'd':        /* "-d"        'diff' */
  788. # ifdef AMIGA
  789.         /* check for "-dev {device}" */
  790.         if (argv[0][argv_idx] == 'e' && argv[0][argv_idx + 1] == 'v')
  791.             want_argument = TRUE;
  792.         else
  793. # endif
  794.             diff_mode = TRUE;
  795.         break;
  796. #endif
  797.         case 'V':        /* "-V{N}"    Verbose level */
  798.         /* default is 10: a little bit verbose */
  799.         p_verbose = get_number_arg((char_u *)argv[0], &argv_idx, 10);
  800.         break;
  801.  
  802.         case 'v':        /* "-v"  Vi-mode (as if called "vi") */
  803.         exmode_active = 0;
  804. #ifdef FEAT_GUI
  805.         gui.starting = FALSE;    /* don't start GUI */
  806. #endif
  807.         break;
  808.  
  809.         case 'w':        /* "-w{number}"    set window height */
  810.                 /* "-w {scriptout}"    write to script */
  811.         if (isdigit(((char_u *)argv[0])[argv_idx]))
  812.         {
  813.             argv_idx = -1;
  814.             break;            /* not implemented, ignored */
  815.         }
  816.         want_argument = TRUE;
  817.         break;
  818.  
  819. #ifdef FEAT_CRYPT
  820.         case 'x':        /* "-x"  encrypted reading/writing of files */
  821.         ask_for_key = TRUE;
  822.         break;
  823. #endif
  824.  
  825.         case 'X':        /* "-X"  don't connect to X server */
  826. #if (defined(UNIX) || defined(VMS)) && defined(FEAT_X11)
  827.         x_no_connect = TRUE;
  828. #endif
  829.         break;
  830.  
  831.         case 'Z':        /* "-Z"  restricted mode */
  832.         restricted = TRUE;
  833.         break;
  834.  
  835.         case 'c':        /* "-c {command}" execute command */
  836.         case 'S':        /* "-S {file}" execute Vim script */
  837.         case 'i':        /* "-i {viminfo}" use for viminfo */
  838. #ifndef FEAT_DIFF
  839.         case 'd':        /* "-d {device}" device (for Amiga) */
  840. #endif
  841.         case 'T':        /* "-T {terminal}" terminal name */
  842.         case 'u':        /* "-u {vimrc}" vim inits file */
  843.         case 'U':        /* "-U {gvimrc}" gvim inits file */
  844.         case 'W':        /* "-W {scriptout}" overwrite */
  845.         want_argument = TRUE;
  846.         break;
  847.  
  848.         default:
  849.         mainerr(ME_UNKNOWN_OPTION, (char_u *)argv[0]);
  850.         }
  851.  
  852.         /*
  853.          * Handle options with argument.
  854.          */
  855.         if (want_argument)
  856.         {
  857.         /*
  858.          * Check for garbage immediately after the option letter.
  859.          */
  860.         if (argv[0][argv_idx] != NUL)
  861.             mainerr(ME_GARBAGE, (char_u *)argv[0]);
  862.  
  863.         --argc;
  864.         if (argc < 1 && c != 'S')
  865.             mainerr_arg_missing((char_u *)argv[0]);
  866.         ++argv;
  867.         argv_idx = -1;
  868.  
  869.         switch (c)
  870.         {
  871.         case 'c':    /* "-c {command}" execute command */
  872.         case 'S':    /* "-S {file}" execute Vim script */
  873.             if (n_commands >= MAX_ARG_CMDS)
  874.             mainerr(ME_EXTRA_CMD, NULL);
  875.             if (c == 'S')
  876.             {
  877.             char    *a;
  878.  
  879.             if (argc < 1)
  880.                 /* "-S" without argument: use default session file
  881.                  * name. */
  882.                 a = SESSION_FILE;
  883.             else if (argv[0][0] == '-')
  884.             {
  885.                 /* "-S" followed by another option: use default
  886.                  * session file name. */
  887.                 a = SESSION_FILE;
  888.                 ++argc;
  889.                 --argv;
  890.             }
  891.             else
  892.                 a = argv[0];
  893.             p = alloc((unsigned)(STRLEN(a) + 4));
  894.             if (p == NULL)
  895.                 mch_exit(2);
  896.             sprintf((char *)p, "so %s", a);
  897.             commands[n_commands++] = p;
  898.             }
  899.             else
  900.             commands[n_commands++] = (char_u *)argv[0];
  901.             break;
  902.  
  903. #ifdef FEAT_PRECOMMANDS
  904.         case '-':    /* "--cmd {command}" execute command */
  905.             if (p_commands >= MAX_ARG_CMDS)
  906.             mainerr(ME_EXTRA_CMD, NULL);
  907.             pre_commands[p_commands++] = (char_u *)argv[0];
  908.             break;
  909. #endif
  910.  
  911.         /*    case 'd':   -d {device} is handled in mch_check_win() for the
  912.          *            Amiga */
  913.  
  914. #ifdef FEAT_QUICKFIX
  915.         case 'q':    /* "-q {errorfile}" QuickFix mode */
  916.             use_ef = (char_u *)argv[0];
  917.             break;
  918. #endif
  919.  
  920.         case 'i':    /* "-i {viminfo}" use for viminfo */
  921.             use_viminfo = (char_u *)argv[0];
  922.             break;
  923.  
  924.         case 's':    /* "-s {scriptin}" read from script file */
  925.             if (scriptin[0] != NULL)
  926.             {
  927. scripterror:
  928.             mch_errmsg(_("Attempt to open script file again: \""));
  929.             mch_errmsg(argv[-1]);
  930.             mch_errmsg(" ");
  931.             mch_errmsg(argv[0]);
  932.             mch_errmsg(_("\"\n"));
  933.             mch_exit(2);
  934.             }
  935.             if ((scriptin[0] = mch_fopen(argv[0], READBIN)) == NULL)
  936.             {
  937.             mch_errmsg(_("Cannot open for reading: \""));
  938.             mch_errmsg(argv[0]);
  939.             mch_errmsg(_("\"\n"));
  940.             mch_exit(2);
  941.             }
  942.             if (save_typebuf() == FAIL)
  943.             mch_exit(2);    /* out of memory */
  944.             break;
  945.  
  946.         case 't':    /* "-t {tag}" */
  947.             tagname = (char_u *)argv[0];
  948.             break;
  949.  
  950.         case 'T':    /* "-T {terminal}" terminal name */
  951.             /*
  952.              * The -T term option is always available and when
  953.              * HAVE_TERMLIB is supported it overrides the environment
  954.              * variable TERM.
  955.              */
  956. #ifdef FEAT_GUI
  957.             if (term_is_gui((char_u *)argv[0]))
  958.             gui.starting = TRUE;    /* start GUI a bit later */
  959.             else
  960. #endif
  961.             term = (char_u *)argv[0];
  962.             break;
  963.  
  964.         case 'u':    /* "-u {vimrc}" vim inits file */
  965.             use_vimrc = (char_u *)argv[0];
  966.             break;
  967.  
  968.         case 'U':    /* "-U {gvimrc}" gvim inits file */
  969. #ifdef FEAT_GUI
  970.             use_gvimrc = (char_u *)argv[0];
  971. #endif
  972.             break;
  973.  
  974.         case 'w':    /* "-w {scriptout}" append to script file */
  975.         case 'W':    /* "-W {scriptout}" overwrite script file */
  976.             if (scriptout != NULL)
  977.             goto scripterror;
  978.             if ((scriptout = mch_fopen(argv[0],
  979.                     c == 'w' ? APPENDBIN : WRITEBIN)) == NULL)
  980.             {
  981.             mch_errmsg(_("Cannot open for script output: \""));
  982.             mch_errmsg(argv[0]);
  983.             mch_errmsg(_("\"\n"));
  984.             mch_exit(2);
  985.             }
  986.             break;
  987.         }
  988.         }
  989.     }
  990.  
  991.     /*
  992.      * File name argument.
  993.      */
  994.     else
  995.     {
  996.         argv_idx = -1;        /* skip to next argument */
  997.  
  998.         /* Check for only one type of editing. */
  999.         if (edit_type != EDIT_NONE && edit_type != EDIT_FILE)
  1000.         mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
  1001.         edit_type = EDIT_FILE;
  1002.  
  1003. #ifdef MSWIN
  1004.         /* Remember if the argument was a full path before changing
  1005.          * slashes to backslashes. */
  1006.         if (argv[0][0] != NUL && argv[0][1] == ':' && argv[0][2] == '\\')
  1007.         full_path = TRUE;
  1008. #endif
  1009.  
  1010.         /* Add the file to the global argument list. */
  1011.         if (ga_grow(&global_alist.al_ga, 1) == FAIL
  1012.             || (p = vim_strsave((char_u *)argv[0])) == NULL)
  1013.         mch_exit(2);
  1014. #ifdef FEAT_DIFF
  1015.         if (diff_mode && mch_isdir(p) && GARGCOUNT > 0
  1016.                       && !mch_isdir(alist_name(&GARGLIST[0])))
  1017.         {
  1018.         char_u        *r;
  1019.  
  1020.         r = concat_fnames(p, gettail(alist_name(&GARGLIST[0])), TRUE);
  1021.         if (r != NULL)
  1022.         {
  1023.             vim_free(p);
  1024.             p = r;
  1025.         }
  1026.         }
  1027. #endif
  1028. #if defined(__CYGWIN32__) && !defined(WIN32)
  1029.         /*
  1030.          * If vim is invoked by non-Cygwin tools, convert away any
  1031.          * DOS paths, so things like .swp files are created correctly.
  1032.          * Look for evidence of non-Cygwin paths before we bother.
  1033.          * This is only for when using the Unix files.
  1034.          */
  1035.         if (strpbrk(p, "\\:") != NULL)
  1036.         {
  1037.         char posix_path[PATH_MAX];
  1038.  
  1039.         cygwin_conv_to_posix_path(p, posix_path);
  1040.         vim_free(p);
  1041.         p = vim_strsave(posix_path);
  1042.         if (p == NULL)
  1043.             mch_exit(2);
  1044.         }
  1045. #endif
  1046.         alist_add(&global_alist, p,
  1047. #if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
  1048.             literal ? 2 : 0    /* add buffer number after expanding */
  1049. #else
  1050.             2        /* add buffer number now and use curbuf */
  1051. #endif
  1052.             );
  1053.     }
  1054.  
  1055.     /*
  1056.      * If there are no more letters after the current "-", go to next
  1057.      * argument.  argv_idx is set to -1 when the current argument is to be
  1058.      * skipped.
  1059.      */
  1060.     if (argv_idx <= 0 || argv[0][argv_idx] == NUL)
  1061.     {
  1062.         --argc;
  1063.         ++argv;
  1064.         argv_idx = 1;
  1065.     }
  1066.     }
  1067.     TIME_MSG("parsing arguments");
  1068.  
  1069.     /*
  1070.      * On some systems, when we compile with the GUI, we always use it.  On Mac
  1071.      * there is no terminal version, and on Windows we can't figure out how to
  1072.      * fork one off with :gui.
  1073.      */
  1074. #ifdef ALWAYS_USE_GUI
  1075.     gui.starting = TRUE;
  1076. #else
  1077. # if defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK)
  1078.     /*
  1079.      * Check if the GUI can be started.  Reset gui.starting if not.
  1080.      * Don't know about other systems, stay on the safe side and don't check.
  1081.      */
  1082.     if (gui.starting && gui_init_check() == FAIL)
  1083.     {
  1084.     gui.starting = FALSE;
  1085.  
  1086.     /* When running "evim" or "gvim -y" we need the menus, exit if we
  1087.      * don't have them. */
  1088.     if (evim_mode)
  1089.         mch_exit(1);
  1090.     }
  1091. # endif
  1092. #endif
  1093.  
  1094.     /* "-b" argument used.  Check before expanding file names, because for
  1095.      * Win32 this makes us edit a shortcut file itself, instead of the file it
  1096.      * links to. */
  1097.     if (bin_mode)
  1098.     {
  1099.     set_options_bin(curbuf->b_p_bin, 1, 0);
  1100.     curbuf->b_p_bin = 1;        /* binary file I/O */
  1101.     }
  1102.  
  1103.     if (GARGCOUNT > 0)
  1104.     {
  1105. #if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
  1106.     /*
  1107.      * Expand wildcards in file names.
  1108.      */
  1109.     if (!literal)
  1110.         alist_expand();
  1111. #endif
  1112.     fname = alist_name(&GARGLIST[0]);
  1113.     }
  1114.     if (GARGCOUNT > 1)
  1115.     printf(_("%d files to edit\n"), GARGCOUNT);
  1116. #ifdef MSWIN
  1117.     else if (GARGCOUNT == 1 && full_path)
  1118.     {
  1119.     /*
  1120.      * If there is one filename, fully qualified, we have very probably
  1121.      * been invoked from explorer, so change to the file's directory.
  1122.      * Hint: to avoid this when typing a command use a forward slash.
  1123.      * If the cd fails, it doesn't matter.
  1124.      */
  1125.     (void)vim_chdirfile(fname);
  1126.     }
  1127. #endif
  1128.     TIME_MSG("expanding arguments");
  1129.  
  1130. #ifdef FEAT_DIFF
  1131.     if (diff_mode)
  1132.     {
  1133.     if (window_count == -1)
  1134.         window_count = 0;        /* open up to 3 files in a window */
  1135.     if (vert_windows == MAYBE)
  1136.         vert_windows = TRUE;    /* use vertical split */
  1137.     }
  1138. #endif
  1139.  
  1140.     ++RedrawingDisabled;
  1141.  
  1142.     /*
  1143.      * When listing swap file names, don't do cursor positioning et. al.
  1144.      */
  1145.     if (recoverymode && fname == NULL)
  1146.     want_full_screen = FALSE;
  1147.  
  1148.     /*
  1149.      * When certain to start the GUI, don't check capabilities of terminal.
  1150.      * For GTK we can't be sure, but when started from the desktop it doesn't
  1151.      * make sense to try using a terminal.
  1152.      */
  1153. #if defined(ALWAYS_USE_GUI) || defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK)
  1154.     if (gui.starting
  1155. # ifdef FEAT_GUI_GTK
  1156.         && !isatty(2)
  1157. # endif
  1158.         )
  1159.     want_full_screen = FALSE;
  1160. #endif
  1161.  
  1162.     /*
  1163.      * mch_init() sets up the terminal (window) for use.  This must be
  1164.      * done after resetting full_screen, otherwise it may move the cursor
  1165.      * (MSDOS).
  1166.      * Note that we may use mch_exit() before mch_init()!
  1167.      */
  1168.     mch_init();
  1169.     TIME_MSG("shell init");
  1170.  
  1171. #ifdef USE_XSMP
  1172.     /*
  1173.      * For want of anywhere else to do it, try to connect to xsmp here.
  1174.      * Fitting it in after gui_mch_init, but before gui_init (via termcapinit).
  1175.      * Hijacking -X 'no X connection' to also disable XSMP connection as that
  1176.      * has a similar delay upon failure.
  1177.      * Only try if SESSION_MANAGER is set to something non-null.
  1178.      */
  1179.     if (!x_no_connect)
  1180.     {
  1181.     p = (char_u *)getenv("SESSION_MANAGER");
  1182.     if (p != NULL && *p != NUL)
  1183.         xsmp_init();
  1184.     }
  1185. #endif
  1186.  
  1187.     /*
  1188.      * Print a warning if stdout is not a terminal.
  1189.      * When starting in Ex mode and commands come from a file, set Silent mode.
  1190.      */
  1191.     input_isatty = mch_input_isatty();
  1192.     if (exmode_active)
  1193.     {
  1194.     if (!input_isatty)
  1195.         silent_mode = TRUE;
  1196.     }
  1197.     else if (want_full_screen && (!stdout_isatty || !input_isatty)
  1198. #ifdef FEAT_GUI
  1199.         /* don't want the delay when started from the desktop */
  1200.         && !gui.starting
  1201. #endif
  1202.         )
  1203.     {
  1204.     if (!stdout_isatty)
  1205.         mch_errmsg(_("Vim: Warning: Output is not to a terminal\n"));
  1206.     if (!input_isatty)
  1207.         mch_errmsg(_("Vim: Warning: Input is not from a terminal\n"));
  1208.     out_flush();
  1209.     if (scriptin[0] == NULL)
  1210.         ui_delay(2000L, TRUE);
  1211.     TIME_MSG("Warning delay");
  1212.     }
  1213.  
  1214.     if (want_full_screen)
  1215.     {
  1216.     termcapinit(term);    /* set terminal name and get terminal
  1217.                    capabilities (will set full_screen) */
  1218.     screen_start();        /* don't know where cursor is now */
  1219.     TIME_MSG("Termcap init");
  1220.     }
  1221.  
  1222.     /*
  1223.      * Set the default values for the options that use Rows and Columns.
  1224.      */
  1225.     ui_get_shellsize();        /* inits Rows and Columns */
  1226. #ifdef FEAT_NETBEANS_INTG
  1227.     if (usingNetbeans)
  1228.     Columns += 2;        /* leave room for glyph gutter */
  1229. #endif
  1230.     firstwin->w_height = Rows - p_ch;
  1231.     topframe->fr_height = Rows - p_ch;
  1232. #ifdef FEAT_VERTSPLIT
  1233.     firstwin->w_width = Columns;
  1234.     topframe->fr_width = Columns;
  1235. #endif
  1236. #ifdef FEAT_DIFF
  1237.     /* Set the 'diff' option now, so that it can be checked for in a .vimrc
  1238.      * file.  There is no buffer yet though. */
  1239.     if (diff_mode)
  1240.     diff_win_options(firstwin, FALSE);
  1241. #endif
  1242.  
  1243.     cmdline_row = Rows - p_ch;
  1244.     msg_row = cmdline_row;
  1245.     screenalloc(FALSE);        /* allocate screen buffers */
  1246.     set_init_2();
  1247.     TIME_MSG("inits 2");
  1248.  
  1249.     msg_scroll = TRUE;
  1250.     no_wait_return = TRUE;
  1251.  
  1252.     init_mappings();        /* set up initial mappings */
  1253.  
  1254.     init_highlight(TRUE, FALSE); /* set the default highlight groups */
  1255.     TIME_MSG("init highlight");
  1256. #ifdef CURSOR_SHAPE
  1257.     parse_shape_opt(SHAPE_CURSOR); /* set cursor shapes from 'guicursor' */
  1258. #endif
  1259. #ifdef FEAT_MOUSESHAPE
  1260.     parse_shape_opt(SHAPE_MOUSE);  /* set mouse shapes from 'mouseshape' */
  1261. #endif
  1262. #ifdef FEAT_PRINTER
  1263.     parse_list_options(p_popt, printer_opts, OPT_PRINT_NUM_OPTIONS);
  1264. #endif
  1265. #ifdef FEAT_PRECOMMANDS
  1266.     if (p_commands > 0)
  1267.     {
  1268.     curwin->w_cursor.lnum = 0; /* just in case.. */
  1269.     sourcing_name = (char_u *)_("pre-vimrc command line");
  1270.     for (i = 0; i < p_commands; ++i)
  1271.         do_cmdline_cmd(pre_commands[i]);
  1272.     sourcing_name = NULL;
  1273.     }
  1274. #endif
  1275.  
  1276.     /*
  1277.      * For "evim" source evim.vim first of all, so that the user can overrule
  1278.      * any things he doesn't like.
  1279.      */
  1280.     if (evim_mode)
  1281.     {
  1282.     (void)do_source((char_u *)EVIM_FILE, FALSE, FALSE);
  1283.     TIME_MSG("source evim file");
  1284.     }
  1285.  
  1286.     /*
  1287.      * If -u option given, use only the initializations from that file and
  1288.      * nothing else.
  1289.      */
  1290.     if (use_vimrc != NULL)
  1291.     {
  1292.     if (STRCMP(use_vimrc, "NONE") == 0 || STRCMP(use_vimrc, "NORC") == 0)
  1293.     {
  1294. #ifdef FEAT_GUI
  1295.         if (use_gvimrc == NULL)        /* don't load gvimrc either */
  1296.         use_gvimrc = use_vimrc;
  1297. #endif
  1298.         if (use_vimrc[2] == 'N')
  1299.         p_lpl = FALSE;            /* don't load plugins either */
  1300.     }
  1301.     else
  1302.     {
  1303.         if (do_source(use_vimrc, FALSE, FALSE) != OK)
  1304.         EMSG2(_("E282: Cannot read from \"%s\""), use_vimrc);
  1305.     }
  1306.     }
  1307.     else if (!silent_mode)
  1308.     {
  1309. #ifdef AMIGA
  1310.     struct Process    *proc = (struct Process *)FindTask(0L);
  1311.     APTR        save_winptr = proc->pr_WindowPtr;
  1312.  
  1313.     /* Avoid a requester here for a volume that doesn't exist. */
  1314.     proc->pr_WindowPtr = (APTR)-1L;
  1315. #endif
  1316.  
  1317.     /*
  1318.      * Get system wide defaults, if the file name is defined.
  1319.      */
  1320. #ifdef SYS_VIMRC_FILE
  1321.     (void)do_source((char_u *)SYS_VIMRC_FILE, FALSE, FALSE);
  1322. #endif
  1323.  
  1324.     /*
  1325.      * Try to read initialization commands from the following places:
  1326.      * - environment variable VIMINIT
  1327.      * - user vimrc file (s:.vimrc for Amiga, ~/.vimrc otherwise)
  1328.      * - second user vimrc file ($VIM/.vimrc for Dos)
  1329.      * - environment variable EXINIT
  1330.      * - user exrc file (s:.exrc for Amiga, ~/.exrc otherwise)
  1331.      * - second user exrc file ($VIM/.exrc for Dos)
  1332.      * The first that exists is used, the rest is ignored.
  1333.      */
  1334.     if (process_env((char_u *)"VIMINIT", TRUE) != OK)
  1335.     {
  1336.         if (do_source((char_u *)USR_VIMRC_FILE, TRUE, TRUE) == FAIL
  1337. #ifdef USR_VIMRC_FILE2
  1338.         && do_source((char_u *)USR_VIMRC_FILE2, TRUE, TRUE) == FAIL
  1339. #endif
  1340. #ifdef USR_VIMRC_FILE3
  1341.         && do_source((char_u *)USR_VIMRC_FILE3, TRUE, TRUE) == FAIL
  1342. #endif
  1343.         && process_env((char_u *)"EXINIT", FALSE) == FAIL
  1344.         && do_source((char_u *)USR_EXRC_FILE, FALSE, FALSE) == FAIL)
  1345.         {
  1346. #ifdef USR_EXRC_FILE2
  1347.         (void)do_source((char_u *)USR_EXRC_FILE2, FALSE, FALSE);
  1348. #endif
  1349.         }
  1350.     }
  1351.  
  1352.     /*
  1353.      * Read initialization commands from ".vimrc" or ".exrc" in current
  1354.      * directory.  This is only done if the 'exrc' option is set.
  1355.      * Because of security reasons we disallow shell and write commands
  1356.      * now, except for unix if the file is owned by the user or 'secure'
  1357.      * option has been reset in environmet of global ".exrc" or ".vimrc".
  1358.      * Only do this if VIMRC_FILE is not the same as USR_VIMRC_FILE or
  1359.      * SYS_VIMRC_FILE.
  1360.      */
  1361.     if (p_exrc)
  1362.     {
  1363. #if defined(UNIX) || defined(VMS)
  1364.         /* If ".vimrc" file is not owned by user, set 'secure' mode. */
  1365.         if (!file_owned(VIMRC_FILE))
  1366. #endif
  1367.         secure = p_secure;
  1368.  
  1369.         i = FAIL;
  1370.         if (fullpathcmp((char_u *)USR_VIMRC_FILE,
  1371.                       (char_u *)VIMRC_FILE, FALSE) != FPC_SAME
  1372. #ifdef USR_VIMRC_FILE2
  1373.             && fullpathcmp((char_u *)USR_VIMRC_FILE2,
  1374.                       (char_u *)VIMRC_FILE, FALSE) != FPC_SAME
  1375. #endif
  1376. #ifdef USR_VIMRC_FILE3
  1377.             && fullpathcmp((char_u *)USR_VIMRC_FILE3,
  1378.                       (char_u *)VIMRC_FILE, FALSE) != FPC_SAME
  1379. #endif
  1380. #ifdef SYS_VIMRC_FILE
  1381.             && fullpathcmp((char_u *)SYS_VIMRC_FILE,
  1382.                       (char_u *)VIMRC_FILE, FALSE) != FPC_SAME
  1383. #endif
  1384.                 )
  1385.         i = do_source((char_u *)VIMRC_FILE, TRUE, TRUE);
  1386.  
  1387.         if (i == FAIL)
  1388.         {
  1389. #if defined(UNIX) || defined(VMS)
  1390.         /* if ".exrc" is not owned by user set 'secure' mode */
  1391.         if (!file_owned(EXRC_FILE))
  1392.             secure = p_secure;
  1393.         else
  1394.             secure = 0;
  1395. #endif
  1396.         if (       fullpathcmp((char_u *)USR_EXRC_FILE,
  1397.                       (char_u *)EXRC_FILE, FALSE) != FPC_SAME
  1398. #ifdef USR_EXRC_FILE2
  1399.             && fullpathcmp((char_u *)USR_EXRC_FILE2,
  1400.                       (char_u *)EXRC_FILE, FALSE) != FPC_SAME
  1401. #endif
  1402.                 )
  1403.             (void)do_source((char_u *)EXRC_FILE, FALSE, FALSE);
  1404.         }
  1405.     }
  1406.     if (secure == 2)
  1407.         need_wait_return = TRUE;
  1408.     secure = 0;
  1409. #ifdef AMIGA
  1410.     proc->pr_WindowPtr = save_winptr;
  1411. #endif
  1412.     }
  1413.     TIME_MSG("sourcing vimrc file(s)");
  1414.  
  1415. #ifdef FEAT_EVAL
  1416.     /*
  1417.      * Read all the plugin files.
  1418.      * Only when compiled with +eval, since most plugins need it.
  1419.      */
  1420.     if (p_lpl)
  1421.     {
  1422.     cmd_runtime((char_u *)"plugin/*.vim", TRUE);
  1423.     TIME_MSG("loading plugins");
  1424.     }
  1425. #endif
  1426.  
  1427.     /*
  1428.      * Recovery mode without a file name: List swap files.
  1429.      * This uses the 'dir' option, therefore it must be after the
  1430.      * initializations.
  1431.      */
  1432.     if (recoverymode && fname == NULL)
  1433.     {
  1434.     recover_names(NULL, TRUE, 0);
  1435.     mch_exit(0);
  1436.     }
  1437.  
  1438.     /*
  1439.      * Set a few option defaults after reading .vimrc files:
  1440.      * 'title' and 'icon', Unix: 'shellpipe' and 'shellredir'.
  1441.      */
  1442.     set_init_3();
  1443.     TIME_MSG("inits 3");
  1444.  
  1445.     /*
  1446.      * "-n" argument: Disable swap file by setting 'updatecount' to 0.
  1447.      * Note that this overrides anything from a vimrc file.
  1448.      */
  1449.     if (no_swap_file)
  1450.     p_uc = 0;
  1451.  
  1452. #ifdef FEAT_FKMAP
  1453.     if (curwin->w_p_rl && p_altkeymap)
  1454.     {
  1455.     p_hkmap = FALSE;    /* Reset the Hebrew keymap mode */
  1456. # ifdef FEAT_ARABIC
  1457.     curwin->w_p_arab = FALSE; /* Reset the Arabic keymap mode */
  1458. # endif
  1459.     p_fkmap = TRUE;        /* Set the Farsi keymap mode */
  1460.     }
  1461. #endif
  1462.  
  1463. #ifdef FEAT_GUI
  1464.     if (gui.starting)
  1465.     {
  1466. #if defined(UNIX) || defined(VMS)
  1467.     /* When something caused a message from a vimrc script, need to output
  1468.      * an extra newline before the shell prompt. */
  1469.     if (did_emsg || msg_didout)
  1470.         putchar('\n');
  1471. #endif
  1472.  
  1473.     gui_start();        /* will set full_screen to TRUE */
  1474.     TIME_MSG("starting GUI");
  1475.  
  1476.     /* When running "evim" or "gvim -y" we need the menus, exit if we
  1477.      * don't have them. */
  1478.     if (!gui.in_use && evim_mode)
  1479.         mch_exit(1);
  1480.     }
  1481. #endif
  1482.  
  1483. #ifdef SPAWNO        /* special MSDOS swapping library */
  1484.     init_SPAWNO("", SWAP_ANY);
  1485. #endif
  1486.  
  1487. #ifdef FEAT_VIMINFO
  1488.     /*
  1489.      * Read in registers, history etc, but not marks, from the viminfo file
  1490.      */
  1491.     if (*p_viminfo != NUL)
  1492.     {
  1493.     read_viminfo(NULL, TRUE, FALSE, FALSE);
  1494.     TIME_MSG("reading viminfo");
  1495.     }
  1496. #endif
  1497.  
  1498. #ifdef FEAT_QUICKFIX
  1499.     /*
  1500.      * "-q errorfile": Load the error file now.
  1501.      * If the error file can't be read, exit before doing anything else.
  1502.      */
  1503.     if (edit_type == EDIT_QF)
  1504.     {
  1505.     if (use_ef != NULL)
  1506.         set_string_option_direct((char_u *)"ef", -1, use_ef, OPT_FREE);
  1507.     if (qf_init(p_ef, p_efm, TRUE) < 0)
  1508.     {
  1509.         out_char('\n');
  1510.         mch_exit(3);
  1511.     }
  1512.     TIME_MSG("reading errorfile");
  1513.     }
  1514. #endif
  1515.  
  1516.     /*
  1517.      * Start putting things on the screen.
  1518.      * Scroll screen down before drawing over it
  1519.      * Clear screen now, so file message will not be cleared.
  1520.      */
  1521.     starting = NO_BUFFERS;
  1522.     no_wait_return = FALSE;
  1523.     if (!exmode_active)
  1524.     msg_scroll = FALSE;
  1525.  
  1526. #ifdef FEAT_GUI
  1527.     /*
  1528.      * This seems to be required to make callbacks to be called now, instead
  1529.      * of after things have been put on the screen, which then may be deleted
  1530.      * when getting a resize callback.
  1531.      */
  1532.     if (gui.in_use)
  1533.     {
  1534. # ifdef FEAT_SUN_WORKSHOP
  1535.     if (!usingSunWorkShop)
  1536. # endif
  1537.         gui_wait_for_chars(50L);
  1538.     TIME_MSG("GUI delay");
  1539.     }
  1540. #endif
  1541.  
  1542. #if defined(FEAT_GUI_PHOTON) && defined(FEAT_CLIPBOARD)
  1543.     qnx_clip_init();
  1544. #endif
  1545.  
  1546. #ifdef FEAT_XCLIPBOARD
  1547.     /* Start using the X clipboard, unless the GUI was started. */
  1548. # ifdef FEAT_GUI
  1549.     if (!gui.in_use)
  1550. # endif
  1551.     {
  1552.     setup_term_clip();
  1553.     TIME_MSG("setup clipboard");
  1554.     }
  1555. #endif
  1556.  
  1557. #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
  1558.     /*
  1559.      * Register for remote command execution with :serversend and --remote
  1560.      * unless there was a -X or a --servername '' on the command line.
  1561.      * Only register nongui-vim's with an explicit --servername argument.
  1562.      */
  1563.     if (X_DISPLAY != NULL && servername != NULL && (
  1564. # ifdef FEAT_GUI
  1565.         gui.in_use ||
  1566. # endif
  1567.         serverName_arg != NULL))
  1568.     {
  1569.     (void)serverRegisterName(X_DISPLAY, servername);
  1570.     vim_free(servername);
  1571.     }
  1572.     else
  1573.     serverDelayedStartName = servername;
  1574. #endif
  1575.  
  1576. #ifdef FEAT_CLIENTSERVER
  1577.     /*
  1578.      * Execute command ourselves if we're here because the send failed (or
  1579.      * else we would have exited above).
  1580.      */
  1581.     if (serverStr != NULL)
  1582.     server_to_input_buf(serverStr);
  1583. #endif
  1584.  
  1585.     /*
  1586.      * If "-" argument given: Read file from stdin.
  1587.      * Do this before starting Raw mode, because it may change things that the
  1588.      * writing end of the pipe doesn't like, e.g., in case stdin and stderr
  1589.      * are the same terminal: "cat | vim -".
  1590.      * Using autocommands here may cause trouble...
  1591.      */
  1592.     if (edit_type == EDIT_STDIN && !recoverymode)
  1593.     {
  1594. #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
  1595.     /* When getting the ATTENTION prompt here, use a dialog */
  1596.     swap_exists_action = SEA_DIALOG;
  1597. #endif
  1598.     no_wait_return = TRUE;
  1599.     i = msg_didany;
  1600.     set_buflisted(TRUE);
  1601.     (void)open_buffer(TRUE, NULL);    /* create memfile and read file */
  1602.     no_wait_return = FALSE;
  1603.     msg_didany = i;
  1604.     TIME_MSG("reading stdin");
  1605. #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
  1606.     check_swap_exists_action();
  1607. #endif
  1608. #if !(defined(AMIGA) || defined(MACOS))
  1609.     /*
  1610.      * Close stdin and dup it from stderr.  Required for GPM to work
  1611.      * properly, and for running external commands.
  1612.      * Is there any other system that cannot do this?
  1613.      */
  1614.     close(0);
  1615.     dup(2);
  1616. #endif
  1617.     }
  1618.  
  1619. #if defined(UNIX) || defined(VMS)
  1620.     /* When switching screens and something caused a message from a vimrc
  1621.      * script, need to output an extra newline on exit. */
  1622.     if ((did_emsg || msg_didout) && *T_TI != NUL)
  1623.     newline_on_exit = TRUE;
  1624. #endif
  1625.  
  1626.     /*
  1627.      * When done something that is not allowed or error message call
  1628.      * wait_return.  This must be done before starttermcap(), because it may
  1629.      * switch to another screen. It must be done after settmode(TMODE_RAW),
  1630.      * because we want to react on a single key stroke.
  1631.      * Call settmode and starttermcap here, so the T_KS and T_TI may be
  1632.      * defined by termcapinit and redifined in .exrc.
  1633.      */
  1634.     settmode(TMODE_RAW);
  1635.     if (need_wait_return || msg_didany)
  1636.     {
  1637.     wait_return(TRUE);
  1638.     TIME_MSG("waiting for return");
  1639.     }
  1640.  
  1641.     starttermcap();        /* start termcap if not done by wait_return() */
  1642. #ifdef FEAT_MOUSE
  1643.     setmouse();                /* may start using the mouse */
  1644. #endif
  1645.     if (scroll_region)
  1646.     scroll_region_reset();        /* In case Rows changed */
  1647.  
  1648.     scroll_start();
  1649.  
  1650.     /*
  1651.      * Don't clear the screen when starting in Ex mode, unless using the GUI.
  1652.      */
  1653.     if (exmode_active
  1654. #ifdef FEAT_GUI
  1655.             && !gui.in_use
  1656. #endif
  1657.                     )
  1658.     must_redraw = CLEAR;
  1659.     else
  1660.     {
  1661.     screenclear();            /* clear screen */
  1662.     TIME_MSG("clearing screen");
  1663.     }
  1664.  
  1665. #ifdef FEAT_CRYPT
  1666.     if (ask_for_key)
  1667.     {
  1668.     (void)get_crypt_key(TRUE, TRUE);
  1669.     TIME_MSG("getting crypt key");
  1670.     }
  1671. #endif
  1672.  
  1673.     no_wait_return = TRUE;
  1674.  
  1675. #ifdef FEAT_WINDOWS
  1676.     /*
  1677.      * Create the number of windows that was requested.
  1678.      */
  1679.     if (window_count == -1)    /* was not set */
  1680.     window_count = 1;
  1681.     if (window_count == 0)
  1682.     window_count = GARGCOUNT;
  1683.     if (window_count > 1)
  1684.     {
  1685.     /* Don't change the windows if there was a command in .vimrc that
  1686.      * already split some windows */
  1687.     if (vert_windows == MAYBE)
  1688.         vert_windows = FALSE;
  1689.     if (firstwin->w_next == NULL)
  1690.     {
  1691.         window_count = make_windows(window_count, vert_windows);
  1692.         TIME_MSG("making windows");
  1693.     }
  1694.     else
  1695.         window_count = win_count();
  1696.     }
  1697.     else
  1698.     window_count = 1;
  1699. #endif
  1700.  
  1701.     if (recoverymode)            /* do recover */
  1702.     {
  1703.     msg_scroll = TRUE;        /* scroll message up */
  1704.     ml_recover();
  1705.     msg_scroll = FALSE;
  1706.     if (curbuf->b_ml.ml_mfp == NULL) /* failed */
  1707.         getout(1);
  1708.     do_modelines();            /* do modelines */
  1709.     }
  1710.     else
  1711.     {
  1712.     /*
  1713.      * Open a buffer for windows that don't have one yet.
  1714.      * Commands in the .vimrc might have loaded a file or split the window.
  1715.      * Watch out for autocommands that delete a window.
  1716.      */
  1717. #ifdef FEAT_AUTOCMD
  1718.     /*
  1719.      * Don't execute Win/Buf Enter/Leave autocommands here
  1720.      */
  1721.     ++autocmd_no_enter;
  1722.     ++autocmd_no_leave;
  1723. #endif
  1724. #ifdef FEAT_WINDOWS
  1725.     for (curwin = firstwin; curwin != NULL; curwin = W_NEXT(curwin))
  1726. #endif
  1727.     {
  1728.         curbuf = curwin->w_buffer;
  1729.         if (curbuf->b_ml.ml_mfp == NULL)
  1730.         {
  1731. #ifdef FEAT_FOLDING
  1732.         /* Set 'foldlevel' to 'foldlevelstart' if it's not negative. */
  1733.         if (p_fdls >= 0)
  1734.             curwin->w_p_fdl = p_fdls;
  1735. #endif
  1736. #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
  1737.         /* When getting the ATTENTION prompt here, use a dialog */
  1738.         swap_exists_action = SEA_DIALOG;
  1739. #endif
  1740.         set_buflisted(TRUE);
  1741.         (void)open_buffer(FALSE, NULL); /* create memfile, read file */
  1742.  
  1743. #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
  1744.         check_swap_exists_action();
  1745. #endif
  1746. #ifdef FEAT_AUTOCMD
  1747.         curwin = firstwin;        /* start again */
  1748. #endif
  1749.         }
  1750. #ifdef FEAT_WINDOWS
  1751.         ui_breakcheck();
  1752.         if (got_int)
  1753.         {
  1754.         (void)vgetc();    /* only break the file loading, not the rest */
  1755.         break;
  1756.         }
  1757. #endif
  1758.     }
  1759. #ifdef FEAT_AUTOCMD
  1760.     --autocmd_no_enter;
  1761.     --autocmd_no_leave;
  1762. #endif
  1763. #ifdef FEAT_WINDOWS
  1764.     curwin = firstwin;
  1765.     curbuf = curwin->w_buffer;
  1766. #endif
  1767.     }
  1768.     TIME_MSG("opening buffers");
  1769.  
  1770.     /* Ex starts at last line of the file */
  1771.     if (exmode_active)
  1772.     curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
  1773.  
  1774. #ifdef FEAT_AUTOCMD
  1775.     apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
  1776.     TIME_MSG("BufEnter autocommands");
  1777. #endif
  1778.     setpcmark();
  1779.  
  1780. #ifdef FEAT_QUICKFIX
  1781.     /*
  1782.      * When started with "-q errorfile" jump to first error now.
  1783.      */
  1784.     if (edit_type == EDIT_QF)
  1785.     {
  1786.     qf_jump(0, 0, FALSE);
  1787.     TIME_MSG("jump to first error");
  1788.     }
  1789. #endif
  1790.  
  1791. #ifdef FEAT_WINDOWS
  1792.     /*
  1793.      * If opened more than one window, start editing files in the other
  1794.      * windows.  Make_windows() has already opened the windows.
  1795.      */
  1796. # ifdef FEAT_AUTOCMD
  1797.     /*
  1798.      * Don't execute Win/Buf Enter/Leave autocommands here
  1799.      */
  1800.     ++autocmd_no_enter;
  1801.     ++autocmd_no_leave;
  1802. # endif
  1803.     arg_idx = 1;
  1804.     for (i = 1; i < window_count; ++i)
  1805.     {
  1806.     if (curwin->w_next == NULL)        /* just checking */
  1807.         break;
  1808.     win_enter(curwin->w_next, FALSE);
  1809.  
  1810.     /* Only open the file if there is no file in this window yet (that can
  1811.      * happen when .vimrc contains ":sall") */
  1812.     if (curbuf == firstwin->w_buffer || curbuf->b_ffname == NULL)
  1813.     {
  1814.         curwin->w_arg_idx = arg_idx;
  1815.         /* edit file from arg list, if there is one */
  1816.         (void)do_ecmd(0, arg_idx < GARGCOUNT
  1817.               ? alist_name(&GARGLIST[arg_idx]) : NULL,
  1818.               NULL, NULL, ECMD_LASTL, ECMD_HIDE);
  1819.         if (arg_idx == GARGCOUNT - 1)
  1820.         arg_had_last = TRUE;
  1821.         ++arg_idx;
  1822.     }
  1823.     ui_breakcheck();
  1824.     if (got_int)
  1825.     {
  1826.         (void)vgetc();    /* only break the file loading, not the rest */
  1827.         break;
  1828.     }
  1829.     }
  1830. # ifdef FEAT_AUTOCMD
  1831.     --autocmd_no_enter;
  1832. # endif
  1833.     win_enter(firstwin, FALSE);        /* back to first window */
  1834. # ifdef FEAT_AUTOCMD
  1835.     --autocmd_no_leave;
  1836. # endif
  1837.     TIME_MSG("editing files in windows");
  1838.     if (window_count > 1)
  1839.     win_equal(curwin, FALSE, 'b');    /* adjust heights */
  1840. #endif /* FEAT_WINDOWS */
  1841.  
  1842. #ifdef FEAT_DIFF
  1843.     if (diff_mode)
  1844.     {
  1845.     win_T    *wp;
  1846.  
  1847.     /* set options in each window for "vimdiff". */
  1848.     for (wp = firstwin; wp != NULL; wp = wp->w_next)
  1849.         diff_win_options(wp, TRUE);
  1850.     }
  1851. #endif
  1852.  
  1853.     /*
  1854.      * Shorten any of the filenames, but only when absolute.
  1855.      */
  1856.     shorten_fnames(FALSE);
  1857.  
  1858.     /*
  1859.      * Need to jump to the tag before executing the '-c command'.
  1860.      * Makes "vim -c '/return' -t main" work.
  1861.      */
  1862.     if (tagname != NULL)
  1863.     {
  1864.     STRCPY(IObuff, "ta ");
  1865.  
  1866.     STRNCAT(IObuff, tagname, IOSIZE - 4);
  1867.     IObuff[IOSIZE - 1] = NUL;
  1868.     do_cmdline_cmd(IObuff);
  1869.     TIME_MSG("jumping to tag");
  1870.     }
  1871.  
  1872.     if (n_commands > 0)
  1873.     {
  1874.     /*
  1875.      * We start commands on line 0, make "vim +/pat file" match a
  1876.      * pattern on line 1.
  1877.      */
  1878.     msg_scroll = TRUE;
  1879.     if (tagname == NULL)
  1880.         curwin->w_cursor.lnum = 0;
  1881.     sourcing_name = (char_u *)"command line";
  1882.     for (i = 0; i < n_commands; ++i)
  1883.         do_cmdline_cmd(commands[i]);
  1884.     sourcing_name = NULL;
  1885.     if (curwin->w_cursor.lnum == 0)
  1886.         curwin->w_cursor.lnum = 1;
  1887.  
  1888.     if (!exmode_active)
  1889.         msg_scroll = FALSE;
  1890.  
  1891. #ifdef FEAT_QUICKFIX
  1892.     /* When started with "-q errorfile" jump to first error again. */
  1893.     if (edit_type == EDIT_QF)
  1894.         qf_jump(0, 0, FALSE);
  1895. #endif
  1896.     TIME_MSG("executing command arguments");
  1897.     }
  1898.  
  1899.     RedrawingDisabled = 0;
  1900.     redraw_all_later(NOT_VALID);
  1901.     no_wait_return = FALSE;
  1902.     starting = 0;
  1903.  
  1904.     /* start in insert mode */
  1905.     if (p_im)
  1906.     need_start_insertmode = TRUE;
  1907.  
  1908. #ifdef FEAT_AUTOCMD
  1909.     apply_autocmds(EVENT_VIMENTER, NULL, NULL, FALSE, curbuf);
  1910.     TIME_MSG("VimEnter autocommands");
  1911. #endif
  1912.  
  1913. #if defined(FEAT_DIFF) && defined(FEAT_SCROLLBIND)
  1914.     /* When a startup script or session file setup for diff'ing and
  1915.      * scrollbind, sync the scrollbind now. */
  1916.     if (curwin->w_p_diff && curwin->w_p_scb)
  1917.     {
  1918.     update_topline();
  1919.     check_scrollbind((linenr_T)0, 0L);
  1920.     TIME_MSG("diff scrollbinding");
  1921.     }
  1922. #endif
  1923.  
  1924. #if defined(WIN3264) && !defined(FEAT_GUI_W32)
  1925.     mch_set_winsize_now();        /* Allow winsize changes from now on */
  1926. #endif
  1927.  
  1928.     /* If ":startinsert" command used, stuff a dummy command to be able to
  1929.      * call normal_cmd(), which will then start Insert mode. */
  1930.     if (restart_edit != 0)
  1931.     stuffcharReadbuff(K_IGNORE);
  1932.  
  1933. #ifdef FEAT_NETBEANS_INTG
  1934.     if (usingNetbeans)
  1935.     /* Tell the client that it can start sending commands. */
  1936.     netbeans_startup_done();
  1937. #endif
  1938.  
  1939.     TIME_MSG("before starting main loop");
  1940.  
  1941.     /*
  1942.      * Call the main command loop.  This never returns.
  1943.      */
  1944.     main_loop(FALSE);
  1945.  
  1946.     return 0;
  1947. }
  1948. #endif /* PROTO */
  1949.  
  1950. /*
  1951.  * Main loop: Execute Normal mode commands until exiting Vim.
  1952.  * Also used to handle commands in the command-line window, until the window
  1953.  * is closed.
  1954.  */
  1955.     void
  1956. main_loop(cmdwin)
  1957.     int        cmdwin;    /* TRUE when working in the command-line window */
  1958. {
  1959.     oparg_T    oa;    /* operator arguments */
  1960.  
  1961. #if defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)
  1962.     /* Setup to catch a terminating error from the X server.  Just ignore
  1963.      * it, restore the state and continue.  This might not always work
  1964.      * properly, but at least we don't exit unexpectedly when the X server
  1965.      * exists while Vim is running in a console. */
  1966.     if (!cmdwin && SETJMP(x_jump_env))
  1967.     {
  1968.     State = NORMAL;
  1969. # ifdef FEAT_VISUAL
  1970.     VIsual_active = FALSE;
  1971. # endif
  1972.     got_int = TRUE;
  1973.     need_wait_return = FALSE;
  1974.     global_busy = FALSE;
  1975.     exmode_active = 0;
  1976.     skip_redraw = FALSE;
  1977.     RedrawingDisabled = 0;
  1978.     no_wait_return = 0;
  1979. # ifdef FEAT_EVAL
  1980.     emsg_skip = 0;
  1981. # endif
  1982.     emsg_off = 0;
  1983. # ifdef FEAT_MOUSE
  1984.     setmouse();
  1985. # endif
  1986.     settmode(TMODE_RAW);
  1987.     starttermcap();
  1988.     scroll_start();
  1989.     redraw_later_clear();
  1990.     }
  1991. #endif
  1992.  
  1993.     clear_oparg(&oa);
  1994.     while (!cmdwin
  1995. #ifdef FEAT_CMDWIN
  1996.         || cmdwin_result == 0
  1997. #endif
  1998.         )
  1999.     {
  2000.     if (stuff_empty())
  2001.     {
  2002.         did_check_timestamps = FALSE;
  2003.         if (need_check_timestamps)
  2004.         check_timestamps(FALSE);
  2005.         if (need_wait_return)    /* if wait_return still needed ... */
  2006.         wait_return(FALSE);    /* ... call it now */
  2007.         if (need_start_insertmode && goto_im()
  2008. #ifdef FEAT_VISUAL
  2009.             && !VIsual_active
  2010. #endif
  2011.             )
  2012.         {
  2013.         need_start_insertmode = FALSE;
  2014.         stuffReadbuff((char_u *)"i");    /* start insert mode next */
  2015.         /* skip the fileinfo message now, because it would be shown
  2016.          * after insert mode finishes! */
  2017.         need_fileinfo = FALSE;
  2018.         }
  2019.     }
  2020.     if (got_int && !global_busy)
  2021.     {
  2022.         if (!quit_more)
  2023.         (void)vgetc();        /* flush all buffers */
  2024.         got_int = FALSE;
  2025.     }
  2026.     if (!exmode_active)
  2027.         msg_scroll = FALSE;
  2028.     quit_more = FALSE;
  2029.  
  2030.     /*
  2031.      * If skip redraw is set (for ":" in wait_return()), don't redraw now.
  2032.      * If there is nothing in the stuff_buffer or do_redraw is TRUE,
  2033.      * update cursor and redraw.
  2034.      */
  2035.     if (skip_redraw || exmode_active)
  2036.         skip_redraw = FALSE;
  2037.     else if (do_redraw || stuff_empty())
  2038.     {
  2039. #if defined(FEAT_FOLDING) && defined(FEAT_VISUAL)
  2040.         /* Include a closed fold completely in the Visual area. */
  2041.         foldAdjustVisual();
  2042. #endif
  2043. #ifdef FEAT_FOLDING
  2044.         /*
  2045.          * When 'foldclose' is set, apply 'foldlevel' to folds that don't
  2046.          * contain the cursor.
  2047.          * When 'foldopen' is "all", open the fold(s) under the cursor.
  2048.          * This may mark the window for redrawing.
  2049.          */
  2050.         if (hasAnyFolding(curwin) && !char_avail())
  2051.         {
  2052.         foldCheckClose();
  2053.         if (fdo_flags & FDO_ALL)
  2054.             foldOpenCursor();
  2055.         }
  2056. #endif
  2057.  
  2058.         /*
  2059.          * Before redrawing, make sure w_topline is correct, and w_leftcol
  2060.          * if lines don't wrap, and w_skipcol if lines wrap.
  2061.          */
  2062.         update_topline();
  2063.         validate_cursor();
  2064.  
  2065. #ifdef FEAT_VISUAL
  2066.         if (VIsual_active)
  2067.         update_curbuf(INVERTED);/* update inverted part */
  2068.         else
  2069. #endif
  2070.         if (must_redraw)
  2071.         update_screen(0);
  2072.         else if (redraw_cmdline || clear_cmdline)
  2073.         showmode();
  2074. #ifdef FEAT_WINDOWS
  2075.         redraw_statuslines();
  2076. #endif
  2077. #ifdef FEAT_TITLE
  2078.         if (need_maketitle)
  2079.         maketitle();
  2080. #endif
  2081.         /* display message after redraw */
  2082.         if (keep_msg != NULL)
  2083.         {
  2084.         char_u *p;
  2085.  
  2086.         /* msg_attr_keep() will set keep_msg to NULL, must free the
  2087.          * string here. */
  2088.         p = keep_msg;
  2089.         msg_attr(p, keep_msg_attr);
  2090.         vim_free(p);
  2091.         }
  2092.         if (need_fileinfo)        /* show file info after redraw */
  2093.         {
  2094.         fileinfo(FALSE, TRUE, FALSE);
  2095.         need_fileinfo = FALSE;
  2096.         }
  2097.  
  2098.         emsg_on_display = FALSE;    /* can delete error message now */
  2099.         did_emsg = FALSE;
  2100.         msg_didany = FALSE;        /* reset lines_left in msg_start() */
  2101.         showruler(FALSE);
  2102.  
  2103.         setcursor();
  2104.         cursor_on();
  2105.  
  2106.         do_redraw = FALSE;
  2107.     }
  2108. #ifdef FEAT_GUI
  2109.     if (need_mouse_correct)
  2110.         gui_mouse_correct();
  2111. #endif
  2112.  
  2113.     /*
  2114.      * Update w_curswant if w_set_curswant has been set.
  2115.      * Postponed until here to avoid computing w_virtcol too often.
  2116.      */
  2117.     update_curswant();
  2118.  
  2119.     /*
  2120.      * If we're invoked as ex, do a round of ex commands.
  2121.      * Otherwise, get and execute a normal mode command.
  2122.      */
  2123.     if (exmode_active)
  2124.         do_exmode(exmode_active == EXMODE_VIM);
  2125.     else
  2126.         normal_cmd(&oa, TRUE);
  2127.     }
  2128. }
  2129.  
  2130.  
  2131. #if defined(USE_XSMP) || defined(FEAT_GUI_MSWIN) || defined(PROTO)
  2132. /*
  2133.  * Exit, but leave behind swap files for modified buffers.
  2134.  */
  2135.     void
  2136. getout_preserve_modified(exitval)
  2137.     int        exitval;
  2138. {
  2139.     ml_close_notmod();            /* close all not-modified buffers */
  2140.     ml_sync_all(FALSE, FALSE);        /* preserve all swap files */
  2141.     ml_close_all(FALSE);        /* close all memfiles, without deleting */
  2142.     getout(exitval);            /* exit Vim properly */
  2143. }
  2144. #endif
  2145.  
  2146.  
  2147. /* Exit properly */
  2148.     void
  2149. getout(exitval)
  2150.     int        exitval;
  2151. {
  2152. #ifdef FEAT_AUTOCMD
  2153.     buf_T    *buf;
  2154.     win_T    *wp;
  2155. #endif
  2156.  
  2157.     exiting = TRUE;
  2158.  
  2159.     /* Position the cursor on the last screen line, below all the text */
  2160. #ifdef FEAT_GUI
  2161.     if (!gui.in_use)
  2162. #endif
  2163.     windgoto((int)Rows - 1, 0);
  2164.  
  2165. #ifdef FEAT_AUTOCMD
  2166.     /* Trigger BufWinLeave for all windows, but only once per buffer. */
  2167.     for (wp = firstwin; wp != NULL; )
  2168.     {
  2169.     buf = wp->w_buffer;
  2170.     if (buf->b_changedtick != -1)
  2171.     {
  2172.         apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
  2173.                                   FALSE, buf);
  2174.         buf->b_changedtick = -1;    /* note that we did it already */
  2175.         wp = firstwin;        /* restart, window may be closed */
  2176.     }
  2177.     else
  2178.         wp = wp->w_next;
  2179.     }
  2180.     /* Trigger BufUnload for buffers that are loaded */
  2181.     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  2182.     if (buf->b_ml.ml_mfp != NULL)
  2183.     {
  2184.         apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname,
  2185.                                   FALSE, buf);
  2186.         if (!buf_valid(buf))    /* autocmd may delete the buffer */
  2187.         break;
  2188.     }
  2189.     apply_autocmds(EVENT_VIMLEAVEPRE, NULL, NULL, FALSE, curbuf);
  2190. #endif
  2191.  
  2192. #ifdef FEAT_VIMINFO
  2193.     if (*p_viminfo != NUL)
  2194.     {
  2195.     /* Write out the registers, history, marks etc, to the viminfo file */
  2196.     msg_didany = FALSE;
  2197.     write_viminfo(NULL, FALSE);
  2198.     if (msg_didany)        /* make the user read the error message */
  2199.     {
  2200.         no_wait_return = FALSE;
  2201.         wait_return(FALSE);
  2202.     }
  2203.     }
  2204. #endif /* FEAT_VIMINFO */
  2205.  
  2206. #ifdef FEAT_AUTOCMD
  2207.     apply_autocmds(EVENT_VIMLEAVE, NULL, NULL, FALSE, curbuf);
  2208.  
  2209.     /* Position the cursor again, the autocommands may have moved it */
  2210. # ifdef FEAT_GUI
  2211.     if (!gui.in_use)
  2212. # endif
  2213.     windgoto((int)Rows - 1, 0);
  2214. #endif
  2215.  
  2216. #ifdef FEAT_TCL
  2217.     tcl_end();
  2218. #endif
  2219. #ifdef FEAT_RUBY
  2220.     ruby_end();
  2221. #endif
  2222. #ifdef FEAT_PYTHON
  2223.     python_end();
  2224. #endif
  2225. #ifdef FEAT_PERL
  2226.     perl_end();
  2227. #endif
  2228. #if defined(USE_ICONV) && defined(DYNAMIC_ICONV)
  2229.     iconv_end();
  2230. #endif
  2231. #ifdef FEAT_NETBEANS_INTG
  2232.     netbeans_end();
  2233. #endif
  2234.  
  2235.     mch_exit(exitval);
  2236. }
  2237.  
  2238. /*
  2239.  * Get a (optional) count for a Vim argument.
  2240.  */
  2241.     static int
  2242. get_number_arg(p, idx, def)
  2243.     char_u    *p;        /* pointer to argument */
  2244.     int        *idx;        /* index in argument, is incremented */
  2245.     int        def;        /* default value */
  2246. {
  2247.     if (isdigit(p[*idx]))
  2248.     {
  2249.     def = atoi((char *)&(p[*idx]));
  2250.     while (isdigit(p[*idx]))
  2251.         *idx = *idx + 1;
  2252.     }
  2253.     return def;
  2254. }
  2255.  
  2256. /*
  2257.  * Setup to start using the GUI.  Exit with an error when not available.
  2258.  */
  2259.     static void
  2260. main_start_gui()
  2261. {
  2262. #ifdef FEAT_GUI
  2263.     gui.starting = TRUE;    /* start GUI a bit later */
  2264. #else
  2265.     mch_errmsg(_(e_nogvim));
  2266.     mch_errmsg("\n");
  2267.     mch_exit(2);
  2268. #endif
  2269. }
  2270.  
  2271. /*
  2272.  * Get an evironment variable, and execute it as Ex commands.
  2273.  * Returns FAIL if the environment variable was not executed, OK otherwise.
  2274.  */
  2275.     int
  2276. process_env(env, is_viminit)
  2277.     char_u    *env;
  2278.     int        is_viminit; /* when TRUE, called for VIMINIT */
  2279. {
  2280.     char_u    *initstr;
  2281.     char_u    *save_sourcing_name;
  2282.     linenr_T    save_sourcing_lnum;
  2283.  
  2284.     if ((initstr = mch_getenv(env)) != NULL && *initstr != NUL)
  2285.     {
  2286.     if (is_viminit)
  2287.         vimrc_found();
  2288.     save_sourcing_name = sourcing_name;
  2289.     save_sourcing_lnum = sourcing_lnum;
  2290.     sourcing_name = env;
  2291.     sourcing_lnum = 0;
  2292.     do_cmdline_cmd(initstr);
  2293.     sourcing_name = save_sourcing_name;
  2294.     sourcing_lnum = save_sourcing_lnum;
  2295.     return OK;
  2296.     }
  2297.     return FAIL;
  2298. }
  2299.  
  2300. #if defined(UNIX) || defined(VMS)
  2301. /*
  2302.  * Return TRUE if we are certain the user owns the file "fname".
  2303.  * Used for ".vimrc" and ".exrc".
  2304.  * Use both stat() and lstat() for extra security.
  2305.  */
  2306.     static int
  2307. file_owned(fname)
  2308.     char    *fname;
  2309. {
  2310.     struct stat s;
  2311. # ifdef UNIX
  2312.     uid_t    uid = getuid();
  2313. # else     /* VMS */
  2314.     uid_t    uid = ((getgid() << 16) | getuid());
  2315. # endif
  2316.  
  2317.     return !(mch_stat(fname, &s) != 0 || s.st_uid != uid
  2318. # ifdef HAVE_LSTAT
  2319.         || mch_lstat(fname, &s) != 0 || s.st_uid != uid
  2320. # endif
  2321.         );
  2322. }
  2323. #endif
  2324.  
  2325. /*
  2326.  * Give an error message main_errors["n"] and exit.
  2327.  */
  2328.     static void
  2329. mainerr(n, str)
  2330.     int        n;    /* one of the ME_ defines */
  2331.     char_u    *str;    /* extra argument or NULL */
  2332. {
  2333. #if defined(UNIX) || defined(__EMX__) || defined(VMS)
  2334.     reset_signals();        /* kill us with CTRL-C here, if you like */
  2335. #endif
  2336.  
  2337.     mch_errmsg(longVersion);
  2338.     mch_errmsg("\n");
  2339.     mch_errmsg(_(main_errors[n]));
  2340.     if (str != NULL)
  2341.     {
  2342.     mch_errmsg(": \"");
  2343.     mch_errmsg((char *)str);
  2344.     mch_errmsg("\"");
  2345.     }
  2346.     mch_errmsg(_("\nMore info with: \"vim -h\"\n"));
  2347.  
  2348.     mch_exit(1);
  2349. }
  2350.  
  2351.     void
  2352. mainerr_arg_missing(str)
  2353.     char_u    *str;
  2354. {
  2355.     mainerr(ME_ARG_MISSING, str);
  2356. }
  2357.  
  2358. /*
  2359.  * print a message with three spaces prepended and '\n' appended.
  2360.  */
  2361.     static void
  2362. main_msg(s)
  2363.     char *s;
  2364. {
  2365.     mch_msg("   ");
  2366.     mch_msg(s);
  2367.     mch_msg("\n");
  2368. }
  2369.  
  2370. /*
  2371.  * Print messages for "vim -h" or "vim --help" and exit.
  2372.  */
  2373.     static void
  2374. usage()
  2375. {
  2376.     int        i;
  2377.     static char    *(use[]) =
  2378.     {
  2379.     N_("[file ..]       edit specified file(s)"),
  2380.     N_("-               read text from stdin"),
  2381.     N_("-t tag          edit file where tag is defined"),
  2382. #ifdef FEAT_QUICKFIX
  2383.     N_("-q [errorfile]  edit file with first error")
  2384. #endif
  2385.     };
  2386.  
  2387. #if defined(UNIX) || defined(__EMX__) || defined(VMS)
  2388.     reset_signals();        /* kill us with CTRL-C here, if you like */
  2389. #endif
  2390.  
  2391.     mch_msg(longVersion);
  2392.     mch_msg(_("\n\nusage:"));
  2393.     for (i = 0; ; ++i)
  2394.     {
  2395.     mch_msg(_(" vim [arguments] "));
  2396.     mch_msg(_(use[i]));
  2397.     if (i == (sizeof(use) / sizeof(char_u *)) - 1)
  2398.         break;
  2399.     mch_msg(_("\n   or:"));
  2400.     }
  2401.  
  2402.     mch_msg(_("\n\nArguments:\n"));
  2403.     main_msg(_("--\t\t\tOnly file names after this"));
  2404. #if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
  2405.     main_msg(_("--literal\t\tDon't expand wildcards"));
  2406. #endif
  2407. #ifdef FEAT_OLE
  2408.     main_msg(_("-register\t\tRegister this gvim for OLE"));
  2409.     main_msg(_("-unregister\t\tUnregister gvim for OLE"));
  2410. #endif
  2411. #ifdef FEAT_GUI
  2412.     main_msg(_("-g\t\t\tRun using GUI (like \"gvim\")"));
  2413.     main_msg(_("-f  or  --nofork\tForeground: Don't fork when starting GUI"));
  2414. #endif
  2415.     main_msg(_("-v\t\t\tVi mode (like \"vi\")"));
  2416.     main_msg(_("-e\t\t\tEx mode (like \"ex\")"));
  2417.     main_msg(_("-s\t\t\tSilent (batch) mode (only for \"ex\")"));
  2418. #ifdef FEAT_DIFF
  2419.     main_msg(_("-d\t\t\tDiff mode (like \"vimdiff\")"));
  2420. #endif
  2421.     main_msg(_("-y\t\t\tEasy mode (like \"evim\", modeless)"));
  2422.     main_msg(_("-R\t\t\tReadonly mode (like \"view\")"));
  2423.     main_msg(_("-Z\t\t\tRestricted mode (like \"rvim\")"));
  2424.     main_msg(_("-m\t\t\tModifications (writing files) not allowed"));
  2425.     main_msg(_("-M\t\t\tModifications in text not allowed"));
  2426.     main_msg(_("-b\t\t\tBinary mode"));
  2427. #ifdef FEAT_LISP
  2428.     main_msg(_("-l\t\t\tLisp mode"));
  2429. #endif
  2430.     main_msg(_("-C\t\t\tCompatible with Vi: 'compatible'"));
  2431.     main_msg(_("-N\t\t\tNot fully Vi compatible: 'nocompatible'"));
  2432.     main_msg(_("-V[N]\t\tVerbose level"));
  2433.     main_msg(_("-D\t\t\tDebugging mode"));
  2434.     main_msg(_("-n\t\t\tNo swap file, use memory only"));
  2435.     main_msg(_("-r\t\t\tList swap files and exit"));
  2436.     main_msg(_("-r (with file name)\tRecover crashed session"));
  2437.     main_msg(_("-L\t\t\tSame as -r"));
  2438. #ifdef AMIGA
  2439.     main_msg(_("-f\t\t\tDon't use newcli to open window"));
  2440.     main_msg(_("-dev <device>\t\tUse <device> for I/O"));
  2441. #endif
  2442. #ifdef FEAT_ARABIC
  2443.     main_msg(_("-A\t\t\tstart in Arabic mode"));
  2444. #endif
  2445. #ifdef FEAT_RIGHTLEFT
  2446.     main_msg(_("-H\t\t\tStart in Hebrew mode"));
  2447. #endif
  2448. #ifdef FEAT_FKMAP
  2449.     main_msg(_("-F\t\t\tStart in Farsi mode"));
  2450. #endif
  2451.     main_msg(_("-T <terminal>\tSet terminal type to <terminal>"));
  2452.     main_msg(_("-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"));
  2453. #ifdef FEAT_GUI
  2454.     main_msg(_("-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"));
  2455. #endif
  2456.     main_msg(_("--noplugin\t\tDon't load plugin scripts"));
  2457.     main_msg(_("-o[N]\t\tOpen N windows (default: one for each file)"));
  2458.     main_msg(_("-O[N]\t\tLike -o but split vertically"));
  2459.     main_msg(_("+\t\t\tStart at end of file"));
  2460.     main_msg(_("+<lnum>\t\tStart at line <lnum>"));
  2461. #ifdef FEAT_PRECOMMANDS
  2462.     main_msg(_("--cmd <command>\tExecute <command> before loading any vimrc file"));
  2463. #endif
  2464.     main_msg(_("-c <command>\t\tExecute <command> after loading the first file"));
  2465.     main_msg(_("-S <session>\t\tSource file <session> after loading the first file"));
  2466.     main_msg(_("-s <scriptin>\tRead Normal mode commands from file <scriptin>"));
  2467.     main_msg(_("-w <scriptout>\tAppend all typed commands to file <scriptout>"));
  2468.     main_msg(_("-W <scriptout>\tWrite all typed commands to file <scriptout>"));
  2469. #ifdef FEAT_CRYPT
  2470.     main_msg(_("-x\t\t\tEdit encrypted files"));
  2471. #endif
  2472. #if (defined(UNIX) || defined(VMS)) && defined(FEAT_X11)
  2473. # if defined(FEAT_GUI_X11) && !defined(FEAT_GUI_GTK)
  2474.     main_msg(_("-display <display>\tConnect vim to this particular X-server"));
  2475. # endif
  2476.     main_msg(_("-X\t\t\tDo not connect to X server"));
  2477. #endif
  2478. #ifdef FEAT_CLIENTSERVER
  2479.     main_msg(_("--remote <files>\tEdit <files> in a Vim server if possible"));
  2480.     main_msg(_("--remote-silent <files>  Same, don't complain if there is no server"));
  2481.     main_msg(_("--remote-wait <files>  As --remote but wait for files to have been edited"));
  2482.     main_msg(_("--remote-wait-silent <files>  Same, don't complain if there is no server"));
  2483.     main_msg(_("--remote-send <keys>\tSend <keys> to a Vim server and exit"));
  2484.     main_msg(_("--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"));
  2485.     main_msg(_("--serverlist\t\tList available Vim server names and exit"));
  2486.     main_msg(_("--servername <name>\tSend to/become the Vim server <name>"));
  2487. #endif
  2488. #ifdef FEAT_VIMINFO
  2489.     main_msg(_("-i <viminfo>\t\tUse <viminfo> instead of .viminfo"));
  2490. #endif
  2491.     main_msg(_("-h  or  --help\tPrint Help (this message) and exit"));
  2492.     main_msg(_("--version\t\tPrint version information and exit"));
  2493.  
  2494. #ifdef FEAT_GUI_X11
  2495. # ifdef FEAT_GUI_MOTIF
  2496.     mch_msg(_("\nArguments recognised by gvim (Motif version):\n"));
  2497. # else
  2498. #  ifdef FEAT_GUI_ATHENA
  2499. #   ifdef FEAT_GUI_NEXTAW
  2500.     mch_msg(_("\nArguments recognised by gvim (neXtaw version):\n"));
  2501. #   else
  2502.     mch_msg(_("\nArguments recognised by gvim (Athena version):\n"));
  2503. #   endif
  2504. #  endif
  2505. # endif
  2506.     main_msg(_("-display <display>\tRun vim on <display>"));
  2507.     main_msg(_("-iconic\t\tStart vim iconified"));
  2508. # if 0
  2509.     main_msg(_("-name <name>\t\tUse resource as if vim was <name>"));
  2510.     mch_msg(_("\t\t\t  (Unimplemented)\n"));
  2511. # endif
  2512.     main_msg(_("-background <color>\tUse <color> for the background (also: -bg)"));
  2513.     main_msg(_("-foreground <color>\tUse <color> for normal text (also: -fg)"));
  2514.     main_msg(_("-font <font>\t\tUse <font> for normal text (also: -fn)"));
  2515.     main_msg(_("-boldfont <font>\tUse <font> for bold text"));
  2516.     main_msg(_("-italicfont <font>\tUse <font> for italic text"));
  2517.     main_msg(_("-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"));
  2518.     main_msg(_("-borderwidth <width>\tUse a border width of <width> (also: -bw)"));
  2519.     main_msg(_("-scrollbarwidth <width>  Use a scrollbar width of <width> (also: -sw)"));
  2520. # ifdef FEAT_GUI_ATHENA
  2521.     main_msg(_("-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"));
  2522. # endif
  2523.     main_msg(_("-reverse\t\tUse reverse video (also: -rv)"));
  2524.     main_msg(_("+reverse\t\tDon't use reverse video (also: +rv)"));
  2525.     main_msg(_("-xrm <resource>\tSet the specified resource"));
  2526. #endif /* FEAT_GUI_X11 */
  2527. #if defined(FEAT_GUI) && defined(RISCOS)
  2528.     mch_msg(_("\nArguments recognised by gvim (RISC OS version):\n"));
  2529.     main_msg(_("--columns <number>\tInitial width of window in columns"));
  2530.     main_msg(_("--rows <number>\tInitial height of window in rows"));
  2531. #endif
  2532. #ifdef FEAT_GUI_GTK
  2533.     mch_msg(_("\nArguments recognised by gvim (GTK+ version):\n"));
  2534.     main_msg(_("-font <font>\t\tUse <font> for normal text (also: -fn)"));
  2535.     main_msg(_("-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"));
  2536.     main_msg(_("-reverse\t\tUse reverse video (also: -rv)"));
  2537.     main_msg(_("-display <display>\tRun vim on <display> (also: --display)"));
  2538. # ifdef HAVE_GTK2
  2539.     main_msg(_("--role <role>\tSet a unique role to identify the main window"));
  2540. # endif
  2541.     main_msg(_("--socketid <xid>\tOpen Vim inside another GTK widget"));
  2542. # ifdef FEAT_GUI_GNOME
  2543.     main_msg(_("--help\t\tShow Gnome arguments"));
  2544. # endif
  2545. #endif
  2546.     mch_exit(0);
  2547. }
  2548.  
  2549. #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
  2550. /*
  2551.  * Check the result of the ATTENTION dialog:
  2552.  * When "Quit" selected, exit Vim.
  2553.  * When "Recover" selected, recover the file.
  2554.  */
  2555.     static void
  2556. check_swap_exists_action()
  2557. {
  2558.     if (swap_exists_action == SEA_QUIT)
  2559.     getout(1);
  2560.     handle_swap_exists(NULL);
  2561. }
  2562. #endif
  2563.  
  2564. #if defined(STARTUPTIME) || defined(PROTO)
  2565. static void time_diff __ARGS((struct timeval *then, struct timeval *now));
  2566.  
  2567. static struct timeval    prev_timeval;
  2568.  
  2569. /*
  2570.  * Save the previous time before doing something that could nest.
  2571.  * set "*tv_rel" to the time elapsed so far.
  2572.  */
  2573.     void
  2574. time_push(tv_rel, tv_start)
  2575.     void    *tv_rel, *tv_start;
  2576. {
  2577.     *((struct timeval *)tv_rel) = prev_timeval;
  2578.     gettimeofday(&prev_timeval, NULL);
  2579.     ((struct timeval *)tv_rel)->tv_usec = prev_timeval.tv_usec
  2580.                     - ((struct timeval *)tv_rel)->tv_usec;
  2581.     ((struct timeval *)tv_rel)->tv_sec = prev_timeval.tv_sec
  2582.                      - ((struct timeval *)tv_rel)->tv_sec;
  2583.     if (((struct timeval *)tv_rel)->tv_usec < 0)
  2584.     {
  2585.     ((struct timeval *)tv_rel)->tv_usec += 1000000;
  2586.     --((struct timeval *)tv_rel)->tv_sec;
  2587.     }
  2588.     *(struct timeval *)tv_start = prev_timeval;
  2589. }
  2590.  
  2591. /*
  2592.  * Compute the previous time after doing something that could nest.
  2593.  * Subtract "*tp" from prev_timeval;
  2594.  * Note: The arguments are (void *) to avoid trouble with systems that don't
  2595.  * have struct timeval.
  2596.  */
  2597.     void
  2598. time_pop(tp)
  2599.     void    *tp;    /* actually (struct timeval *) */
  2600. {
  2601.     prev_timeval.tv_usec -= ((struct timeval *)tp)->tv_usec;
  2602.     prev_timeval.tv_sec -= ((struct timeval *)tp)->tv_sec;
  2603.     if (prev_timeval.tv_usec < 0)
  2604.     {
  2605.     prev_timeval.tv_usec += 1000000;
  2606.     --prev_timeval.tv_sec;
  2607.     }
  2608. }
  2609.  
  2610.     static void
  2611. time_diff(then, now)
  2612.     struct timeval    *then;
  2613.     struct timeval    *now;
  2614. {
  2615.     long    usec;
  2616.     long    msec;
  2617.  
  2618.     usec = now->tv_usec - then->tv_usec;
  2619.     msec = (now->tv_sec - then->tv_sec) * 1000L + usec / 1000L,
  2620.     usec = usec % 1000L;
  2621.     fprintf(time_fd, "%03ld.%03ld", msec, usec >= 0 ? usec : usec + 1000L);
  2622. }
  2623.  
  2624.     void
  2625. time_msg(msg, tv_start)
  2626.     char    *msg;
  2627.     void    *tv_start;  /* only for do_source: start time; actually
  2628.                    (struct timeval *) */
  2629. {
  2630.     static struct timeval    start;
  2631.     struct timeval        now;
  2632.  
  2633.     if (time_fd != NULL)
  2634.     {
  2635.     if (strstr(msg, "STARTING") != NULL)
  2636.     {
  2637.         gettimeofday(&start, NULL);
  2638.         prev_timeval = start;
  2639.         fprintf(time_fd, "\n\ntimes in msec\n");
  2640.         fprintf(time_fd, " clock   self+sourced   self:  sourced script\n");
  2641.         fprintf(time_fd, " clock   elapsed:              other lines\n\n");
  2642.     }
  2643.     gettimeofday(&now, NULL);
  2644.     time_diff(&start, &now);
  2645.     if (((struct timeval *)tv_start) != NULL)
  2646.     {
  2647.         fprintf(time_fd, "  ");
  2648.         time_diff(((struct timeval *)tv_start), &now);
  2649.     }
  2650.     fprintf(time_fd, "  ");
  2651.     time_diff(&prev_timeval, &now);
  2652.     prev_timeval = now;
  2653.     fprintf(time_fd, ": %s\n", msg);
  2654.     }
  2655. }
  2656.  
  2657. # ifdef WIN3264
  2658. /*
  2659.  * Windows doesn't have gettimeofday(), although it does have struct timeval.
  2660.  */
  2661.     int
  2662. gettimeofday(struct timeval *tv, char *dummy)
  2663. {
  2664.     long t = clock();
  2665.     tv->tv_sec = t / CLOCKS_PER_SEC;
  2666.     tv->tv_usec = (t - tv->tv_sec * CLOCKS_PER_SEC) * 1000000 / CLOCKS_PER_SEC;
  2667.     return 0;
  2668. }
  2669. # endif
  2670.  
  2671. #endif
  2672.  
  2673. #if defined(FEAT_CLIENTSERVER) || defined(PROTO)
  2674.  
  2675. /*
  2676.  * Common code for the X command server and the Win32 command server.
  2677.  */
  2678.  
  2679. static char_u *build_drop_cmd __ARGS((int filec, char **filev, int sendReply));
  2680.  
  2681.     static void
  2682. cmdsrv_main(argc, argv, serverName_arg, serverStr)
  2683.     int        *argc;
  2684.     char    **argv;
  2685.     char_u    *serverName_arg;
  2686.     char_u    **serverStr;
  2687. {
  2688.     char_u    *res;
  2689.     int        i;
  2690.     char_u    *sname;
  2691.     int        ret;
  2692.     int        didone = FALSE;
  2693.     int        exiterr = 0;
  2694.     char    **newArgV = argv + 1;
  2695.     int        newArgC = 1,
  2696.         Argc = *argc;
  2697.     int        argtype;
  2698. #define ARGTYPE_OTHER        0
  2699. #define ARGTYPE_EDIT        1
  2700. #define ARGTYPE_EDIT_WAIT    2
  2701. #define ARGTYPE_SEND        3
  2702.     int        silent = FALSE;
  2703. # ifndef FEAT_X11
  2704.     HWND    srv;
  2705. # else
  2706.     Window    srv;
  2707.  
  2708.     setup_term_clip();
  2709. # endif
  2710.  
  2711.     sname = serverMakeName(serverName_arg, argv[0]);
  2712.     if (sname == NULL)
  2713.     return;
  2714.  
  2715.     /*
  2716.      * Execute the command server related arguments and remove them
  2717.      * from the argc/argv array; We may have to return into main()
  2718.      */
  2719.     for (i = 1; i < Argc; i++)
  2720.     {
  2721.     res = NULL;
  2722.     if (STRCMP(argv[i], "--") == 0)    /* end of options */
  2723.     {
  2724.         for (; i < *argc; i++)
  2725.         {
  2726.         *newArgV++ = argv[i];
  2727.         newArgC++;
  2728.         }
  2729.         break;
  2730.     }
  2731.  
  2732.     if (STRICMP(argv[i], "--remote") == 0)
  2733.         argtype = ARGTYPE_EDIT;
  2734.     else if (STRICMP(argv[i], "--remote-silent") == 0)
  2735.     {
  2736.         argtype = ARGTYPE_EDIT;
  2737.         silent = TRUE;
  2738.     }
  2739.     else if (STRICMP(argv[i], "--remote-wait") == 0)
  2740.         argtype = ARGTYPE_EDIT_WAIT;
  2741.     else if (STRICMP(argv[i], "--remote-wait-silent") == 0)
  2742.     {
  2743.         argtype = ARGTYPE_EDIT_WAIT;
  2744.         silent = TRUE;
  2745.     }
  2746.     else if (STRICMP(argv[i], "--remote-send") == 0)
  2747.         argtype = ARGTYPE_SEND;
  2748.     else
  2749.         argtype = ARGTYPE_OTHER;
  2750.     if (argtype != ARGTYPE_OTHER)
  2751.     {
  2752.         if (i == *argc - 1)
  2753.         mainerr_arg_missing((char_u *)argv[i]);
  2754.         if (argtype == ARGTYPE_SEND)
  2755.         {
  2756.         *serverStr = (char_u *)argv[i + 1];
  2757.         i++;
  2758.         }
  2759.         else
  2760.         {
  2761.         *serverStr = build_drop_cmd(*argc - i - 1, argv + i + 1,
  2762.                         argtype == ARGTYPE_EDIT_WAIT);
  2763.         if (*serverStr == NULL)
  2764.         {
  2765.             /* Probably out of memory, exit. */
  2766.             didone = TRUE;
  2767.             exiterr = 1;
  2768.             break;
  2769.         }
  2770.         Argc = i;
  2771.         }
  2772. # ifdef FEAT_X11
  2773.         if (xterm_dpy == NULL)
  2774.         {
  2775.         mch_errmsg(_("No display"));
  2776.         ret = -1;
  2777.         }
  2778.         else
  2779.         ret = serverSendToVim(xterm_dpy, sname, *serverStr,
  2780.                             NULL, &srv, 0, 0, silent);
  2781. # else
  2782.         /* Win32 always works? */
  2783.         ret = serverSendToVim(sname, *serverStr, NULL, &srv, 0, silent);
  2784. # endif
  2785.         if (ret < 0)
  2786.         {
  2787.         if (argtype == ARGTYPE_SEND)
  2788.         {
  2789.             /* Failed to send, abort. */
  2790.             mch_errmsg(_(": Send failed.\n"));
  2791.             didone = TRUE;
  2792.             exiterr = 1;
  2793.         }
  2794.         else if (!silent)
  2795.             /* Let vim start normally.  */
  2796.             mch_errmsg(_(": Send failed. Trying to execute locally\n"));
  2797.         break;
  2798.         }
  2799.  
  2800. # ifdef FEAT_GUI_W32
  2801.         /* Guess that when the server name starts with "g" it's a GUI
  2802.          * server, which we can bring to the foreground here.
  2803.          * Foreground() in the server doesn't work very well. */
  2804.         if (argtype != ARGTYPE_SEND && TOUPPER_ASC(*sname) == 'G')
  2805.         SetForegroundWindow(srv);
  2806. # endif
  2807.  
  2808.         /*
  2809.          * For --remote-wait: Wait until the server did edit each
  2810.          * file.  Also detect that the server no longer runs.
  2811.          */
  2812.         if (ret >= 0 && argtype == ARGTYPE_EDIT_WAIT)
  2813.         {
  2814.         int    numFiles = *argc - i - 1;
  2815.         int    j;
  2816.         char_u  *done = alloc(numFiles);
  2817.         char_u  *p;
  2818. # ifdef FEAT_GUI_W32
  2819.         NOTIFYICONDATA ni;
  2820.         int    count = 0;
  2821.         extern HWND message_window;
  2822. # endif
  2823.  
  2824.         if (numFiles > 0 && argv[i + 1][0] == '+')
  2825.             /* Skip "+cmd" argument, don't wait for it to be edited. */
  2826.             --numFiles;
  2827.  
  2828. # ifdef FEAT_GUI_W32
  2829.         ni.cbSize = sizeof(ni);
  2830.         ni.hWnd = message_window;
  2831.         ni.uID = 0;
  2832.         ni.uFlags = NIF_ICON|NIF_TIP;
  2833.         ni.hIcon = LoadIcon((HINSTANCE)GetModuleHandle(0), "IDR_VIM");
  2834.         sprintf(ni.szTip, _("%d of %d edited"), count, numFiles);
  2835.         Shell_NotifyIcon(NIM_ADD, &ni);
  2836. # endif
  2837.  
  2838.         /* Wait for all files to unload in remote */
  2839.         memset(done, 0, numFiles);
  2840.         while (memchr(done, 0, numFiles) != NULL)
  2841.         {
  2842. # ifdef WIN32
  2843.             p = serverGetReply(srv, NULL, TRUE, TRUE);
  2844.             if (p == NULL)
  2845.             break;
  2846. # else
  2847.             if (serverReadReply(xterm_dpy, srv, &p, TRUE) < 0)
  2848.             break;
  2849. # endif
  2850.             j = atoi((char *)p);
  2851.             if (j >= 0 && j < numFiles)
  2852.             {
  2853. # ifdef FEAT_GUI_W32
  2854.             ++count;
  2855.             sprintf(ni.szTip, _("%d of %d edited"),
  2856.                                  count, numFiles);
  2857.             Shell_NotifyIcon(NIM_MODIFY, &ni);
  2858. # endif
  2859.             done[j] = 1;
  2860.             }
  2861.         }
  2862. # ifdef FEAT_GUI_W32
  2863.         Shell_NotifyIcon(NIM_DELETE, &ni);
  2864. # endif
  2865.         }
  2866.     }
  2867.     else if (STRICMP(argv[i], "--remote-expr") == 0)
  2868.     {
  2869.         if (i == *argc - 1)
  2870.         mainerr_arg_missing((char_u *)argv[i]);
  2871. # ifdef WIN32
  2872.         /* Win32 always works? */
  2873.         if (serverSendToVim(sname, (char_u *)argv[i + 1],
  2874.                             &res, NULL, 1, FALSE) < 0)
  2875. # else
  2876.         if (xterm_dpy == NULL)
  2877.         mch_errmsg(_("No display: Send expression failed.\n"));
  2878.         else if (serverSendToVim(xterm_dpy, sname, (char_u *)argv[i + 1],
  2879.                          &res, NULL, 1, 1, FALSE) < 0)
  2880. # endif
  2881.         {
  2882.         if (res != NULL && *res != NUL)
  2883.         {
  2884.             /* Output error from remote */
  2885.             mch_errmsg((char *)res);
  2886.             vim_free(res);
  2887.             res = NULL;
  2888.         }
  2889.         mch_errmsg(_(": Send expression failed.\n"));
  2890.         }
  2891.     }
  2892.     else if (STRICMP(argv[i], "--serverlist") == 0)
  2893.     {
  2894. # ifdef WIN32
  2895.         /* Win32 always works? */
  2896.         res = serverGetVimNames();
  2897. # else
  2898.         if (xterm_dpy != NULL)
  2899.         res = serverGetVimNames(xterm_dpy);
  2900. # endif
  2901.         if (called_emsg)
  2902.         mch_errmsg("\n");
  2903.     }
  2904.     else if (STRICMP(argv[i], "--servername") == 0)
  2905.     {
  2906.         /* Alredy processed. Take it out of the command line */
  2907.         i++;
  2908.         continue;
  2909.     }
  2910.     else
  2911.     {
  2912.         *newArgV++ = argv[i];
  2913.         newArgC++;
  2914.         continue;
  2915.     }
  2916.     didone = TRUE;
  2917.     if (res != NULL && *res != NUL)
  2918.     {
  2919.         mch_msg((char *)res);
  2920.         if (res[STRLEN(res) - 1] != '\n')
  2921.         mch_msg("\n");
  2922.     }
  2923.     vim_free(res);
  2924.     }
  2925.  
  2926.     if (didone)
  2927.     {
  2928.     display_errors();    /* display any collected messages */
  2929.     exit(exiterr);    /* Mission accomplished - get out */
  2930.     }
  2931.  
  2932.     /* Return back into main() */
  2933.     *argc = newArgC;
  2934.     vim_free(sname);
  2935. }
  2936.  
  2937. /*
  2938.  * Build a ":drop" command to send to a Vim server.
  2939.  */
  2940.     static char_u *
  2941. build_drop_cmd(filec, filev, sendReply)
  2942.     int        filec;
  2943.     char    **filev;
  2944.     int        sendReply;
  2945. {
  2946.     garray_T    ga;
  2947.     int        i;
  2948.     char_u    *inicmd = NULL;
  2949.     char_u    *p;
  2950.     char_u    cwd[MAXPATHL];
  2951.  
  2952.     if (filec > 0 && filev[0][0] == '+')
  2953.     {
  2954.     inicmd = (char_u *)filev[0] + 1;
  2955.     filev++;
  2956.     filec--;
  2957.     }
  2958.     /* Check if we have at least one argument. */
  2959.     if (filec <= 0)
  2960.     mainerr_arg_missing((char_u *)filev[-1]);
  2961.     if (mch_dirname(cwd, MAXPATHL) != OK)
  2962.     return NULL;
  2963.     if ((p = vim_strsave_escaped(cwd, PATH_ESC_CHARS)) == NULL)
  2964.     return NULL;
  2965.     ga_init2(&ga, 1, 100);
  2966.     ga_concat(&ga, (char_u *)"<C-\\><C-N>:cd ");
  2967.     ga_concat(&ga, p);
  2968.     /* Call inputsave() so that a prompt for an encryption key works. */
  2969.     ga_concat(&ga, (char_u *)"<CR>:if exists('*inputsave')|call inputsave()|endif|drop");
  2970.     vim_free(p);
  2971.     for (i = 0; i < filec; i++)
  2972.     {
  2973.     /* On Unix the shell has already expanded the wildcards, don't want to
  2974.      * do it again in the Vim server.  On MS-Windows only need to escape a
  2975.      * space. */
  2976.     p = vim_strsave_escaped((char_u *)filev[i],
  2977. #ifdef UNIX
  2978.         PATH_ESC_CHARS
  2979. #else
  2980.         (char_u *)" "
  2981. #endif
  2982.         );
  2983.     if (p == NULL)
  2984.     {
  2985.         vim_free(ga.ga_data);
  2986.         return NULL;
  2987.     }
  2988.     ga_concat(&ga, (char_u *)" ");
  2989.     ga_concat(&ga, p);
  2990.     vim_free(p);
  2991.     }
  2992.     /* The :drop commands goes to Insert mode when 'insertmode' is set, use
  2993.      * CTRL-\ CTRL-N again. */
  2994.     ga_concat(&ga, (char_u *)"|if exists('*inputrestore')|call inputrestore()|endif<CR>");
  2995.     ga_concat(&ga, (char_u *)"<C-\\><C-N>:cd -");
  2996.     if (sendReply)
  2997.     ga_concat(&ga, (char_u *)"<CR>:call SetupRemoteReplies()");
  2998.     if (inicmd != NULL)
  2999.     {
  3000.     ga_concat(&ga, (char_u *)"<CR>:");
  3001.     ga_concat(&ga, inicmd);
  3002.     }
  3003.     /* Bring the window to the foreground, goto Insert mode when 'im' set and
  3004.      * clear command line */
  3005.     ga_concat(&ga, (char_u *)"<CR>:call foreground()<CR>:if &im|starti|endif|echo<CR>");
  3006.     ga_append(&ga, NUL);
  3007.     return ga.ga_data;
  3008. }
  3009.  
  3010. /*
  3011.  * Replace termcodes such as <CR> and insert as key presses if there is room.
  3012.  */
  3013.     void
  3014. server_to_input_buf(str)
  3015.     char_u    *str;
  3016. {
  3017.     char_u      *ptr = NULL;
  3018.     char_u      *cpo_save = p_cpo;
  3019.  
  3020.     /* Set 'cpoptions' the way we want it.
  3021.      *    B set - backslashes are *not* treated specially
  3022.      *    k set - keycodes are *not* reverse-engineered
  3023.      *    < unset - <Key> sequences *are* interpreted
  3024.      *  The last parameter of replace_termcodes() is TRUE so that the <lt>
  3025.      *  sequence is recognised - needed for a real backslash.
  3026.      */
  3027.     p_cpo = (char_u *)"Bk";
  3028.     str = replace_termcodes((char_u *)str, &ptr, FALSE, TRUE);
  3029.     p_cpo = cpo_save;
  3030.  
  3031.     /* Can't use add_to_input_buf() here, we now have K_SPECIAL bytes.
  3032.      * First clear the typeahead buffer, there could be half a mapping there. */
  3033.     del_typebuf(typebuf.tb_len, 0);
  3034.     (void)ins_typebuf(str, REMAP_NONE, 0, TRUE, FALSE);
  3035.     vim_free((char_u *)ptr);
  3036.  
  3037.     /* Let input_available() know we inserted text in the typeahead buffer. */
  3038.     received_from_client = TRUE;
  3039. }
  3040.  
  3041. /*
  3042.  * Make our basic server name: use the specified "arg" if given, otherwise use
  3043.  * the tail of the command "cmd" we were started with.
  3044.  * Return the name in allocated memory.  This doesn't include a serial number.
  3045.  */
  3046.     static char_u *
  3047. serverMakeName(arg, cmd)
  3048.     char_u    *arg;
  3049.     char    *cmd;
  3050. {
  3051.     char_u *p;
  3052.  
  3053.     if (arg != NULL && *arg != NUL)
  3054.     p = vim_strsave_up(arg);
  3055.     else
  3056.     {
  3057.     p = vim_strsave_up(gettail((char_u *)cmd));
  3058.     /* Remove .exe or .bat from the name. */
  3059.     if (p != NULL && vim_strchr(p, '.') != NULL)
  3060.         *vim_strchr(p, '.') = NUL;
  3061.     }
  3062.     return p;
  3063. }
  3064. #endif /* FEAT_CLIENTSERVER */
  3065.  
  3066. /*
  3067.  * When FEAT_FKMAP is defined, also compile the Farsi source code.
  3068.  */
  3069. #if defined(FEAT_FKMAP) || defined(PROTO)
  3070. # include "farsi.c"
  3071. #endif
  3072.  
  3073. /*
  3074.  * When FEAT_ARABIC is defined, also compile the Arabic source code.
  3075.  */
  3076. #if defined(FEAT_ARABIC) || defined(PROTO)
  3077. # include "arabic.c"
  3078. #endif
  3079.