[BACK]Return to main.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / vim

Annotation of src/usr.bin/vim/main.c, Revision 1.1.1.1

1.1       downsj      1: /* $OpenBSD$   */
                      2: /* vi:set ts=4 sw=4:
                      3:  *
                      4:  * VIM - Vi IMproved       by Bram Moolenaar
                      5:  *
                      6:  * Do ":help uganda"  in Vim to read copying and usage conditions.
                      7:  * Do ":help credits" in Vim to see a list of people who contributed.
                      8:  */
                      9:
                     10: #define EXTERN
                     11: #include "vim.h"
                     12: #include "globals.h"
                     13: #include "proto.h"
                     14: #include "option.h"
                     15:
                     16: #ifdef SPAWNO
                     17: # include <spawno.h>           /* special MSDOS swapping library */
                     18: #endif
                     19:
                     20: static void usage __PARMS((int, char_u *));
                     21: static int stdout_notty = FALSE;           /* is stdout not a terminal? */
                     22:
                     23: /*
                     24:  * Types of usage message required.  These must match the array of error
                     25:  * messages in usage().
                     26:  */
                     27: #define USAGE_UNKNOWN_OPTION   0
                     28: #define USAGE_TOO_MANY_ARGS        1
                     29: #define USAGE_ARG_MISSING      2
                     30: #define USAGE_GARBAGE          3
                     31:
                     32:    static void
                     33: usage(n, str)
                     34:    int     n;
                     35:    char_u  *str;
                     36: {
                     37:    register int i;
                     38:    static char_u *(use[]) = {(char_u *)"[file ..]",
                     39:                            (char_u *)"-t tag",
                     40:                            (char_u *)"-e [errorfile]"};
                     41:    static char_u *(errors[]) =  {(char_u *)"Unknown option",
                     42:                                (char_u *)"Too many arguments",
                     43:                                (char_u *)"Argument missing after",
                     44:                                (char_u *)"Garbage after option",
                     45:                                };
                     46:
                     47: #if defined(UNIX) || defined(__EMX__)
                     48:    reset_signals();        /* kill us with CTRL-C here, if you like */
                     49: #endif
                     50:
                     51:    fprintf(stderr, longVersion);
                     52:    fprintf(stderr, "\n");
                     53:    fprintf(stderr, (char *)errors[n]);
                     54:    if (str != NULL)
                     55:        fprintf(stderr, ": \"%s\"", str);
                     56:    fprintf(stderr, "\nusage:");
                     57:    for (i = 0; ; ++i)
                     58:    {
                     59:        fprintf(stderr, " vim [options] ");
                     60:        fprintf(stderr, (char *)use[i]);
                     61:        if (i == (sizeof(use) / sizeof(char_u *)) - 1)
                     62:            break;
                     63:        fprintf(stderr, "\n   or:");
                     64:    }
                     65:
                     66:    fprintf(stderr, "\n\nOptions:\n");
                     67: #ifdef USE_GUI
                     68:    fprintf(stderr, "   -g\t\t\tRun using GUI\n");
                     69:    fprintf(stderr, "   -f\t\t\tForeground: Don't fork when starting GUI\n");
                     70: #endif
                     71:    fprintf(stderr, "   -R  or  -v\t\tReadonly mode (view mode)\n");
                     72:    fprintf(stderr, "   -b\t\t\tBinary mode\n");
                     73:    fprintf(stderr, "   -l\t\t\tLisp mode\n");
                     74:    fprintf(stderr, "   -n\t\t\tNo swap file, use memory only\n");
                     75:    fprintf(stderr, "   -r\t\t\tList swap files\n");
                     76:    fprintf(stderr, "   -r (with file name)\tRecover crashed session\n");
                     77:    fprintf(stderr, "   -L\t\t\tSame as -r\n");
                     78: #ifdef AMIGA
                     79:    fprintf(stderr, "   -x\t\t\tDon't use newcli to open window\n");
                     80:    fprintf(stderr, "   -d <device>\t\tUse <device> for I/O\n");
                     81: #endif
                     82: #ifdef RIGHTLEFT
                     83:    fprintf(stderr, "   -H\t\t\tstart in Hebrew mode\n");
                     84: #endif
                     85:    fprintf(stderr, "   -T <terminal>\tSet terminal type to <terminal>\n");
                     86:    fprintf(stderr, "   -o[N]\t\tOpen N windows (default: one for each file)\n");
                     87:    fprintf(stderr, "   +\t\t\tStart at end of file\n");
                     88:    fprintf(stderr, "   +<lnum>\t\tStart at line <lnum>\n");
                     89:    fprintf(stderr, "   -c <command>\t\tExecute <command> first\n");
                     90:    fprintf(stderr, "   -s <scriptin>\tRead commands from script file <scriptin>\n");
                     91:    fprintf(stderr, "   -w <scriptout>\tAppend commands to script file <scriptout>\n");
                     92:    fprintf(stderr, "   -W <scriptout>\tWrite commands to script file <scriptout>\n");
                     93:    fprintf(stderr, "   -u <vimrc>\t\tUse <vimrc> instead of any .vimrc\n");
                     94:    fprintf(stderr, "   -i <viminfo>\t\tUse <viminfo> instead of .viminfo\n");
                     95:    fprintf(stderr, "   --\t\t\tEnd of options\n");
                     96:
                     97: #ifdef USE_GUI_X11
                     98: # ifdef USE_GUI_MOTIF
                     99:    fprintf(stderr, "\nOptions recognised by gvim (Motif version):\n");
                    100: # else
                    101: #  ifdef USE_GUI_ATHENA
                    102:    fprintf(stderr, "\nOptions recognised by gvim (Athena version):\n");
                    103: #  endif /* USE_GUI_ATHENA */
                    104: # endif /* USE_GUI_MOTIF */
                    105:    fprintf(stderr, "   -display <display>\tRun vim on <display>\n");
                    106:    fprintf(stderr, "   -iconic\t\tStart vim iconified\n");
                    107: # if 0
                    108:    fprintf(stderr, "   -name <name>\t\tUse resource as if vim was <name>\n");
                    109:    fprintf(stderr, "\t\t\t  (Unimplemented)\n");
                    110: # endif
                    111:    fprintf(stderr, "   -background <color>\tUse <color> for the background (also: -bg)\n");
                    112:    fprintf(stderr, "   -foreground <color>\tUse <color> for normal text (also: -fg)\n");
                    113:    fprintf(stderr, "   -bold <color>\tUse <color> for bold text\n");
                    114:    fprintf(stderr, "   -italic <color>\tUse <color> for italic text\n");
                    115:    fprintf(stderr, "   -underline <color>\tUse <color> for underlined text (also: -ul)\n");
                    116:    fprintf(stderr, "   -cursor <color>\tUse <color> for cursor\n");
                    117:    fprintf(stderr, "   -font <font>\t\tUse <font> for normal text (also: -fn)\n");
                    118:    fprintf(stderr, "   -boldfont <font>\tUse <font> for bold text\n");
                    119:    fprintf(stderr, "   -italicfont <font>\tUse <font> for italic text\n");
                    120:    fprintf(stderr, "   -geometry <geom>\tUse <geom> for initial geometry (also: -geom)\n");
                    121:    fprintf(stderr, "   -borderwidth <width>\tUse a border width of <width> (also: -bw)\n");
                    122:    fprintf(stderr, "   -scrollbarwidth <width>\tUse a scrollbar width of <width> (also: -sw)\n");
                    123:    fprintf(stderr, "   -menuheight <height>\tUse a menu bar height of <height> (also: -mh)\n");
                    124:    fprintf(stderr, "   -reverse\t\tUse reverse video (also: -rv)\n");
                    125:    fprintf(stderr, "   +reverse\t\tDon't use reverse video (also: +rv)\n");
                    126:    fprintf(stderr, "   -xrm <resource>\tSet the specified resource\n");
                    127: #endif /* USE_GUI_X11 */
                    128:
                    129:    mch_windexit(1);
                    130: }
                    131:
                    132: #ifdef HAVE_LOCALE_H
                    133: # include <locale.h>
                    134: #endif
                    135:
                    136:    void
                    137: main(argc, argv)
                    138:    int             argc;
                    139:    char          **argv;
                    140: {
                    141:    char_u         *initstr;        /* init string from the environment */
                    142:    char_u         *term = NULL;    /* specified terminal name */
                    143:    char_u         *fname = NULL;   /* file name from command line */
                    144:    char_u         *command = NULL; /* command from + or -c option */
                    145:    char_u         *tagname = NULL; /* tag from -t option */
                    146:    char_u         *use_vimrc = NULL;   /* vimrc from -u option */
                    147:    int             c;
                    148:    int             doqf = 0;
                    149:    int             i;
                    150:    int             bin_mode = FALSE;       /* -b option used */
                    151:    int             vi_mode = FALSE;        /* run as vi */
                    152:    int             window_count = 1;       /* number of windows to use */
                    153:    int             arg_idx = 0;            /* index for arg_files[] */
                    154:    int             check_version = FALSE;  /* check .vimrc version number */
                    155:    int             argv_idx;               /* index in argv[n][] */
                    156:
                    157: #if defined(MSDOS) || defined(WIN32) || defined(OS2)
                    158:    static struct initmap
                    159:    {
                    160:        char_u      *arg;
                    161:        int         mode;
                    162:    } initmappings[] =
                    163:    {
                    164:        /* normal and visual mode */
                    165: #ifdef MSDOS
                    166:        {(char_u *)"\316w H", NORMAL+VISUAL},       /* CTRL-HOME is 'H' */
                    167:        {(char_u *)"\316u L", NORMAL+VISUAL},       /* CTRL-END is 'L' */
                    168:        {(char_u *)"\316\204 1G", NORMAL+VISUAL},   /* CTRL-PageUp is '1G' */
                    169:        {(char_u *)"\316v G", NORMAL+VISUAL},       /* CTRL-PageDown is 'G' */
                    170: #else /* WIN32 */
                    171:        /* Use the Windows (CUA) keybindings */
                    172:        {(char_u *)"\316w 1G", NORMAL+VISUAL},      /* CTRL-HOME is '1G' */
                    173:        {(char_u *)"\316u G$", NORMAL+VISUAL},      /* CTRL-END is 'G$' */
                    174:        {(char_u *)"\316\204 H", NORMAL+VISUAL},    /* CTRL-PageUp is 'H' */
                    175:        {(char_u *)"\316v L$", NORMAL+VISUAL},      /* CTRL-PageDown is 'L$' */
                    176:        {(char_u *)"\316s B", NORMAL+VISUAL},       /* CTRL-Left is 'B' */
                    177:        {(char_u *)"\316t W", NORMAL+VISUAL},       /* CTRL-Right is 'W' */
                    178: #endif /* WIN32 */
                    179:
                    180:        /* insert mode */
                    181: #ifdef MSDOS
                    182:        {(char_u *)"\316w \017H", INSERT},          /* CTRL-HOME is '^OH' */
                    183:        {(char_u *)"\316u \017L", INSERT},          /* CTRL-END is '^OL' */
                    184:        {(char_u *)"\316\204 \017\061G", INSERT},   /* CTRL-PageUp is '^O1G' */
                    185:        {(char_u *)"\316v \017G", INSERT},          /* CTRL-PageDown is '^OG' */
                    186: #else /* WIN32 */
                    187:        /* Use the Windows (CUA) keybindings */
                    188:        {(char_u *)"\316w \017\061G", INSERT},      /* CTRL-HOME is '^O1G' */
                    189:        {(char_u *)"\316u \017G\017$", INSERT},     /* CTRL-END is '^OG^O$' */
                    190:        {(char_u *)"\316\204 \017H",INSERT},        /* CTRL-PageUp is '^OH'*/
                    191:        {(char_u *)"\316v \017L\017$", INSERT},     /* CTRL-PageDown ='^OL^O$'*/
                    192:        {(char_u *)"\316s \017B", INSERT},          /* CTRL-Left is '^OB' */
                    193:        {(char_u *)"\316t \017W", INSERT},          /* CTRL-Right is '^OW' */
                    194: #endif /* WIN32 */
                    195:    };
                    196: #endif
                    197:
                    198: #ifdef __EMX__
                    199:    _wildcard(&argc, &argv);
                    200: #endif
                    201:
                    202: #ifdef HAVE_LOCALE_H
                    203:    setlocale(LC_ALL, "");      /* for ctype() and the like */
                    204: #endif
                    205:
                    206: #ifdef USE_GUI
                    207:    gui_prepare(&argc, argv);   /* Prepare for possibly starting GUI sometime */
                    208: #endif
                    209:
                    210: /*
                    211:  * Check if we have an interactive window.
                    212:  * On the Amiga: If there is no window, we open one with a newcli command
                    213:  * (needed for :! to * work). mch_check_win() will also handle the -d argument.
                    214:  */
                    215:    stdout_notty = (mch_check_win(argc, argv) == FAIL);
                    216:
                    217: /*
                    218:  * allocate the first window and buffer. Can't do anything without it
                    219:  */
                    220:    if ((curwin = win_alloc(NULL)) == NULL ||
                    221:                        (curbuf = buflist_new(NULL, NULL, 1L, FALSE)) == NULL)
                    222:        mch_windexit(0);
                    223:    curwin->w_buffer = curbuf;
                    224:    screen_start();                 /* don't know where cursor is yet */
                    225:
                    226: /*
                    227:  * Allocate space for the generic buffers (needed for set_init_1()).
                    228:  */
                    229:    if ((IObuff = alloc(IOSIZE)) == NULL ||
                    230:                            (NameBuff = alloc(MAXPATHL)) == NULL)
                    231:        mch_windexit(0);
                    232:
                    233: /*
                    234:  * Set the default values for the options.
                    235:  * First find out the home directory, needed to expand "~" in options.
                    236:  */
                    237:    init_homedir();             /* find real value of $HOME */
                    238:    set_init_1();
                    239:
                    240: /*
                    241:  * If the executable is called "view" we start in readonly mode.
                    242:  */
                    243:    if (STRCMP(gettail((char_u *)argv[0]), (char_u *)"view") == 0)
                    244:    {
                    245:        readonlymode = TRUE;
                    246:        curbuf->b_p_ro = TRUE;
                    247:        if (p_uc)                   /* if we are doing any updating.. */
                    248:            p_uc = 10000;           /* ..don't update very often */
                    249:    }
                    250:
                    251: /*
                    252:  * If the executable is called "gvim" we run the GUI version.
                    253:  */
                    254:    if (STRCMP(gettail((char_u *)argv[0]), (char_u *)"gvim") == 0)
                    255:    {
                    256: #ifdef USE_GUI
                    257:        gui.starting = TRUE;
                    258: #else
                    259:        fprintf(stderr, (char *)e_nogvim);
                    260:        mch_windexit(2);
                    261: #endif
                    262:    }
                    263:
                    264: /*
                    265:  * If the executable is called "vi" we switch to compat mode.
                    266:  */
                    267:    if (STRCMP(gettail((char_u *)argv[0]), (char_u *)"vi") == 0)
                    268:    {
                    269:        vi_mode = TRUE;
                    270:    }
                    271:
                    272:    ++argv;
                    273:    /*
                    274:     * Process the command line arguments
                    275:     *      '+{command}'    execute command
                    276:     *      '-b'            binary
                    277:     *      '-c {command}'  execute command
                    278:     *      '-d {device}'   device (for Amiga)
                    279:     *      '-f'            Don't fork when starging GUI. (if USE_GUI defined)
                    280:     *      '-g'            Run with GUI. (if USE_GUI defined)
                    281:     *      '-H'            Start in right-left mode
                    282:     *      '-i viminfo'    use instead of p_viminfo
                    283:     *      '-n'            no .vim file
                    284:     *      '-o[N]'         open N windows (default: number of files)
                    285:     *      '-r'            recovery mode
                    286:     *      '-L'            recovery mode
                    287:     *      '-s scriptin'   read from script file
                    288:     *      '-T terminal'   terminal name
                    289:     *      '-u vimrc'      read initializations from a file
                    290:     *      '-v'            view or Readonly mode
                    291:     *      '-R'            view or Readonly mode
                    292:     *      '-w scriptout'  write to script file (append)
                    293:     *      '-W scriptout'  write to script file (overwrite)
                    294:     *      '-x'            open window directly, not with newcli
                    295:     */
                    296:    argv_idx = 1;           /* active option letter is argv[0][argv_idx] */
                    297:
                    298:    while (argc > 1 && ((c = argv[0][0]) == '+' || (c == '-' &&
                    299:                                   vim_strchr((char_u *)"bcdfgHilLnorRsTuvwWx",
                    300:                                             c = argv[0][argv_idx]) != NULL)))
                    301:    {
                    302:        ++argv_idx;         /* advance to next option letter by default */
                    303:        switch (c)
                    304:        {
                    305:        case '+':           /* + or +{number} or +/{pat} or +{command} */
                    306:            argv_idx = -1;          /* skip to next argument */
                    307:            if (argv[0][1] == NUL)
                    308:                command = (char_u *)"$";
                    309:            else
                    310:                command = (char_u *)&(argv[0][1]);
                    311:            break;
                    312:
                    313:        case 'b':
                    314:            bin_mode = TRUE;        /* postpone to after reading .exrc files */
                    315:            break;
                    316:
                    317: #ifdef USE_GUI
                    318:        case 'f':
                    319:            gui.dofork = FALSE;     /* don't fork() when starting GUI */
                    320:            break;
                    321: #endif
                    322:
                    323:        case 'g':
                    324: #ifdef USE_GUI
                    325:            gui.starting = TRUE;    /* start GUI a bit later */
                    326: #else
                    327:            fprintf(stderr, (char *)e_nogvim);
                    328:            mch_windexit(2);
                    329: #endif
                    330:            break;
                    331:
                    332:        case 'H':               /* start in Hebrew mode: rl + hkmap set */
                    333: #ifdef RIGHTLEFT
                    334:            curwin->w_p_rl = p_hkmap = TRUE;
                    335: #else
                    336:            fprintf(stderr, (char *)e_nohebrew);
                    337:            mch_windexit(2);
                    338: #endif
                    339:            break;
                    340:
                    341:        case 'l':           /* -l: lisp mode, 'lisp' and 'showmatch' on */
                    342:            curbuf->b_p_lisp = TRUE;
                    343:            p_sm = TRUE;
                    344:            break;
                    345:
                    346:        case 'n':
                    347:            p_uc = 0;
                    348:            break;
                    349:
                    350:        case 'o':
                    351:            window_count = 0;       /* default: open window for each file */
                    352:            if (isdigit(argv[0][argv_idx]))
                    353:            {
                    354:                window_count = atoi(&(argv[0][argv_idx]));
                    355:                while (isdigit(argv[0][argv_idx]))
                    356:                    ++argv_idx;
                    357:            }
                    358:            break;
                    359:
                    360:        case 'r':
                    361:        case 'L':
                    362:            recoverymode = 1;
                    363:            break;
                    364:
                    365:        case 'v':
                    366:        case 'R':
                    367:            readonlymode = TRUE;
                    368:            curbuf->b_p_ro = TRUE;
                    369:            if (p_uc)                   /* if we are doing any updating.. */
                    370:                p_uc = 10000;           /* ..don't update very often */
                    371:            break;
                    372:
                    373:        case 'x':
                    374:            break;  /* This is ignored as it is handled in mch_check_win() */
                    375:
                    376:
                    377:        case 'w':
                    378:            if (isdigit(argv[0][argv_idx])) /* -w{number}; set window height */
                    379:            {
                    380:                argv_idx = -1;
                    381:                break;                      /* not implemented, ignored */
                    382:            }
                    383:            /* FALLTHROUGH */
                    384:
                    385:        default:    /* options with argument */
                    386:            /*
                    387:             * Check there's no garbage immediately after the option letter.
                    388:             */
                    389:            if (argv[0][argv_idx] != NUL)
                    390:                usage(USAGE_GARBAGE, (char_u *)argv[0]);
                    391:
                    392:            --argc;
                    393:            if (argc < 2)
                    394:                usage(USAGE_ARG_MISSING, (char_u *)argv[0]);
                    395:            ++argv;
                    396:            argv_idx = -1;
                    397:
                    398:            switch (c)
                    399:            {
                    400:            case 'c':           /* -c {command} */
                    401:                command = (char_u *)argv[0];
                    402:                break;
                    403:
                    404:        /*  case 'd':   This is ignored as it is handled in mch_check_win() */
                    405:
                    406:            case 'i':           /* -i {viminfo} */
                    407:                use_viminfo = (char_u *)argv[0];
                    408:                break;
                    409:
                    410:            case 's':           /* -s {scriptin} */
                    411:                if (scriptin[0] != NULL)
                    412:                {
                    413:                    fprintf(stderr,
                    414:                            "Attempt to open script file again: \"%s %s\"\n",
                    415:                            argv[-1], argv[0]);
                    416:                    mch_windexit(2);
                    417:                }
                    418:                if ((scriptin[0] = fopen(argv[0], READBIN)) == NULL)
                    419:                {
                    420:                    fprintf(stderr, "Cannot open \"%s\" for reading\n", argv[0]);
                    421:                    mch_windexit(2);
                    422:                }
                    423:                break;
                    424:
                    425: /*
                    426:  * The -T term option is always available and when HAVE_TERMLIB is supported
                    427:  * it overrides the environment variable TERM.
                    428:  */
                    429:            case 'T':           /* -T {terminal} */
                    430:                term = (char_u *)argv[0];
                    431:                break;
                    432:
                    433:            case 'u':           /* -u {vimrc} */
                    434:                use_vimrc = (char_u *)argv[0];
                    435:                break;
                    436:
                    437:            case 'w':           /* -w {scriptout} (append) */
                    438:            case 'W':           /* -W {scriptout} (overwrite) */
                    439:                if (scriptout != NULL)
                    440:                {
                    441:                    fprintf(stderr,
                    442:                            "Attempt to open script file again: \"%s %s\"\n",
                    443:                            argv[-1], argv[0]);
                    444:                    mch_windexit(2);
                    445:                }
                    446:                if ((scriptout = fopen(argv[0],
                    447:                                    c == 'w' ? APPENDBIN : WRITEBIN)) == NULL)
                    448:                {
                    449:                    fprintf(stderr, "cannot open \"%s\" for output\n", argv[0]);
                    450:                    mch_windexit(2);
                    451:                }
                    452:                break;
                    453:            }
                    454:        }
                    455:        /*
                    456:         * If there are no more letters after the current "-", go to next
                    457:         * argument.  argv_idx is set to -1 when the current argument is to be
                    458:         * skipped.
                    459:         */
                    460:        if (argv_idx <= 0 || argv[0][argv_idx] == NUL)
                    461:        {
                    462:            --argc;
                    463:            ++argv;
                    464:            argv_idx = 1;
                    465:        }
                    466:    }
                    467:
                    468:    /* note that we may use mch_windexit() before mch_windinit()! */
                    469:    mch_windinit();             /* inits Rows and Columns */
                    470: /*
                    471:  * Set the default values for the options that use Rows and Columns.
                    472:  */
                    473:    set_init_2();
                    474:
                    475:    firstwin->w_height = Rows - 1;
                    476:    cmdline_row = Rows - 1;
                    477:
                    478:    /*
                    479:     * Process the other command line arguments.
                    480:     * -e[errorfile]    quickfix mode
                    481:     * -t[tagname]      jump to tag
                    482:     * [--] [file ..]   file names
                    483:     */
                    484:    if (argc > 1)
                    485:    {
                    486:        if (argv[0][0] == '-' && (argv[0][1] != '-' || argv[0][2] != NUL))
                    487:        {
                    488:            switch (argv[0][1])
                    489:            {
                    490:            case 'e':           /* -e QuickFix mode */
                    491:                switch (argc)
                    492:                {
                    493:                    case 2:
                    494:                            if (argv[0][2]) /* -eerrorfile */
                    495:                                p_ef = (char_u *)argv[0] + 2;
                    496:                            break;              /* -e */
                    497:
                    498:                    case 3:                 /* -e errorfile */
                    499:                            if (argv[0][2] != NUL)
                    500:                                usage(USAGE_GARBAGE, (char_u *)argv[0]);
                    501:                            ++argv;
                    502:                            p_ef = (char_u *)argv[0];
                    503:                            break;
                    504:
                    505:                    default:                /* argc > 3: too many arguments */
                    506:                            usage(USAGE_TOO_MANY_ARGS, NULL);
                    507:                }
                    508:                doqf = 1;
                    509:                break;
                    510:
                    511:            case 't':           /* -t tag  or -ttag */
                    512:                switch (argc)
                    513:                {
                    514:                    case 2:
                    515:                            if (argv[0][2])     /* -ttag */
                    516:                            {
                    517:                                tagname = (char_u *)argv[0] + 2;
                    518:                                break;
                    519:                            }
                    520:                            usage(USAGE_ARG_MISSING, (char_u *)argv[0]);
                    521:                            break;
                    522:
                    523:                    case 3:                     /* -t tag */
                    524:                            if (argv[0][2] != NUL)  /* also -ttag?! */
                    525:                                usage(USAGE_GARBAGE, (char_u *)argv[0]);
                    526:                            ++argv;
                    527:                            tagname = (char_u *)argv[0];
                    528:                            break;
                    529:
                    530:                    default:                /* argc > 3: too many arguments */
                    531:                            usage(USAGE_TOO_MANY_ARGS, NULL);
                    532:                }
                    533:                break;
                    534:
                    535:            default:
                    536:                usage(USAGE_UNKNOWN_OPTION, (char_u *)argv[0]);
                    537:            }
                    538:        }
                    539:        else                /* must be a file name */
                    540:        {
                    541:            /*
                    542:             * Skip a single "--" argument, used in front of a file name that
                    543:             * starts with '-'.
                    544:             */
                    545:            if (argc > 2 && STRCMP(argv[0], "--") == 0)
                    546:            {
                    547:                ++argv;
                    548:                --argc;
                    549:            }
                    550:
                    551: #if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
                    552:            if (ExpandWildCards(argc - 1, (char_u **)argv, &arg_count,
                    553:                    &arg_files, TRUE, TRUE) == OK && arg_count != 0)
                    554:            {
                    555:                fname = arg_files[0];
                    556:                arg_exp = TRUE;
                    557:            }
                    558: #else
                    559:            arg_files = (char_u **)argv;
                    560:            arg_count = argc - 1;
                    561:            fname = (char_u *)argv[0];
                    562: #endif
                    563:            if (arg_count > 1)
                    564:            {
                    565:                printf("%d files to edit\n", arg_count);
                    566:                screen_start();         /* don't know where cursor is now */
                    567:            }
                    568:        }
                    569:    }
                    570:
                    571:    RedrawingDisabled = TRUE;
                    572:
                    573:    /*
                    574:     * When listing swap file names, don't do cursor positioning et. al.
                    575:     */
                    576:    if (recoverymode && fname == NULL)
                    577:        full_screen = FALSE;
                    578:
                    579: #ifdef USE_GUI
                    580:    /*
                    581:     * We don't want to open the GUI window until after we've read .vimrc,
                    582:     * otherwise we don't know what font we will use, and hence we don't know
                    583:     * what size the window should be.  So if there are errors in the .vimrc
                    584:     * file, they will have to go to the terminal -- webb
                    585:     */
                    586:    if (gui.starting)
                    587:        full_screen = FALSE;
                    588: #endif
                    589:
                    590:    /*
                    591:     * Now print a warning if stdout is not a terminal.
                    592:     */
                    593:    if (full_screen && (stdout_notty || mch_check_input() == FAIL))
                    594:    {
                    595:        if (stdout_notty)
                    596:            fprintf(stderr, "Vim: Warning: Output is not to a terminal\n");
                    597:        if (mch_check_input() == FAIL)
                    598:            fprintf(stderr, "Vim: Warning: Input is not from a terminal\n");
                    599:        mch_delay(2000L, TRUE);
                    600:        screen_start();         /* don't know where cursor is now */
                    601:    }
                    602:
                    603:    curbuf->b_nwindows = 1;     /* there is one window */
                    604:    win_init(curwin);           /* init current window */
                    605:    init_yank();                /* init yank buffers */
                    606:    if (full_screen)
                    607:        termcapinit(term);      /* set terminal name and get terminal
                    608:                                   capabilities */
                    609:    screenclear();              /* clear screen (just inits screen structures,
                    610:                                    because starting is TRUE) */
                    611:
                    612:    if (full_screen)
                    613:        msg_start();        /* in case a mapping or error message is printed */
                    614:    msg_scroll = TRUE;
                    615:    no_wait_return = TRUE;
                    616:
                    617: #if defined(MSDOS) || defined(WIN32) || defined(OS2)
                    618: /*
                    619:  * Default mapping for some often used keys.
                    620:  * Need to put string in allocated memory, because do_map() will modify it.
                    621:  */
                    622:    for (i = 0; i < sizeof(initmappings) / sizeof(struct initmap); ++i)
                    623:    {
                    624:        initstr = strsave(initmappings[i].arg);
                    625:        if (initstr != NULL)
                    626:        {
                    627:            do_map(0, initstr, initmappings[i].mode);
                    628:            vim_free(initstr);
                    629:        }
                    630:    }
                    631: #endif
                    632:
                    633: /*
                    634:  * If -u option give, use only the initializations from that file and nothing
                    635:  * else.
                    636:  */
                    637:    if (use_vimrc != NULL)
                    638:    {
                    639:        if (STRCMP(use_vimrc, "NONE") != 0)
                    640:        {
                    641:            if (do_source(use_vimrc, FALSE) == OK)
                    642:                check_version = TRUE;
                    643:            else
                    644:                EMSG2("Cannot read from \"%s\"", use_vimrc);
                    645:        }
                    646:    }
                    647:    else
                    648:    {
                    649:
                    650:    /*
                    651:     * get system wide defaults (for unix)
                    652:     */
                    653: #if defined(HAVE_CONFIG_H) || defined(OS2)
                    654:        if (do_source(((vi_mode == TRUE) ? sys_compatrc_fname
                    655:                       : sys_vimrc_fname), TRUE) == OK)
                    656:            check_version = TRUE;
                    657: #endif
                    658:
                    659:    /*
                    660:     * Try to read initialization commands from the following places:
                    661:     * - environment variable VIMINIT
                    662:     * - user vimrc file (s:.vimrc for Amiga, ~/.vimrc for Unix)
                    663:     * - environment variable EXINIT
                    664:     * - user exrc file (s:.exrc for Amiga, ~/.exrc for Unix)
                    665:     * The first that exists is used, the rest is ignored.
                    666:     */
                    667:        if ((initstr = vim_getenv((char_u *)"VIMINIT")) != NULL &&
                    668:                                                        *initstr != NUL)
                    669:        {
                    670:            sourcing_name = (char_u *)"VIMINIT";
                    671:            do_cmdline(initstr, TRUE, TRUE);
                    672:            sourcing_name = NULL;
                    673:        }
                    674:        else if (do_source((char_u *)USR_VIMRC_FILE, TRUE) == FAIL)
                    675:        {
                    676:            if ((initstr = vim_getenv((char_u *)"EXINIT")) != NULL)
                    677:            {
                    678:                sourcing_name = (char_u *)"EXINIT";
                    679:                do_cmdline(initstr, TRUE, TRUE);
                    680:                sourcing_name = NULL;
                    681:            }
                    682:            else
                    683:                (void)do_source((char_u *)USR_EXRC_FILE, FALSE);
                    684:        }
                    685:        else
                    686:            check_version = TRUE;
                    687:
                    688:    /*
                    689:     * Read initialization commands from ".vimrc" or ".exrc" in current
                    690:     * directory.  This is only done if the 'exrc' option is set.
                    691:     * Because of security reasons we disallow shell and write commands now,
                    692:     * except for unix if the file is owned by the user or 'secure' option has
                    693:     * been reset in environmet of global ".exrc" or ".vimrc".
                    694:     * Only do this if VIMRC_FILE is not the same as USR_VIMRC_FILE or
                    695:     * sys_vimrc_fname.
                    696:     */
                    697:        if (p_exrc)
                    698:        {
                    699: #ifdef UNIX
                    700:            {
                    701:                struct stat s;
                    702:
                    703:                /* if ".vimrc" file is not owned by user, set 'secure' mode */
                    704:                if (stat(VIMRC_FILE, &s) || s.st_uid != getuid())
                    705:                    secure = p_secure;
                    706:            }
                    707: #else
                    708:            secure = p_secure;
                    709: #endif
                    710:
                    711:            i = FAIL;
                    712:            if (fullpathcmp((char_u *)USR_VIMRC_FILE,
                    713:                                             (char_u *)VIMRC_FILE) != FPC_SAME
                    714: #if defined(HAVE_CONFIG_H) || defined(OS2)
                    715:                    && fullpathcmp(((vi_mode == TRUE) ? sys_compatrc_fname : sys_vimrc_fname),
                    716:                                             (char_u *)VIMRC_FILE) != FPC_SAME
                    717: #endif
                    718:                    )
                    719:                i = do_source((char_u *)VIMRC_FILE, TRUE);
                    720: #ifdef UNIX
                    721:            if (i == FAIL)
                    722:            {
                    723:                struct stat s;
                    724:
                    725:                    /* if ".exrc" is not owned by user set 'secure' mode */
                    726:                if (stat(EXRC_FILE, &s) || s.st_uid != getuid())
                    727:                    secure = p_secure;
                    728:                else
                    729:                    secure = 0;
                    730:            }
                    731:            else
                    732:                check_version = TRUE;
                    733: #endif
                    734:            if (i == FAIL && fullpathcmp((char_u *)USR_EXRC_FILE,
                    735:                                             (char_u *)EXRC_FILE) != FPC_SAME)
                    736:                (void)do_source((char_u *)EXRC_FILE, FALSE);
                    737:        }
                    738:    }
                    739:
                    740:    /*
                    741:     * Recovery mode without a file name: List swap files.
                    742:     * This uses the 'dir' option, therefore it must be after the
                    743:     * initializations.
                    744:     */
                    745:    if (recoverymode && fname == NULL)
                    746:    {
                    747:        recover_names(NULL, TRUE, 0);
                    748:        mch_windexit(0);
                    749:    }
                    750:
                    751:    /*
                    752:     * Set a few option defaults after reading .vimrc files:
                    753:     * 'title' and 'icon', Unix: 'shellpipe' and 'shellredir'.
                    754:     */
                    755:    set_init_3();
                    756:
                    757: #ifdef USE_GUI
                    758:    if (gui.starting)
                    759:    {
                    760:        gui_start();
                    761:        gui.starting = FALSE;
                    762:        full_screen = TRUE;
                    763:    }
                    764: #endif
                    765:
                    766:    /*
                    767:     * If we read a .vimrc but it does not contain a "version 4.0" command,
                    768:     * give the user a pointer to the help for the new version.
                    769:     */
                    770:    if (check_version && found_version == 0)
                    771:    {
                    772:        MSG("This is Vim version 4.0.");
                    773:        MSG("No \":version 4.0\" command found in any .vimrc.");
                    774:        MSG("Use \":help version\" for info about this new version.");
                    775:    }
                    776:
                    777: #ifdef VIMINFO
                    778: /*
                    779:  * Read in registers, history etc, but not marks, from the viminfo file
                    780:  */
                    781:    if (*p_viminfo != NUL)
                    782:        read_viminfo(NULL, TRUE, FALSE, FALSE);
                    783: #endif /* VIMINFO */
                    784:
                    785: #ifdef SPAWNO          /* special MSDOS swapping library */
                    786:    init_SPAWNO("", SWAP_ANY);
                    787: #endif
                    788:
                    789:    if (bin_mode)                   /* -b option used */
                    790:    {
                    791:        set_options_bin(curbuf->b_p_bin, 1);
                    792:        curbuf->b_p_bin = 1;        /* binary file I/O */
                    793:    }
                    794:
                    795:    /* Don't set the file name if there was a command in .vimrc that already
                    796:     * loaded the file */
                    797:    if (curbuf->b_filename == NULL)
                    798:    {
                    799:        (void)setfname(fname, NULL, TRUE);  /* includes maketitle() */
                    800:        ++arg_idx;                          /* used first argument name */
                    801:    }
                    802:
                    803:    if (window_count == 0)
                    804:        window_count = arg_count;
                    805:    if (window_count > 1)
                    806:    {
                    807:        /* Don't change the windows if there was a command in .vimrc that
                    808:         * already split some windows */
                    809:        if (firstwin->w_next == NULL)
                    810:            window_count = make_windows(window_count);
                    811:        else
                    812:            window_count = win_count();
                    813:    }
                    814:    else
                    815:        window_count = 1;
                    816:
                    817: /*
                    818:  * "-e errorfile": Load the error file now.
                    819:  * If the error file can't be read, exit before doing anything else.
                    820:  */
                    821:    if (doqf && qf_init() == FAIL)      /* if reading error file fails: exit */
                    822:        mch_windexit(3);
                    823:
                    824: /*
                    825:  * Start putting things on the screen.
                    826:  * Scroll screen down before drawing over it
                    827:  * Clear screen now, so file message will not be cleared.
                    828:  */
                    829:    starting = FALSE;
                    830:    no_wait_return = FALSE;
                    831:    msg_scroll = FALSE;
                    832: #ifdef USE_GUI
                    833:    /*
                    834:     * This seems to be required to make callbacks to be called now, instead
                    835:     * of after things have been put on the screen, which then may be deleted
                    836:     * when getting a resize callback.
                    837:     */
                    838:    if (gui.in_use)
                    839:        gui_mch_wait_for_chars(50);
                    840: #endif
                    841:
                    842: /*
                    843:  * When done something that is not allowed or error message call wait_return.
                    844:  * This must be done before starttermcap(), because it may switch to another
                    845:  * screen. It must be done after settmode(1), because we want to react on a
                    846:  * single key stroke.
                    847:  * Call settmode and starttermcap here, so the T_KS and T_TI may be defined
                    848:  * by termcapinit and redifined in .exrc.
                    849:  */
                    850:    settmode(1);
                    851:    if (secure == 2 || need_wait_return || msg_didany)
                    852:        wait_return(TRUE);
                    853:
                    854:    starttermcap();         /* start termcap if not done by wait_return() */
                    855: #ifdef USE_MOUSE
                    856:    setmouse();                         /* may start using the mouse */
                    857: #endif
                    858:    if (scroll_region)
                    859:        scroll_region_reset();          /* In case Rows changed */
                    860:
                    861:    secure = 0;
                    862:
                    863:    scroll_start();
                    864:    screenclear();                      /* clear screen */
                    865:
                    866:    no_wait_return = TRUE;
                    867:
                    868:    if (recoverymode)                   /* do recover */
                    869:    {
                    870:        msg_scroll = TRUE;              /* scroll message up */
                    871:        ml_recover();
                    872:        msg_scroll = FALSE;
                    873:        if (curbuf->b_ml.ml_mfp == NULL) /* failed */
                    874:            getout(1);
                    875: #ifdef AUTOCMD
                    876:        apply_autocmds(EVENT_BUFENTER, NULL, NULL);
                    877: #endif
                    878:        do_modelines();                 /* do modelines */
                    879:    }
                    880:    /* Only read the file if there is none for the current buffer, a command
                    881:     * in the .vimrc might have loaded a file */
                    882:    else if (curbuf->b_ml.ml_mfp == NULL)
                    883:        (void)open_buffer();            /* create memfile and read file */
                    884:
                    885:    setpcmark();
                    886:
                    887:    /*
                    888:     * When started with "-e errorfile" jump to first error now.
                    889:     */
                    890:    if (doqf)
                    891:        qf_jump(0, 0);
                    892:
                    893:    /*
                    894:     * If opened more than one window, start editing files in the other windows.
                    895:     * Make_windows() has already opened the windows.
                    896:     */
                    897:    for (i = 1; i < window_count; ++i)
                    898:    {
                    899:        if (curwin->w_next == NULL)         /* just checking */
                    900:            break;
                    901:        win_enter(curwin->w_next, FALSE);
                    902:
                    903:        /* Only open the file if there is no file in this window yet (that can
                    904:         * happen when .vimrc contains ":sall") */
                    905:        if (curbuf == firstwin->w_buffer || curbuf->b_filename == NULL)
                    906:        {
                    907:            curwin->w_arg_idx = arg_idx;
                    908:            /* edit file from arg list, if there is one */
                    909:            (void)do_ecmd(0, arg_idx < arg_count ? arg_files[arg_idx] : NULL,
                    910:                                        NULL, NULL, TRUE, (linenr_t)1, FALSE);
                    911:            if (arg_idx == arg_count - 1)
                    912:                arg_had_last = TRUE;
                    913:            ++arg_idx;
                    914:        }
                    915:        mch_breakcheck();
                    916:        if (got_int)
                    917:        {
                    918:            (void)vgetc();      /* only break the file loading, not the rest */
                    919:            break;
                    920:        }
                    921:    }
                    922:    win_enter(firstwin, FALSE);             /* back to first window */
                    923:    if (window_count > 1)
                    924:        win_equal(curwin, FALSE);           /* adjust heights */
                    925:
                    926:    /*
                    927:     * If there are more file names in the argument list than windows,
                    928:     * put the rest of the names in the buffer list.
                    929:     */
                    930:    while (arg_idx < arg_count)
                    931:        (void)buflist_add(arg_files[arg_idx++]);
                    932:
                    933:    /*
                    934:     * Need to jump to the tag before executing the '-c command'.
                    935:     * Makes "vim -c '/return' -t main" work.
                    936:     */
                    937:    if (tagname)
                    938:    {
                    939:        STRCPY(IObuff, "ta ");
                    940:        STRCAT(IObuff, tagname);
                    941:        do_cmdline(IObuff, TRUE, TRUE);
                    942:    }
                    943:
                    944:    if (command)
                    945:    {
                    946:        /*
                    947:         * We start commands on line 0, make "vim +/pat file" match a
                    948:         * pattern on line 1.
                    949:         */
                    950:        curwin->w_cursor.lnum = 0;
                    951:        sourcing_name = (char_u *)"command line";
                    952:        do_cmdline(command, TRUE, TRUE);
                    953:        sourcing_name = NULL;
                    954:    }
                    955:
                    956:    RedrawingDisabled = FALSE;
                    957:    redraw_later(NOT_VALID);
                    958:    no_wait_return = FALSE;
                    959:
                    960:    /* start in insert mode */
                    961:    if (p_im)
                    962:        need_start_insertmode = TRUE;
                    963:
                    964: /*
                    965:  * main command loop
                    966:  */
                    967:    for (;;)
                    968:    {
                    969:        if (stuff_empty())
                    970:        {
                    971:            if (need_check_timestamps)
                    972:                check_timestamps();
                    973:            if (need_wait_return)       /* if wait_return still needed ... */
                    974:                wait_return(FALSE);     /* ... call it now */
                    975:            if (need_start_insertmode)
                    976:            {
                    977:                need_start_insertmode = FALSE;
                    978:                stuffReadbuff((char_u *)"i");   /* start insert mode next */
                    979:                /* skip the fileinfo message now, because it would be shown
                    980:                 * after insert mode finishes! */
                    981:                need_fileinfo = FALSE;
                    982:            }
                    983:        }
                    984:        dont_wait_return = FALSE;
                    985:        if (got_int)
                    986:        {
                    987:            (void)vgetc();              /* flush all buffers */
                    988:            got_int = FALSE;
                    989:        }
                    990:        adjust_cursor();                /* put cursor on an existing line */
                    991:        msg_scroll = FALSE;
                    992:        quit_more = FALSE;
                    993:        keep_help_flag = FALSE;
                    994:        /*
                    995:         * If skip redraw is set (for ":" in wait_return()), don't redraw now.
                    996:         * If there is nothing in the stuff_buffer or do_redraw is TRUE,
                    997:         * update cursor and redraw.
                    998:         */
                    999:        if (skip_redraw)
                   1000:            skip_redraw = FALSE;
                   1001:        else if (do_redraw || stuff_empty())
                   1002:        {
                   1003:            cursupdate();               /* Figure out where the cursor is based
                   1004:                                            on curwin->w_cursor. */
                   1005: #ifdef SLEEP_IN_EMSG
                   1006:            if (need_sleep)             /* sleep before redrawing */
                   1007:            {
                   1008:                mch_delay(1000L, TRUE);
                   1009:                need_sleep = FALSE;
                   1010:            }
                   1011: #endif
                   1012:            if (VIsual_active)
                   1013:                update_curbuf(INVERTED);/* update inverted part */
                   1014:            if (must_redraw)
                   1015:                updateScreen(must_redraw);
                   1016:            else if (redraw_cmdline)
                   1017:                showmode();
                   1018:            if (keep_msg != NULL)
                   1019:            {
                   1020:                if (keep_msg_highlight)
                   1021:                {
                   1022:                    (void)set_highlight(keep_msg_highlight);
                   1023:                    msg_highlight = TRUE;
                   1024:                }
                   1025:                msg(keep_msg);          /* display message after redraw */
                   1026:            }
                   1027:            if (need_fileinfo)          /* used after jumping to a tag */
                   1028:            {
                   1029:                fileinfo(did_cd, TRUE, FALSE);
                   1030:                need_fileinfo = FALSE;
                   1031:            }
                   1032:
                   1033:            emsg_on_display = FALSE;    /* can delete error message now */
                   1034:            msg_didany = FALSE;         /* reset lines_left in msg_start() */
                   1035:            do_redraw = FALSE;
                   1036:            showruler(FALSE);
                   1037:
                   1038:            setcursor();
                   1039:            cursor_on();
                   1040:        }
                   1041:
                   1042:        /*
                   1043:         * get and execute a normal mode command
                   1044:         */
                   1045:        normal();
                   1046:    }
                   1047:    /*NOTREACHED*/
                   1048: }
                   1049:
                   1050:    void
                   1051: getout(r)
                   1052:    int             r;
                   1053: {
                   1054:    exiting = TRUE;
                   1055:
                   1056:    /* Position the cursor on the last screen line, below all the text */
                   1057: #ifdef USE_GUI
                   1058:    if (!gui.in_use)
                   1059: #endif
                   1060:        windgoto((int)Rows - 1, 0);
                   1061:
                   1062: #ifdef AUTOCMD
                   1063:    apply_autocmds(EVENT_VIMLEAVE, NULL, NULL);
                   1064:
                   1065:    /* Position the cursor again, the autocommands may have moved it */
                   1066: # ifdef USE_GUI
                   1067:    if (!gui.in_use)
                   1068: # endif
                   1069:        windgoto((int)Rows - 1, 0);
                   1070: #endif
                   1071:
                   1072: #ifdef VIMINFO
                   1073:    /* Write out the registers, history, marks etc, to the viminfo file */
                   1074:    if (*p_viminfo != NUL)
                   1075:        write_viminfo(NULL, FALSE);
                   1076: #endif /* VIMINFO */
                   1077:
                   1078:    outchar('\r');
                   1079:    outchar('\n');
                   1080:    mch_windexit(r);
                   1081: }