⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 3 页
字号:
/* vi:set ts=8 sts=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"

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

static void mainerr __ARGS((int, char_u *));
static void main_msg __ARGS((char *s));
static void usage __ARGS((void));
static int get_number_arg __ARGS((char_u *p, int *idx, int def));

/*
 * Type of error message.  These must match with errors[] in mainerr().
 */
#define ME_UNKNOWN_OPTION	0
#define ME_TOO_MANY_ARGS	1
#define ME_ARG_MISSING		2
#define ME_GARBAGE		3
#define ME_EXTRA_CMD		4

    static void
mainerr(n, str)
    int	    n;
    char_u  *str;
{
    static char	*(errors[]) =
    {
	"Unknown option",
	"Too many edit arguments",
	"Argument missing after",
	"Garbage after option",
	"Too many \"+command\" or \"-c command\" arguments",
    };

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

    mch_errmsg(longVersion);
    mch_errmsg("\n");
    mch_errmsg(errors[n]);
    if (str != NULL)
    {
	mch_errmsg(": \"");
	mch_errmsg((char *)str);
	mch_errmsg("\"");
    }
    mch_errmsg("\nMore info with: \"vim -h\"\n");

    mch_windexit(1);
}

/*
 * print a message with three spaces prepended and '\n' appended.
 */
    static void
main_msg(s)
    char *s;
{
    mch_msg("   ");
    mch_msg(s);
    mch_msg("\n");
}

    static void
usage()
{
    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",
#ifdef QUICKFIX
	(char_u *)"-q [errorfile]  edit file with first error"
#endif
    };

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

    mch_msg(longVersion);
    mch_msg("\nusage:");
    for (i = 0; ; ++i)
    {
	mch_msg(" vim [options] ");
	mch_msg((char *)use[i]);
	if (i == (sizeof(use) / sizeof(char_u *)) - 1)
	    break;
	mch_msg("\n   or:");
    }

    mch_msg("\n\nOptions:\n");
    main_msg("--\t\t\tEnd of options");
#ifdef HAVE_OLE
    main_msg("-register\t\tRegister this gvim for OLE");
    main_msg("-unregister\t\tUnregister gvim for OLE");
#endif
#ifdef USE_GUI
    main_msg("-g\t\t\tRun using GUI (like \"gvim\")");
    main_msg("-f\t\t\tForeground: Don't fork when starting GUI");
#endif
    main_msg("-v\t\t\tVi mode (like \"vi\")");
    main_msg("-e\t\t\tEx mode (like \"ex\")");
    main_msg("-s\t\t\tSilent (batch) mode (only for \"ex\")");
    main_msg("-R\t\t\tReadonly mode (like \"view\")");
    main_msg("-Z\t\t\tRestricted mode (like \"rvim\")");
    main_msg("-b\t\t\tBinary mode");
#ifdef LISPINDENT
    main_msg("-l\t\t\tLisp mode");
#endif
    main_msg("-C\t\t\tCompatible with Vi: 'compatible'");
    main_msg("-N\t\t\tNot fully Vi compatible: 'nocompatible'");
    main_msg("-V[N]\t\tVerbose level");
    main_msg("-n\t\t\tNo swap file, use memory only");
    main_msg("-r\t\t\tList swap files and exit");
    main_msg("-r (with file name)\tRecover crashed session");
    main_msg("-L\t\t\tSame as -r");
#ifdef AMIGA
    main_msg("-f\t\t\tDon't use newcli to open window");
    main_msg("-d <device>\t\tUse <device> for I/O");
#endif
#ifdef RIGHTLEFT
    main_msg("-H\t\t\tstart in Hebrew mode");
#endif
#ifdef FKMAP
    main_msg("-F\t\t\tstart in Farsi mode");
#endif
    main_msg("-T <terminal>\tSet terminal type to <terminal>");
    main_msg("-o[N]\t\tOpen N windows (default: one for each file)");
    main_msg("+\t\t\tStart at end of file");
    main_msg("+<lnum>\t\tStart at line <lnum>");
    main_msg("-c <command>\t\tExecute <command> first");
    main_msg("-s <scriptin>\tRead commands from script file <scriptin>");
    main_msg("-w <scriptout>\tAppend commands to script file <scriptout>");
    main_msg("-W <scriptout>\tWrite commands to script file <scriptout>");
    main_msg("-u <vimrc>\t\tUse <vimrc> instead of any .vimrc");
#ifdef USE_GUI
    main_msg("-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc");
#endif
#ifdef VIMINFO
    main_msg("-i <viminfo>\t\tUse <viminfo> instead of .viminfo");
#endif
    main_msg("-h\t\t\tprint Help (this message) and exit");
    main_msg("--version\t\tprint version information and exit");

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

    mch_windexit(1);
}

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

/* Maximum number of commands from + or -c options */
#define MAX_ARG_CMDS 10

#ifndef PROTO	    /* don't want a prototype for main() */
    int
#ifdef VIMDLL
_export
#endif
main(argc, argv)
    int		    argc;
    char	  **argv;
{
    char_u	   *initstr;		    /* init string from environment */
    char_u	   *term = NULL;	    /* specified terminal name */
    char_u	   *fname = NULL;	    /* file name from command line */
    char_u	   *tagname = NULL;	    /* tag from -t option */
    char_u	   *use_vimrc = NULL;	    /* vimrc from -u option */
#ifdef QUICKFIX
    char_u	   *use_ef = NULL;	    /* 'errorfile' from -q option */
#endif
    int		    n_commands = 0;	    /* no. of commands from + or -c */
    char_u	   *commands[MAX_ARG_CMDS]; /* commands from + or -c option */
    int		    no_swap_file = FALSE;   /* "-n" option used */
    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 "--" option */
    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	    /* file name 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;	    /* is stdout a terminal? */
    int		    input_isatty;	    /* is active input a terminal? */
    OPARG	    oa;			    /* operator arguments */

#ifdef RISCOS
    /* Turn off all the horrible filename munging in UnixLib. */
    __uname_control = __UNAME_NO_PROCESS;
#endif

#if defined(MSDOS) || defined(WIN32) || defined(OS2)
    /*
     * Default mappings for some often used keys.
     * Use the Windows (CUA) keybindings.
     */
    static struct initmap
    {
	char_u	    *arg;
	int	    mode;
    } initmappings[] =
    {
# ifdef USE_GUI
	{(char_u *)"<C-PageUp> H", NORMAL+VISUAL},
	{(char_u *)"<C-PageUp> <C-O>H",INSERT},
	{(char_u *)"<C-PageDown> L$", NORMAL+VISUAL},
	{(char_u *)"<C-PageDown> <C-O>L<C-O>$", INSERT},

	/* paste, copy and cut */
	{(char_u *)"<S-Insert> \"*P", NORMAL},
	{(char_u *)"<S-Insert> \"-d\"*P", VISUAL},
	{(char_u *)"<S-Insert> <C-R>*", INSERT+CMDLINE},
	{(char_u *)"<C-Insert> \"*y", VISUAL},
	{(char_u *)"<S-Del> \"*d", VISUAL},
	{(char_u *)"<C-Del> \"*d", VISUAL},
	{(char_u *)"<C-X> \"*d", VISUAL},
	/* Missing: CTRL-C (can't be mapped) and CTRL-V (means something) */
# else
	{(char_u *)"\316\204 H", NORMAL+VISUAL},    /* CTRL-PageUp is "H" */
	{(char_u *)"\316\204 \017H",INSERT},	    /* CTRL-PageUp is "^OH"*/
	{(char_u *)"\316v L$", NORMAL+VISUAL},	    /* CTRL-PageDown is "L$" */
	{(char_u *)"\316v \017L\017$", INSERT},	    /* CTRL-PageDown ="^OL^O$"*/
	{(char_u *)"\316w <C-Home>", NORMAL+VISUAL},
	{(char_u *)"\316w <C-Home>", INSERT+CMDLINE},
	{(char_u *)"\316u <C-End>", NORMAL+VISUAL},
	{(char_u *)"\316u <C-End>", INSERT+CMDLINE},

	/* paste, copy and cut */
#  ifdef USE_CLIPBOARD
	{(char_u *)"\316\324 \"*P", NORMAL},	    /* SHIFT-Insert is "*P */
	{(char_u *)"\316\324 \"-d\"*P", VISUAL},    /* SHIFT-Insert is "-d"*P */
	{(char_u *)"\316\324 \017\"*P", INSERT},    /* SHIFT-Insert is ^O"*P */
	{(char_u *)"\316\325 \"*y", VISUAL},	    /* CTRL-Insert is "*y */
	{(char_u *)"\316\327 \"*d", VISUAL},	    /* SHIFT-Del is "*d */
	{(char_u *)"\316\330 \"*d", VISUAL},	    /* CTRL-Del is "*d */
	{(char_u *)"\030 \"-d", VISUAL},	    /* CTRL-X is "-d */
#  else
	{(char_u *)"\316\324 P", NORMAL},	    /* SHIFT-Insert is P */
	{(char_u *)"\316\324 d\"0P", VISUAL},	    /* SHIFT-Insert is d"0P */
	{(char_u *)"\316\324 \017P", INSERT},	    /* SHIFT-Insert is ^OP */
	{(char_u *)"\316\325 y", VISUAL},	    /* CTRL-Insert is y */
	{(char_u *)"\316\327 d", VISUAL},	    /* SHIFT-Del is d */
	{(char_u *)"\316\330 d", VISUAL},	    /* CTRL-Del is d */
#  endif
# endif
    };
#endif

#if defined(macintosh)
    /*
     * Default mappings for some often used keys.
     * Use the Standard MacOS binding.
     */
    static struct initmap
    {
	char_u	    *arg;
	int	    mode;
    } initmappings[] =
    {
	/* paste, copy and cut */
	{(char_u *)"<D-v> \"*P", NORMAL},
	{(char_u *)"<D-v> \"-d\"*P", VISUAL},
	{(char_u *)"<D-v> <C-R>*", INSERT+CMDLINE},
	{(char_u *)"<D-c> \"*y", VISUAL},
	{(char_u *)"<D-x> \"*d", VISUAL},
	{(char_u *)"<Backspace> \"-d", VISUAL},
    };
#endif

#ifdef MEM_PROFILE
    atexit(vim_mem_profile_dump);
#endif

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

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

#if defined(USE_GUI_WIN32) && defined(HAVE_OLE)
    /* Check for special OLE command line parameters */
    if (argc == 2 && (argv[1][0] == '-' || argv[1][0] == '/'))
    {
	/* Register Vim as an OLE Automation server */
	if (STRICMP(argv[1] + 1, "register") == 0)
	{
	    RegisterMe();
	    mch_windexit(0);
	}

	/* Unregister Vim as an OLE Automation server */
	if (STRICMP(argv[1] + 1, "unregister") == 0)
	{
	    UnregisterMe(TRUE);
	    mch_windexit(0);
	}

	/* Ignore an -embedding argument. It is only relevant if the
	 * application wants to treat the case when it is started manually
	 * differently from the case where it is started via automation (and
	 * we don't).
	 */
	if (STRICMP(argv[1] + 1, "embedding") == 0)
	    argc = 1;
    }

    {
	int	bDoRestart = FALSE;

	InitOLE(&bDoRestart);
	/* automatically exit after registering */
	if (bDoRestart)
	    mch_windexit(0);
    }
#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;
    curbuf->b_nwindows = 1;	/* there is one window */
    win_init(curwin);		/* init current window */
    init_yank();		/* init yank buffers */

    /*
     * 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
	mch_errmsg((char *)e_nogvim);
	mch_windexit(2);
#endif
    }

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

    if (STRNCMP(initstr, "ex", 2) == 0)
    {
	exmode_active = TRUE;
	change_compatible(TRUE);	/* set 'compatible' */
    }

    /*
     * 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;

#ifndef macintosh
    /*
     * Allocate arg_files[], big enough to hold all potential file name
     * arguments.
     */
    arg_files = (char_u **)alloc((unsigned)(sizeof(char_u *) * (argc + 1)));
    if (arg_files == NULL)
	mch_windexit(2);
#else
    arg_files = NULL;
#endif
    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 (n_commands >= MAX_ARG_CMDS)
		mainerr(ME_EXTRA_CMD, NULL);
	    argv_idx = -1;	    /* skip to next argument */
	    if (argv[0][1] == NUL)
		commands[n_commands++] = (char_u *)"$";
	    else
		commands[n_commands++] = (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)
		    mainerr(ME_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 */
				/* "--help" give help message */
				/* "--version" give version message */
		if (STRCMP(argv[0] + argv_idx, "help") == 0)
		    usage();
		if (STRCMP(argv[0] + argv_idx, "version") == 0)
		{
		    Columns = 80;	/* need to init Columns */
		    do_version((char_u *)"");
		    mch_windexit(1);
		}
		if (argv[0][argv_idx])
		    mainerr(ME_UNKNOWN_OPTION, (char_u *)argv[0]);
		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 'C':		/* "-C"  Compatible */
		change_compatible(TRUE);
		break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -