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