Annotation of src/usr.bin/vim/main.c, Revision 1.2
1.2 ! downsj 1: /* $OpenBSD: main.c,v 1.1.1.1 1996/09/07 21:40:26 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][] */
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: full_screen = TRUE;
762: }
763: #endif
764:
765: /*
766: * If we read a .vimrc but it does not contain a "version 4.0" command,
767: * give the user a pointer to the help for the new version.
768: */
769: if (check_version && found_version == 0)
770: {
771: MSG("This is Vim version 4.0.");
772: MSG("No \":version 4.0\" command found in any .vimrc.");
773: MSG("Use \":help version\" for info about this new version.");
774: }
775:
776: #ifdef VIMINFO
777: /*
778: * Read in registers, history etc, but not marks, from the viminfo file
779: */
780: if (*p_viminfo != NUL)
781: read_viminfo(NULL, TRUE, FALSE, FALSE);
782: #endif /* VIMINFO */
783:
784: #ifdef SPAWNO /* special MSDOS swapping library */
785: init_SPAWNO("", SWAP_ANY);
786: #endif
787:
788: if (bin_mode) /* -b option used */
789: {
790: set_options_bin(curbuf->b_p_bin, 1);
791: curbuf->b_p_bin = 1; /* binary file I/O */
792: }
793:
1.2 ! downsj 794: /*
! 795: * "-e errorfile": Load the error file now.
! 796: * If the error file can't be read, exit before doing anything else.
! 797: */
! 798: if (doqf && qf_init() == FAIL) /* if reading error file fails: exit */
! 799: {
! 800: outchar('\n');
! 801: mch_windexit(3);
! 802: }
! 803:
1.1 downsj 804: /* Don't set the file name if there was a command in .vimrc that already
805: * loaded the file */
806: if (curbuf->b_filename == NULL)
807: {
808: (void)setfname(fname, NULL, TRUE); /* includes maketitle() */
809: ++arg_idx; /* used first argument name */
810: }
811:
812: if (window_count == 0)
813: window_count = arg_count;
814: if (window_count > 1)
815: {
816: /* Don't change the windows if there was a command in .vimrc that
817: * already split some windows */
818: if (firstwin->w_next == NULL)
819: window_count = make_windows(window_count);
820: else
821: window_count = win_count();
822: }
823: else
824: window_count = 1;
825:
826: /*
827: * Start putting things on the screen.
828: * Scroll screen down before drawing over it
829: * Clear screen now, so file message will not be cleared.
830: */
831: starting = FALSE;
832: no_wait_return = FALSE;
833: msg_scroll = FALSE;
834: #ifdef USE_GUI
835: /*
836: * This seems to be required to make callbacks to be called now, instead
837: * of after things have been put on the screen, which then may be deleted
838: * when getting a resize callback.
839: */
840: if (gui.in_use)
841: gui_mch_wait_for_chars(50);
842: #endif
843:
844: /*
845: * When done something that is not allowed or error message call wait_return.
846: * This must be done before starttermcap(), because it may switch to another
847: * screen. It must be done after settmode(1), because we want to react on a
848: * single key stroke.
849: * Call settmode and starttermcap here, so the T_KS and T_TI may be defined
850: * by termcapinit and redifined in .exrc.
851: */
852: settmode(1);
853: if (secure == 2 || need_wait_return || msg_didany)
854: wait_return(TRUE);
855:
856: starttermcap(); /* start termcap if not done by wait_return() */
857: #ifdef USE_MOUSE
858: setmouse(); /* may start using the mouse */
859: #endif
860: if (scroll_region)
861: scroll_region_reset(); /* In case Rows changed */
862:
863: secure = 0;
864:
865: scroll_start();
866: screenclear(); /* clear screen */
867:
868: no_wait_return = TRUE;
869:
870: if (recoverymode) /* do recover */
871: {
872: msg_scroll = TRUE; /* scroll message up */
873: ml_recover();
874: msg_scroll = FALSE;
875: if (curbuf->b_ml.ml_mfp == NULL) /* failed */
876: getout(1);
1.2 ! downsj 877: do_modelines(); /* do modelines */
! 878: }
! 879: else
! 880: {
! 881: /*
! 882: * Open a buffer for windows that don't have one yet.
! 883: * Commands in the .vimrc might have loaded a file or split the window.
! 884: * Watch out for autocommands that delete a window.
! 885: */
! 886: #ifdef AUTOCMD
! 887: /*
! 888: * Don't execute Win/Buf Enter/Leave autocommands here
! 889: */
! 890: ++autocmd_no_enter;
! 891: ++autocmd_no_leave;
! 892: #endif
! 893: for (curwin = firstwin; curwin != NULL; curwin = curwin->w_next)
! 894: {
! 895: curbuf = curwin->w_buffer;
! 896: if (curbuf->b_ml.ml_mfp == NULL)
! 897: {
! 898: (void)open_buffer(); /* create memfile and read file */
! 899: #ifdef AUTOCMD
! 900: curwin = firstwin; /* start again */
! 901: #endif
! 902: }
! 903: mch_breakcheck();
! 904: if (got_int)
! 905: {
! 906: (void)vgetc(); /* only break the file loading, not the rest */
! 907: break;
! 908: }
! 909: }
1.1 downsj 910: #ifdef AUTOCMD
1.2 ! downsj 911: --autocmd_no_enter;
! 912: --autocmd_no_leave;
1.1 downsj 913: #endif
1.2 ! downsj 914: curwin = firstwin;
! 915: curbuf = curwin->w_buffer;
1.1 downsj 916: }
917:
1.2 ! downsj 918: #ifdef AUTOCMD
! 919: apply_autocmds(EVENT_BUFENTER, NULL, NULL);
! 920: #endif
1.1 downsj 921: setpcmark();
922:
923: /*
924: * When started with "-e errorfile" jump to first error now.
925: */
926: if (doqf)
1.2 ! downsj 927: qf_jump(0, 0, FALSE);
1.1 downsj 928:
929: /*
930: * If opened more than one window, start editing files in the other windows.
931: * Make_windows() has already opened the windows.
932: */
1.2 ! downsj 933: #ifdef AUTOCMD
! 934: /*
! 935: * Don't execute Win/Buf Enter/Leave autocommands here
! 936: */
! 937: ++autocmd_no_enter;
! 938: ++autocmd_no_leave;
! 939: #endif
1.1 downsj 940: for (i = 1; i < window_count; ++i)
941: {
942: if (curwin->w_next == NULL) /* just checking */
943: break;
944: win_enter(curwin->w_next, FALSE);
945:
946: /* Only open the file if there is no file in this window yet (that can
947: * happen when .vimrc contains ":sall") */
948: if (curbuf == firstwin->w_buffer || curbuf->b_filename == NULL)
949: {
950: curwin->w_arg_idx = arg_idx;
951: /* edit file from arg list, if there is one */
952: (void)do_ecmd(0, arg_idx < arg_count ? arg_files[arg_idx] : NULL,
1.2 ! downsj 953: NULL, NULL, (linenr_t)1, ECMD_HIDE);
1.1 downsj 954: if (arg_idx == arg_count - 1)
955: arg_had_last = TRUE;
956: ++arg_idx;
957: }
958: mch_breakcheck();
959: if (got_int)
960: {
961: (void)vgetc(); /* only break the file loading, not the rest */
962: break;
963: }
964: }
1.2 ! downsj 965: #ifdef AUTOCMD
! 966: --autocmd_no_enter;
! 967: #endif
1.1 downsj 968: win_enter(firstwin, FALSE); /* back to first window */
1.2 ! downsj 969: #ifdef AUTOCMD
! 970: --autocmd_no_leave;
! 971: #endif
1.1 downsj 972: if (window_count > 1)
973: win_equal(curwin, FALSE); /* adjust heights */
974:
975: /*
976: * If there are more file names in the argument list than windows,
977: * put the rest of the names in the buffer list.
978: */
979: while (arg_idx < arg_count)
980: (void)buflist_add(arg_files[arg_idx++]);
981:
982: /*
983: * Need to jump to the tag before executing the '-c command'.
984: * Makes "vim -c '/return' -t main" work.
985: */
986: if (tagname)
987: {
988: STRCPY(IObuff, "ta ");
989: STRCAT(IObuff, tagname);
990: do_cmdline(IObuff, TRUE, TRUE);
991: }
992:
993: if (command)
994: {
995: /*
996: * We start commands on line 0, make "vim +/pat file" match a
997: * pattern on line 1.
998: */
999: curwin->w_cursor.lnum = 0;
1000: sourcing_name = (char_u *)"command line";
1001: do_cmdline(command, TRUE, TRUE);
1002: sourcing_name = NULL;
1003: }
1004:
1005: RedrawingDisabled = FALSE;
1006: redraw_later(NOT_VALID);
1007: no_wait_return = FALSE;
1008:
1009: /* start in insert mode */
1010: if (p_im)
1011: need_start_insertmode = TRUE;
1012:
1013: /*
1014: * main command loop
1015: */
1016: for (;;)
1017: {
1018: if (stuff_empty())
1019: {
1020: if (need_check_timestamps)
1021: check_timestamps();
1022: if (need_wait_return) /* if wait_return still needed ... */
1023: wait_return(FALSE); /* ... call it now */
1024: if (need_start_insertmode)
1025: {
1026: need_start_insertmode = FALSE;
1027: stuffReadbuff((char_u *)"i"); /* start insert mode next */
1028: /* skip the fileinfo message now, because it would be shown
1029: * after insert mode finishes! */
1030: need_fileinfo = FALSE;
1031: }
1032: }
1033: dont_wait_return = FALSE;
1034: if (got_int)
1035: {
1036: (void)vgetc(); /* flush all buffers */
1037: got_int = FALSE;
1038: }
1039: adjust_cursor(); /* put cursor on an existing line */
1040: msg_scroll = FALSE;
1041: quit_more = FALSE;
1042: keep_help_flag = FALSE;
1043: /*
1044: * If skip redraw is set (for ":" in wait_return()), don't redraw now.
1045: * If there is nothing in the stuff_buffer or do_redraw is TRUE,
1046: * update cursor and redraw.
1047: */
1048: if (skip_redraw)
1049: skip_redraw = FALSE;
1050: else if (do_redraw || stuff_empty())
1051: {
1052: cursupdate(); /* Figure out where the cursor is based
1053: on curwin->w_cursor. */
1054: #ifdef SLEEP_IN_EMSG
1055: if (need_sleep) /* sleep before redrawing */
1056: {
1057: mch_delay(1000L, TRUE);
1058: need_sleep = FALSE;
1059: }
1060: #endif
1061: if (VIsual_active)
1062: update_curbuf(INVERTED);/* update inverted part */
1063: if (must_redraw)
1064: updateScreen(must_redraw);
1065: else if (redraw_cmdline)
1066: showmode();
1067: if (keep_msg != NULL)
1068: {
1069: if (keep_msg_highlight)
1070: {
1071: (void)set_highlight(keep_msg_highlight);
1072: msg_highlight = TRUE;
1073: }
1074: msg(keep_msg); /* display message after redraw */
1075: }
1076: if (need_fileinfo) /* used after jumping to a tag */
1077: {
1078: fileinfo(did_cd, TRUE, FALSE);
1079: need_fileinfo = FALSE;
1080: }
1081:
1082: emsg_on_display = FALSE; /* can delete error message now */
1083: msg_didany = FALSE; /* reset lines_left in msg_start() */
1084: do_redraw = FALSE;
1085: showruler(FALSE);
1086:
1087: setcursor();
1088: cursor_on();
1089: }
1090:
1091: /*
1092: * get and execute a normal mode command
1093: */
1094: normal();
1095: }
1096: /*NOTREACHED*/
1097: }
1098:
1099: void
1100: getout(r)
1101: int r;
1102: {
1103: exiting = TRUE;
1104:
1105: /* Position the cursor on the last screen line, below all the text */
1106: #ifdef USE_GUI
1107: if (!gui.in_use)
1108: #endif
1109: windgoto((int)Rows - 1, 0);
1110:
1111: #ifdef AUTOCMD
1112: apply_autocmds(EVENT_VIMLEAVE, NULL, NULL);
1113:
1114: /* Position the cursor again, the autocommands may have moved it */
1115: # ifdef USE_GUI
1116: if (!gui.in_use)
1117: # endif
1118: windgoto((int)Rows - 1, 0);
1119: #endif
1120:
1121: #ifdef VIMINFO
1.2 ! downsj 1122: msg_didany = FALSE;
1.1 downsj 1123: /* Write out the registers, history, marks etc, to the viminfo file */
1124: if (*p_viminfo != NUL)
1125: write_viminfo(NULL, FALSE);
1.2 ! downsj 1126: if (msg_didany) /* make the user read the error message */
! 1127: {
! 1128: no_wait_return = FALSE;
! 1129: wait_return(FALSE);
! 1130: }
1.1 downsj 1131: #endif /* VIMINFO */
1132:
1133: mch_windexit(r);
1134: }