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