ftp.nice.ch/pub/next/unix/editor/vim-5.0f.s.tar.gz#/vim-5.0f/src/main.c

This is main.c in view mode; [Download] [Up]

/* vi:set ts=4 sw=4:
 *
 * VIM - Vi IMproved		by Bram Moolenaar
 *
 * Do ":help uganda"  in Vim to read copying and usage conditions.
 * Do ":help credits" in Vim to see a list of people who contributed.
 */

#define EXTERN
#include "vim.h"
#include "globals.h"
#include "proto.h"
#include "option.h"

#ifdef SPAWNO
# include <spawno.h>			/* special MSDOS swapping library */
#endif

static void usage __ARGS((int, char_u *));

/*
 * Types of usage message required.  These must match the array of error
 * messages in usage().
 */
#define USAGE_UNKNOWN_OPTION	0
#define USAGE_TOO_MANY_ARGS		1
#define USAGE_ARG_MISSING		2
#define USAGE_GARBAGE			3
#define USAGE_EXTRA_CMD			4

	static void
usage(n, str)
	int		n;
	char_u	*str;
{
	int 			i;
	static char_u *(use[]) =
	{
		(char_u *)"[file ..]       edit specified file(s)",
		(char_u *)"-               read from stdin",
		(char_u *)"-t tag          edit file where tag is defined",
		(char_u *)"-q [errorfile]  edit file with first error"
	};
	static char_u *(errors[]) =
	{
		(char_u *)"Unknown option",
		(char_u *)"Too many edit arguments",
		(char_u *)"Argument missing after",
		(char_u *)"Garbage after option",
		(char_u *)"Only one \"+command\" or \"-c command\" argument allowed",
	};

#if defined(UNIX) || defined(__EMX__)
	reset_signals();		/* kill us with CTRL-C here, if you like */
#endif

	fprintf(stderr, longVersion);
	fprintf(stderr, "\n");
	fprintf(stderr, (char *)errors[n]);
	if (str != NULL)
		fprintf(stderr, ": \"%s\"", str);
	fprintf(stderr, "\nusage:");
	for (i = 0; ; ++i)
	{
		fprintf(stderr, " vim [options] ");
		fprintf(stderr, (char *)use[i]);
		if (i == (sizeof(use) / sizeof(char_u *)) - 1)
			break;
		fprintf(stderr, "\n   or:");
	}

	fprintf(stderr, "\n\nOptions:\n");
#ifdef USE_GUI
	fprintf(stderr, "   -g\t\t\tRun using GUI (like \"gvim\")\n");
	fprintf(stderr, "   -f\t\t\tForeground: Don't fork when starting GUI\n");
#endif
	fprintf(stderr, "   -v\t\t\tVi mode (like \"vi\")\n");
	fprintf(stderr, "   -e\t\t\tEx mode (like \"ex\")\n");
	fprintf(stderr, "   -s\t\t\tSilent (batch) mode (only for \"ex\")\n");
	fprintf(stderr, "   -R\t\t\tReadonly mode (like \"view\")\n");
	fprintf(stderr, "   -Z\t\t\tRestricted mode (like \"rvim\")\n");
	fprintf(stderr, "   -b\t\t\tBinary mode\n");
	fprintf(stderr, "   -l\t\t\tLisp mode\n");
	fprintf(stderr, "   -n\t\t\tNo swap file, use memory only\n");
	fprintf(stderr, "   -r\t\t\tList swap files\n");
	fprintf(stderr, "   -r (with file name)\tRecover crashed session\n");
	fprintf(stderr, "   -L\t\t\tSame as -r\n");
#ifdef AMIGA
	fprintf(stderr, "   -f\t\t\tDon't use newcli to open window\n");
	fprintf(stderr, "   -d <device>\t\tUse <device> for I/O\n");
#endif
#ifdef RIGHTLEFT
	fprintf(stderr, "   -H\t\t\tstart in Hebrew mode\n");
#endif
	fprintf(stderr, "   -T <terminal>\tSet terminal type to <terminal>\n");
	fprintf(stderr, "   -o[N]\t\tOpen N windows (default: one for each file)\n");
	fprintf(stderr, "   +\t\t\tStart at end of file\n");
	fprintf(stderr, "   +<lnum>\t\tStart at line <lnum>\n");
	fprintf(stderr, "   -c <command>\t\tExecute <command> first\n");
	fprintf(stderr, "   -s <scriptin>\tRead commands from script file <scriptin>\n");
	fprintf(stderr, "   -w <scriptout>\tAppend commands to script file <scriptout>\n");
	fprintf(stderr, "   -W <scriptout>\tWrite commands to script file <scriptout>\n");
	fprintf(stderr, "   -u <vimrc>\t\tUse <vimrc> instead of any .vimrc\n");
	fprintf(stderr, "   -i <viminfo>\t\tUse <viminfo> instead of .viminfo\n");
	fprintf(stderr, "   -\t\t\tRead file from stdin\n");
	fprintf(stderr, "   --\t\t\tEnd of options\n");

#ifdef USE_GUI_X11
# ifdef USE_GUI_MOTIF
	fprintf(stderr, "\nOptions recognised by gvim (Motif version):\n");
# else
#  ifdef USE_GUI_ATHENA
	fprintf(stderr, "\nOptions recognised by gvim (Athena version):\n");
#  endif /* USE_GUI_ATHENA */
# endif /* USE_GUI_MOTIF */
	fprintf(stderr, "   -display <display>\tRun vim on <display>\n");
	fprintf(stderr, "   -iconic\t\tStart vim iconified\n");
# if 0
	fprintf(stderr, "   -name <name>\t\tUse resource as if vim was <name>\n");
	fprintf(stderr, "\t\t\t  (Unimplemented)\n");
# endif
	fprintf(stderr, "   -background <color>\tUse <color> for the background (also: -bg)\n");
	fprintf(stderr, "   -foreground <color>\tUse <color> for normal text (also: -fg)\n");
	fprintf(stderr, "   -bold <color>\tUse <color> for bold text\n");
	fprintf(stderr, "   -italic <color>\tUse <color> for italic text\n");
	fprintf(stderr, "   -underline <color>\tUse <color> for underlined text (also: -ul)\n");
	fprintf(stderr, "   -cursor <color>\tUse <color> for cursor\n");
	fprintf(stderr, "   -font <font>\t\tUse <font> for normal text (also: -fn)\n");
	fprintf(stderr, "   -boldfont <font>\tUse <font> for bold text\n");
	fprintf(stderr, "   -italicfont <font>\tUse <font> for italic text\n");
	fprintf(stderr, "   -geometry <geom>\tUse <geom> for initial geometry (also: -geom)\n");
	fprintf(stderr, "   -borderwidth <width>\tUse a border width of <width> (also: -bw)\n");
	fprintf(stderr, "   -scrollbarwidth <width>\tUse a scrollbar width of <width> (also: -sw)\n");
	fprintf(stderr, "   -menuheight <height>\tUse a menu bar height of <height> (also: -mh)\n");
	fprintf(stderr, "   -reverse\t\tUse reverse video (also: -rv)\n");
	fprintf(stderr, "   +reverse\t\tDon't use reverse video (also: +rv)\n");
	fprintf(stderr, "   -xrm <resource>\tSet the specified resource\n");
#endif /* USE_GUI_X11 */

	mch_windexit(1);
}

#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif

#ifndef PROTO		/* don't want a prototype for main() */
	void
main(argc, argv)
	int				argc;
	char		  **argv;
{
	char_u		   *initstr;		/* init string from the environment */
	char_u		   *term = NULL;	/* specified terminal name */
	char_u		   *fname = NULL;	/* file name from command line */
	char_u		   *command = NULL;	/* command from + or -c option */
	char_u		   *tagname = NULL;	/* tag from -t option */
	char_u		   *use_vimrc = NULL;	/* vimrc from -u option */
	int 			c;
	int				i;
	int				bin_mode = FALSE;		/* -b option used */
	int				window_count = 1;		/* number of windows to use */
	int				arg_idx = 0;			/* index for arg_files[] */
	int				had_minmin = FALSE;		/* found "--" argument */
	int				check_version = FALSE;	/* check .vimrc version number */
	int				argv_idx;				/* index in argv[n][] */
	int				want_full_screen = TRUE;
	int				want_argument;			/* option with argument */
#define EDIT_NONE	0		/* no edit type yet */
#define EDIT_FILE	1		/* filename argument[s] given, use arg_files[] */
#define EDIT_STDIN	2		/* read file from stdin */
#define EDIT_TAG	3		/* tag name argument given, use tagname */
#define EDIT_QF		4		/* start in quickfix mode */
	int				edit_type = EDIT_NONE;	/* type of editing to do */
	int				stdout_isatty = TRUE;	/* is stdout a terminal? */
	int				stdin_isatty = TRUE;	/* is stdin a terminal? */
	OPARG			oa;						/* operator arguments */

#if defined(MSDOS) || defined(WIN32) || defined(OS2)
	/*
	 * Default mapping for some often used keys.
	 */
	static struct initmap
	{
		char_u		*arg;
		int			mode;
	} initmappings[] =
	{
		/* normal and visual mode */
#ifdef MSDOS
		{(char_u *)"\316w H", NORMAL+VISUAL},		/* CTRL-HOME is "H" */
		{(char_u *)"\316u L", NORMAL+VISUAL},		/* CTRL-END is "L" */
		{(char_u *)"\316\204 1G", NORMAL+VISUAL},	/* CTRL-PageUp is "1G" */
		{(char_u *)"\316v G", NORMAL+VISUAL},		/* CTRL-PageDown is "G" */
#else /* WIN32 */
		/* Use the Windows (CUA) keybindings */
		{(char_u *)"\316w 1G", NORMAL+VISUAL},		/* CTRL-HOME is "1G" */
		{(char_u *)"\316u G$", NORMAL+VISUAL},		/* CTRL-END is "G$" */
		{(char_u *)"\316\204 H", NORMAL+VISUAL},	/* CTRL-PageUp is "H" */
		{(char_u *)"\316v L$", NORMAL+VISUAL},		/* CTRL-PageDown is "L$" */
		{(char_u *)"\316s B", NORMAL+VISUAL},		/* CTRL-Left is "B" */
		{(char_u *)"\316t W", NORMAL+VISUAL},		/* CTRL-Right is "W" */
#endif /* WIN32 */

		/* insert mode */
#ifdef MSDOS
		{(char_u *)"\316w \017H", INSERT},			/* CTRL-HOME is "^OH" */
		{(char_u *)"\316u \017L", INSERT},			/* CTRL-END is "^OL" */
		{(char_u *)"\316\204 \017\061G", INSERT},	/* CTRL-PageUp is "^O1G" */
		{(char_u *)"\316v \017G", INSERT},			/* CTRL-PageDown is "^OG" */
#else /* WIN32 */
		/* Use the Windows (CUA) keybindings */
		{(char_u *)"\316w \017\061G", INSERT},		/* CTRL-HOME is "^O1G" */
		{(char_u *)"\316u \017G\017$", INSERT},		/* CTRL-END is "^OG^O$" */
		{(char_u *)"\316\204 \017H",INSERT},		/* CTRL-PageUp is "^OH"*/
		{(char_u *)"\316v \017L\017$", INSERT},		/* CTRL-PageDown ="^OL^O$"*/
		{(char_u *)"\316s \017B", INSERT},			/* CTRL-Left is "^OB" */
		{(char_u *)"\316t \017W", INSERT},			/* CTRL-Right is "^OW" */
#endif /* WIN32 */
	};
#endif

#ifdef __EMX__
	_wildcard(&argc, &argv);
#endif

#ifdef HAVE_LOCALE_H
	setlocale(LC_ALL, "");		/* for ctype() and the like */
#endif

#ifdef USE_GUI
	gui_prepare(&argc, argv);	/* Prepare for possibly starting GUI sometime */
#endif

#ifdef USE_CLIPBOARD
	clip_init(FALSE);			/* Initialise clipboard stuff */
#endif

	/*
	 * Check if we have an interactive window.
	 * On the Amiga: If there is no window, we open one with a newcli command
	 * (needed for :! to * work). mch_check_win() will also handle the -d
	 * argument.
	 */
	stdout_isatty = (mch_check_win(argc, argv) != FAIL);

	/*
	 * allocate the first window and buffer. Can't do anything without it
	 */
	if ((curwin = win_alloc(NULL)) == NULL ||
						(curbuf = buflist_new(NULL, NULL, 1L, FALSE)) == NULL)
		mch_windexit(0);
	curwin->w_buffer = curbuf;

	/*
	 * Allocate space for the generic buffers (needed for set_init_1()).
	 */
	if ((IObuff = alloc(IOSIZE)) == NULL ||
							(NameBuff = alloc(MAXPATHL)) == NULL)
		mch_windexit(0);

	/*
	 * Set the default values for the options.
	 * First find out the home directory, needed to expand "~" in options.
	 */
	init_homedir();				/* find real value of $HOME */
	set_init_1();

	/*
	 * If the executable name starts with "r" we disable shell commands.
	 * If the next character is "g" we run the GUI version.
	 * If the next characters are "view" we start in readonly mode.
	 * If the next characters are "ex" we start in ex mode.
	 */
	initstr = gettail((char_u *)argv[0]);

	if (initstr[0] == 'r')
	{
		restricted = TRUE;
		++initstr;
	}

	if (initstr[0] == 'g')
	{
#ifdef USE_GUI
		gui.starting = TRUE;
		++initstr;
#else
		fprintf(stderr, (char *)e_nogvim);
		mch_windexit(2);
#endif
	}

	if (STRNCMP(initstr, "view", 4) == 0)
	{
		readonlymode = TRUE;
		curbuf->b_p_ro = TRUE;
		if (p_uc)					/* if we are doing any updating.. */
			p_uc = 10000;			/* ..don't update very often */
	}

	if (STRNCMP(initstr, "ex", 2) == 0)
		exmode_active = TRUE;

	/*
	 * On some systems, when we compile with the GUI, we always use it.  On Mac
	 * there is no terminal version, and on Windows we can't figure out how to
	 * fork one off with :gui.
	 */
#ifdef ALWAYS_USE_GUI
	gui.starting = TRUE;
#endif

	++argv;
	--argc;

	/*
	 * Allocate arg_files[], big enough to hold all potential filename
	 * arguments.
	 */
	arg_files = (char_u **)alloc((unsigned)(sizeof(char_u *) * (argc + 1)));
	if (arg_files == NULL)
		mch_windexit(2);
	arg_file_count = 0;

	/*
	 * Process the command line arguments.
	 */
	argv_idx = 1;			/* active option letter is argv[0][argv_idx] */
	while (argc > 0)
	{
		/*
		 * "+" or "+{number}" or "+/{pat}" or "+{command}" argument.
		 */
		if (argv[0][0] == '+' && !had_minmin)
		{
			if (command != NULL)
				usage(USAGE_EXTRA_CMD, NULL);
			argv_idx = -1;			/* skip to next argument */
			if (argv[0][1] == NUL)
				command = (char_u *)"$";
			else
				command = (char_u *)&(argv[0][1]);
		}

		/*
		 * Option argument.
		 */
		else if (argv[0][0] == '-' && !had_minmin)
		{
			want_argument = FALSE;
			c = argv[0][argv_idx++];
			switch (c)
			{
			case NUL:		/* "-"  read from stdin */
				if (edit_type != EDIT_NONE)
					usage(USAGE_TOO_MANY_ARGS, (char_u *)argv[0]);
				edit_type = EDIT_STDIN;
				read_cmd_fd = 2;		/* read from stderr instead of stdin */
				argv_idx = -1;			/* skip to next argument */
				break;

			case '-':		/* "--"	don't take any more options */
				had_minmin = TRUE;
				argv_idx = -1;			/* skip to next argument */
				break;

			case 'b':		/* "-b" binary mode */
				bin_mode = TRUE;	/* postpone to after reading .exrc files */
				break;

			case 'e':		/* "-e" Ex mode */
				exmode_active = TRUE;
				break;

#ifdef USE_GUI
			case 'f':		/* "-f" run GUI in foreground */
				gui.dofork = FALSE;		/* don't fork() when starting GUI */
				break;
#endif

#ifdef AMIGA
			case 'f':		/* "-f" open window directly, not with newcli */
				break;		/* This is handled in mch_check_win() */
#endif

			case 'g':		/* "-g" start GUI */
#ifdef USE_GUI
				gui.starting = TRUE;	/* start GUI a bit later */
#else
				fprintf(stderr, (char *)e_nogvim);
				mch_windexit(2);
#endif
				break;

			case 'H':		/* "-H" start in Hebrew mode: rl + hkmap set */
#ifdef RIGHTLEFT
				curwin->w_p_rl = p_hkmap = TRUE;
#else
				fprintf(stderr, (char *)e_nohebrew);
				mch_windexit(2);
#endif
				break;

			case 'l':		/* "-l" lisp mode, 'lisp' and 'showmatch' on */
				curbuf->b_p_lisp = TRUE;
				p_sm = TRUE;
				break;

			case 'n':		/* "-n" no swap file */
				p_uc = 0;
				break;

			case 'o':		/* "-o[N]" open N windows */
				window_count = 0;		/* default: open window for each file */
				if (isdigit(argv[0][argv_idx]))
				{
					window_count = atoi(&(argv[0][argv_idx]));
					while (isdigit(argv[0][argv_idx]))
						++argv_idx;
				}
				break;

		  	case 'q':		/* "-q" QuickFix mode */
				if (edit_type != EDIT_NONE)
					usage(USAGE_TOO_MANY_ARGS, (char_u *)argv[0]);
				edit_type = EDIT_QF;
				if (argv[0][argv_idx])				/* "-q{errorfile}" */
				{
					p_ef = (char_u *)argv[0] + argv_idx;
					argv_idx = -1;
				}
				else if (argc > 1)					/* "-q {errorfile}" */
					want_argument = TRUE;
				break;

			case 'R':		/* "-R" readonly mode */
				readonlymode = TRUE;
				curbuf->b_p_ro = TRUE;
				if (p_uc)				/* if we are doing any updating.. */
					p_uc = 10000;			/* ..don't update very often */
				break;

			case 'r':		/* "-r" recovery mode */
			case 'L':		/* "-L" recovery mode */
				recoverymode = 1;
				break;

			case 's':
				if (exmode_active)		/* "-s" silent (batch) mode */
					silent_mode = TRUE;
				else			/* "-s {scriptin}" read from script file */
					want_argument = TRUE;
				break;

			case 't':		/* "-t {tag}" or "-t{tag}" jump to tag */
				if (edit_type != EDIT_NONE)
					usage(USAGE_TOO_MANY_ARGS, (char_u *)argv[0]);
				edit_type = EDIT_TAG;
				if (argv[0][argv_idx])		/* "-t{tag}" */
				{
					tagname = (char_u *)argv[0] + argv_idx;
					argv_idx = -1;
				}
				else						/* "-t {tag}" */
					want_argument = TRUE;
				break;

			case 'v':		/* "-v"  Vi-mode (as if called "vi") */
				exmode_active = FALSE;
				break;

			case 'w':		/* "-w{number}"		set window height */
							/* "-w {scriptout}"	write to script */
				if (isdigit(argv[0][argv_idx]))
				{
					argv_idx = -1;
					break;						/* not implemented, ignored */
				}
				want_argument = TRUE;
				break;

			case 'x':		/* "-x"  use "crypt" for reading/writing files. */
				/* TODO */
				break;

			case 'Z':		/* "-Z"  restricted mode */
				restricted = TRUE;
				break;

			case 'c':		/* "-c {command}" execute command */
			case 'd':		/* "-d {device}" device (for Amiga) */
			case 'i':		/* "-i {viminfo}" use for viminfo */
			case 'T':		/* "-T {terminal}" terminal name */
			case 'u':		/* "-u {vimrc}" read initializations from a file */
			case 'W':		/* "-W {scriptout}" overwrite */
				want_argument = TRUE;
				break;

			default:
				usage(USAGE_UNKNOWN_OPTION, (char_u *)argv[0]);
			}

			/*
			 * Handle options with argument.
			 */
			if (want_argument)
			{
				/*
				 * Check for garbage immediately after the option letter.
				 */
				if (argv[0][argv_idx] != NUL)
					usage(USAGE_GARBAGE, (char_u *)argv[0]);

				--argc;
				if (argc < 1)
					usage(USAGE_ARG_MISSING, (char_u *)argv[0]);
				++argv;
				argv_idx = -1;

				switch (c)
				{
				case 'c':			/* "-c {command}" execute command */
					if (command != NULL)
						usage(USAGE_EXTRA_CMD, NULL);
					command = (char_u *)argv[0];
					break;

			/*	case 'd':	This is handled in mch_check_win() */

				case 'q':			/* "-q {errorfile}" QuickFix mode */
					p_ef = (char_u *)argv[0];
					break;

				case 'i':			/* "-i {viminfo}" use for viminfo */
					use_viminfo = (char_u *)argv[0];
					break;

				case 's':			/* "-s {scriptin}" read from script file */
					if (scriptin[0] != NULL)
					{
						fprintf(stderr,
							 "Attempt to open script file again: \"%s %s\"\n",
								argv[-1], argv[0]);
						mch_windexit(2);
					}
					if ((scriptin[0] = fopen(argv[0], READBIN)) == NULL)
					{
						fprintf(stderr,
								"Cannot open \"%s\" for reading\n", argv[0]);
						mch_windexit(2);
					}
					break;

				case 't':			/* "-t {tag}" */
					tagname = (char_u *)argv[0];
					break;

				case 'T':			/* "-T {terminal}" terminal name */
					/*
					 * The -T term option is always available and when
					 * HAVE_TERMLIB is supported it overrides the environment
					 * variable TERM.
					 */
					term = (char_u *)argv[0];
					break;

				case 'u':			/* "-u {vimrc}" read initializations from
									   a file */
					use_vimrc = (char_u *)argv[0];
					break;

				case 'w':			/* "-w {scriptout}" append to script file */
				case 'W':			/* "-W {scriptout}" overwrite script file */
					if (scriptout != NULL)
					{
						fprintf(stderr,
							 "Attempt to open script file again: \"%s %s\"\n",
								argv[-1], argv[0]);
						mch_windexit(2);
					}
					if ((scriptout = fopen(argv[0],
									c == 'w' ? APPENDBIN : WRITEBIN)) == NULL)
					{
						fprintf(stderr,
								"cannot open \"%s\" for output\n", argv[0]);
						mch_windexit(2);
					}
					break;
				}
			}
		}

		/*
		 * Filename argument.
		 */
		else
		{
			argv_idx = -1;			/* skip to next argument */
			if (edit_type != EDIT_NONE && edit_type != EDIT_FILE)
				usage(USAGE_TOO_MANY_ARGS, (char_u *)argv[0]);
			edit_type = EDIT_FILE;
			arg_files[arg_file_count] = vim_strsave((char_u *)argv[0]);
			if (arg_files[arg_file_count] != NULL)
				++arg_file_count;
		}

		/*
		 * If there are no more letters after the current "-", go to next
		 * argument.  argv_idx is set to -1 when the current argument is to be
		 * skipped.
		 */
		if (argv_idx <= 0 || argv[0][argv_idx] == NUL)
		{
			--argc;
			++argv;
			argv_idx = 1;
		}
	}

	/*
	 * May expand wildcards in filenames.
	 */
	if (arg_file_count > 0)
	{
#if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
		char_u		**new_arg_files;
		int			new_arg_file_count;

		if (ExpandWildCards(arg_file_count, arg_files, &new_arg_file_count,
				&new_arg_files, TRUE, TRUE) == OK && new_arg_file_count != 0)
		{
			FreeWild(arg_file_count, arg_files);
			arg_file_count = new_arg_file_count;
			arg_files = new_arg_files;
		}
#endif
		fname = arg_files[0];
	}
	if (arg_file_count > 1)
		printf("%d files to edit\n", arg_file_count);

	RedrawingDisabled = TRUE;

	/*
	 * When listing swap file names, don't do cursor positioning et. al.
	 */
	if (recoverymode && fname == NULL)
		want_full_screen = FALSE;

	/*
	 * When starting the GUI, don't need to check capabilities of terminal.
	 */
#ifdef USE_GUI
	if (gui.starting)
		want_full_screen = FALSE;
#endif

	/*
	 * mch_windinit() sets up the terminal (window) for use.  This must be
	 * done after resetting full_screen, otherwise it may move the cursor
	 * (MSDOS).
	 * Note that we may use mch_windexit() before mch_windinit()!
	 */
	mch_windinit();				/* inits Rows and Columns */

	/*
	 * Set the default values for the options that use Rows and Columns.
	 */
	set_init_2();

	firstwin->w_height = Rows - 1;
	cmdline_row = Rows - 1;

	/*
	 * Now print a warning if stdout is not a terminal.
	 * When starting in Ex mode and commands come from a file, set Silent mode.
	 */
	stdin_isatty = mch_input_isatty();
	if (exmode_active)
	{
		if (!stdin_isatty)
			silent_mode = TRUE;
	}
	else if (want_full_screen && (!stdout_isatty || !stdin_isatty))
	{
		if (!stdout_isatty)
			fprintf(stderr, "Vim: Warning: Output is not to a terminal\n");
		if (!stdin_isatty)
			fprintf(stderr, "Vim: Warning: Input is not from a terminal\n");
		ui_delay(2000L, TRUE);
	}

	curbuf->b_nwindows = 1;		/* there is one window */
	win_init(curwin);			/* init current window */
	init_yank();				/* init yank buffers */
	if (want_full_screen)
	{
		termcapinit(term);		/* set terminal name and get terminal
								   capabilities */
		screen_start();			/* don't know where cursor is now */
		full_screen = TRUE;
	}
	screenclear();				/* clear screen (just inits screen structures,
									because starting is TRUE) */

	if (full_screen)
		msg_start();		/* in case a mapping or error message is printed */
	msg_scroll = TRUE;
	no_wait_return = TRUE;

#if defined(MSDOS) || defined(WIN32) || defined(OS2)
	/*
	 * Default mapping for some often used keys.
	 * Need to put string in allocated memory, because do_map() will modify it.
	 */
	for (i = 0; i < sizeof(initmappings) / sizeof(struct initmap); ++i)
	{
		initstr = vim_strsave(initmappings[i].arg);
		if (initstr != NULL)
		{
			do_map(0, initstr, initmappings[i].mode, FALSE);
			vim_free(initstr);
		}
	}
#endif

	/*
	 * If -u option given, use only the initializations from that file and
	 * nothing else.
	 */
	if (use_vimrc != NULL)
	{
		if (STRCMP(use_vimrc, "NONE") != 0)
		{
			if (do_source(use_vimrc, FALSE) == OK)
				check_version = TRUE;
			else
				EMSG2("Cannot read from \"%s\"", use_vimrc);
		}
	}
	else if (!silent_mode)
	{
		/*
		 * Get system wide defaults, if the filename is defined.
		 */
#ifdef SYS_VIMRC_FILE
		if (do_source((char_u *)SYS_VIMRC_FILE, TRUE) == OK)
			check_version = TRUE;
#endif

		/*
		 * Try to read initialization commands from the following places:
		 * - environment variable VIMINIT
		 * - user vimrc file (s:.vimrc for Amiga, ~/.vimrc for Unix)
		 * - environment variable EXINIT
		 * - user exrc file (s:.exrc for Amiga, ~/.exrc for Unix)
		 * The first that exists is used, the rest is ignored.
		 */
		if ((initstr = vim_getenv((char_u *)"VIMINIT")) != NULL &&
														*initstr != NUL)
		{
			sourcing_name = (char_u *)"VIMINIT";
			do_cmdline(initstr, NULL, NULL, DOCMD_NOWAIT|DOCMD_VERBOSE);
			sourcing_name = NULL;
		}
		else if (do_source((char_u *)USR_VIMRC_FILE, TRUE) == FAIL)
		{
			if ((initstr = vim_getenv((char_u *)"EXINIT")) != NULL)
			{
				sourcing_name = (char_u *)"EXINIT";
				do_cmdline(initstr, NULL, NULL, DOCMD_NOWAIT|DOCMD_VERBOSE);
				sourcing_name = NULL;
			}
			else
				(void)do_source((char_u *)USR_EXRC_FILE, FALSE);
		}
		else
			check_version = TRUE;

		/*
		 * Read initialization commands from ".vimrc" or ".exrc" in current
		 * directory.  This is only done if the 'exrc' option is set.
		 * Because of security reasons we disallow shell and write commands
		 * now, except for unix if the file is owned by the user or 'secure'
		 * option has been reset in environmet of global ".exrc" or ".vimrc".
		 * Only do this if VIMRC_FILE is not the same as USR_VIMRC_FILE or
		 * SYS_VIMRC_FILE.
		 */
		if (p_exrc)
		{
#ifdef UNIX
			{
				struct stat s;

				/* if ".vimrc" file is not owned by user, set 'secure' mode */
				if (stat(VIMRC_FILE, &s) || s.st_uid != getuid())
					secure = p_secure;
			}
#else
			secure = p_secure;
#endif

			i = FAIL;
			if (fullpathcmp((char_u *)USR_VIMRC_FILE,
											 (char_u *)VIMRC_FILE) != FPC_SAME
#ifdef SYS_VIMRC_FILE
					&& fullpathcmp((char_u *)SYS_VIMRC_FILE,
											 (char_u *)VIMRC_FILE) != FPC_SAME
#endif
					)
				i = do_source((char_u *)VIMRC_FILE, TRUE);

			if (i != FAIL)
				check_version = TRUE;
#ifdef UNIX
			else
			{
				struct stat s;

				/* if ".exrc" is not owned by user set 'secure' mode */
				if (stat(EXRC_FILE, &s) || s.st_uid != getuid())
					secure = p_secure;
				else
					secure = 0;
			}
#endif
			if (i == FAIL && fullpathcmp((char_u *)USR_EXRC_FILE,
											 (char_u *)EXRC_FILE) != FPC_SAME)
				(void)do_source((char_u *)EXRC_FILE, FALSE);
		}
		if (secure == 2)
			need_wait_return = TRUE;
		secure = 0;
	}

	/*
	 * Recovery mode without a file name: List swap files.
	 * This uses the 'dir' option, therefore it must be after the
	 * initializations.
	 */
	if (recoverymode && fname == NULL)
	{
		recover_names(NULL, TRUE, 0);
		mch_windexit(0);
	}

	/*
	 * Set a few option defaults after reading .vimrc files:
	 * 'title' and 'icon', Unix: 'shellpipe' and 'shellredir'.
	 */
	set_init_3();

	if (bin_mode)					/* "-b" argument used */
	{
		set_options_bin(curbuf->b_p_bin, 1);
		curbuf->b_p_bin = 1;		/* binary file I/O */
	}

#ifdef USE_GUI
	if (gui.starting)
		gui_start();			/* will set full_screen to TRUE */
#endif

	/*
	 * If we read a .vimrc but it does not contain a "version 4.0" command,
	 * give the user a pointer to the help for the new version.
	 */
	if (check_version && found_version == 0)
	{
		smsg((char_u *)"This is Vim version %s.", Version);
		MSG("No \":version 4.x\" command found in any .vimrc.");
		MSG("Use \":help version\" for info about this new version.");
	}

#ifdef VIMINFO
	/*
	 * Read in registers, history etc, but not marks, from the viminfo file
	 */
	if (*p_viminfo != NUL)
		read_viminfo(NULL, TRUE, FALSE, FALSE);
#endif /* VIMINFO */

#ifdef SPAWNO			/* special MSDOS swapping library */
	init_SPAWNO("", SWAP_ANY);
#endif

	/*
	 * "-q errorfile": Load the error file now.
	 * If the error file can't be read, exit before doing anything else.
	 */
	if (edit_type == EDIT_QF && qf_init() == FAIL)
	{
		outchar('\n');
		mch_windexit(3);
	}

	/*
	 * Don't set the file name if there was a command in .vimrc that already
	 * loaded the file
	 */
	if (curbuf->b_ffname == NULL)
	{
		(void)setfname(fname, NULL, TRUE);	/* includes maketitle() */
		++arg_idx;							/* used first argument name */
	}

	if (window_count == 0)
		window_count = arg_file_count;
	if (window_count > 1)
	{
		/* Don't change the windows if there was a command in .vimrc that
		 * already split some windows */
		if (firstwin->w_next == NULL)
			window_count = make_windows(window_count);
		else
			window_count = win_count();
	}
	else
		window_count = 1;

	/*
	 * Start putting things on the screen.
	 * Scroll screen down before drawing over it
	 * Clear screen now, so file message will not be cleared.
	 */
	starting = FALSE;
	no_wait_return = FALSE;
	msg_scroll = FALSE;
#ifdef USE_GUI
	/*
	 * This seems to be required to make callbacks to be called now, instead
	 * of after things have been put on the screen, which then may be deleted
	 * when getting a resize callback.
	 */
	if (gui.in_use)
		gui_wait_for_chars(50);
#endif

	/*
	 * When done something that is not allowed or error message call
	 * wait_return.  This must be done before starttermcap(), because it may
	 * switch to another screen. It must be done after settmode(TMODE_RAW),
	 * because we want to react on a single key stroke.
	 * Call settmode and starttermcap here, so the T_KS and T_TI may be
	 * defined by termcapinit and redifined in .exrc.
	 */
	settmode(TMODE_RAW);
	if (need_wait_return || msg_didany)
		wait_return(TRUE);

	starttermcap();			/* start termcap if not done by wait_return() */
#ifdef USE_MOUSE
	setmouse();							/* may start using the mouse */
#endif
	if (scroll_region)
		scroll_region_reset();			/* In case Rows changed */

	scroll_start();
	/*
	 * Don't clear the screen when starting in Ex mode, unless using the GUI.
	 */
	if (exmode_active
#ifdef USE_GUI
						&& !gui.in_use
#endif
										)
		redraw_later(CLEAR);
	else
		screenclear();					/* clear screen */

	no_wait_return = TRUE;

	if (recoverymode)					/* do recover */
	{
		msg_scroll = TRUE;				/* scroll message up */
		ml_recover();
		msg_scroll = FALSE;
		if (curbuf->b_ml.ml_mfp == NULL) /* failed */
			getout(1);
		do_modelines();					/* do modelines */
	}
	else
	{
		/*
		 * If "-" argument given: read file from stdin.
		 */
		if (edit_type == EDIT_STDIN)
			(void)open_buffer(TRUE);		/* create memfile and read file */

		/*
		 * Open a buffer for windows that don't have one yet.
		 * Commands in the .vimrc might have loaded a file or split the window.
		 * Watch out for autocommands that delete a window.
		 */
#ifdef AUTOCMD
		/*
		 * Don't execute Win/Buf Enter/Leave autocommands here
		 */
		++autocmd_no_enter;
		++autocmd_no_leave;
#endif
		for (curwin = firstwin; curwin != NULL; curwin = curwin->w_next)
		{
			curbuf = curwin->w_buffer;
			if (curbuf->b_ml.ml_mfp == NULL)
			{
				(void)open_buffer(FALSE);	/* create memfile and read file */
#ifdef AUTOCMD
				curwin = firstwin;			/* start again */
#endif
			}
			ui_breakcheck();
			if (got_int)
			{
				(void)vgetc();	/* only break the file loading, not the rest */
				break;
			}
		}
#ifdef AUTOCMD
		--autocmd_no_enter;
		--autocmd_no_leave;
#endif
		curwin = firstwin;
		curbuf = curwin->w_buffer;
	}

	/* Ex starts at last line of the file */
	if (exmode_active)
		curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;

#ifdef AUTOCMD
	apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE);
#endif
	setpcmark();

	/*
	 * When started with "-q errorfile" jump to first error now.
	 */
	if (edit_type == EDIT_QF)
		qf_jump(0, 0, FALSE);

	/*
	 * If opened more than one window, start editing files in the other
	 * windows.  Make_windows() has already opened the windows.
	 */
#ifdef AUTOCMD
	/*
	 * Don't execute Win/Buf Enter/Leave autocommands here
	 */
	++autocmd_no_enter;
	++autocmd_no_leave;
#endif
	for (i = 1; i < window_count; ++i)
	{
		if (curwin->w_next == NULL)			/* just checking */
			break;
		win_enter(curwin->w_next, FALSE);

		/* Only open the file if there is no file in this window yet (that can
		 * happen when .vimrc contains ":sall") */
		if (curbuf == firstwin->w_buffer || curbuf->b_ffname == NULL)
		{
			curwin->w_arg_idx = arg_idx;
			/* edit file from arg list, if there is one */
			(void)do_ecmd(0,
						 arg_idx < arg_file_count ? arg_files[arg_idx] : NULL,
										  NULL, NULL, (linenr_t)0, ECMD_HIDE);
			if (arg_idx == arg_file_count - 1)
				arg_had_last = TRUE;
			++arg_idx;
		}
		ui_breakcheck();
		if (got_int)
		{
			(void)vgetc();		/* only break the file loading, not the rest */
			break;
		}
	}
#ifdef AUTOCMD
	--autocmd_no_enter;
#endif
	win_enter(firstwin, FALSE);				/* back to first window */
#ifdef AUTOCMD
	--autocmd_no_leave;
#endif
	if (window_count > 1)
		win_equal(curwin, FALSE);			/* adjust heights */

	/*
	 * If there are more file names in the argument list than windows,
	 * put the rest of the names in the buffer list.
	 */
	while (arg_idx < arg_file_count)
		(void)buflist_add(arg_files[arg_idx++]);

	/*
	 * Need to jump to the tag before executing the '-c command'.
	 * Makes "vim -c '/return' -t main" work.
	 */
	if (tagname)
	{
		STRCPY(IObuff, "ta ");
		STRCAT(IObuff, tagname);
		do_cmdline(IObuff, NULL, NULL, DOCMD_NOWAIT|DOCMD_VERBOSE);
	}

	if (command)
	{
		/*
		 * We start commands on line 0, make "vim +/pat file" match a
		 * pattern on line 1.
		 */
		curwin->w_cursor.lnum = 0;
		sourcing_name = (char_u *)"command line";
		do_cmdline(command, NULL, NULL, DOCMD_NOWAIT|DOCMD_VERBOSE);
		sourcing_name = NULL;
		if (curwin->w_cursor.lnum == 0)
			curwin->w_cursor.lnum = 1;
	}

	RedrawingDisabled = FALSE;
	redraw_later(NOT_VALID);
	no_wait_return = FALSE;

	/* start in insert mode */
	if (p_im)
		need_start_insertmode = TRUE;

	/*
	 * main command loop
	 */
	clear_oparg(&oa);
	for (;;)
	{
		if (stuff_empty())
		{
			if (need_check_timestamps)
				check_timestamps();
			if (need_wait_return)		/* if wait_return still needed ... */
				wait_return(FALSE);		/* ... call it now */
			if (need_start_insertmode)
			{
				need_start_insertmode = FALSE;
				stuffReadbuff((char_u *)"i");	/* start insert mode next */
				/* skip the fileinfo message now, because it would be shown
				 * after insert mode finishes! */
				need_fileinfo = FALSE;
			}
		}
		dont_wait_return = FALSE;
		if (got_int && !global_busy)
		{
			(void)vgetc();				/* flush all buffers */
			got_int = FALSE;
		}
		msg_scroll = FALSE;
		quit_more = FALSE;
		keep_help_flag = FALSE;

		/*
		 * Update w_curswant if w_set_curswant has been set.
		 * Postponed until here to avoid computing w_virtcol too often.
		 */
		update_curswant();

		/*
		 * If skip redraw is set (for ":" in wait_return()), don't redraw now.
		 * If there is nothing in the stuff_buffer or do_redraw is TRUE,
		 * update cursor and redraw.
		 */
		if (skip_redraw || exmode_active)
			skip_redraw = FALSE;
		else if (do_redraw || stuff_empty())
		{
			/*
			 * Before redrawing, make sure w_topline is correct, and w_leftcol
			 * if lines don't wrap.
			 */
			update_topline();
			if (!curwin->w_p_wrap)
				validate_cursor();

#ifdef SLEEP_IN_EMSG
			if (need_sleep)				/* sleep before redrawing */
			{
				flushbuf();
				ui_delay(1000L, TRUE);
				need_sleep = FALSE;
			}
#endif
			if (VIsual_active)
				update_curbuf(INVERTED);/* update inverted part */
			if (must_redraw)
				update_screen(must_redraw);
			else if (redraw_cmdline)
				showmode();
			/* display message after redraw */
			if (keep_msg != NULL)
				msg_attr(keep_msg, keep_msg_attr);
			if (need_fileinfo)			/* used after jumping to a tag */
			{
				fileinfo(FALSE, TRUE, FALSE);
				need_fileinfo = FALSE;
			}

			emsg_on_display = FALSE;	/* can delete error message now */
			msg_didany = FALSE;			/* reset lines_left in msg_start() */
			do_redraw = FALSE;
			showruler(FALSE);

			setcursor();
			cursor_on();
		}

		/*
		 * If we're invoked as ex, do a round of ex commands.
		 * Otherwise, get and execute a normal mode command.
		 */
		if (exmode_active)
			do_exmode();
		else
			normal_cmd(&oa);
	}
	/*NOTREACHED*/
}
#endif /* PROTO */

	void
getout(r)
	int 			r;
{
	exiting = TRUE;

	/* Position the cursor on the last screen line, below all the text */
#ifdef USE_GUI
	if (!gui.in_use)
#endif
		windgoto((int)Rows - 1, 0);

#ifdef HAVE_PERL_INTERP
	perl_end();
#endif

#ifdef AUTOCMD
	apply_autocmds(EVENT_VIMLEAVE, NULL, NULL, FALSE);

	/* Position the cursor again, the autocommands may have moved it */
# ifdef USE_GUI
	if (!gui.in_use)
# endif
		windgoto((int)Rows - 1, 0);
#endif

#ifdef VIMINFO
	msg_didany = FALSE;
	/* Write out the registers, history, marks etc, to the viminfo file */
	if (*p_viminfo != NUL)
		write_viminfo(NULL, FALSE);
	if (msg_didany)				/* make the user read the error message */
	{
		no_wait_return = FALSE;
		wait_return(FALSE);
	}
#endif /* VIMINFO */

	mch_windexit(r);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.