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

📄 main.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 3 页
字号:
     * 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();

    /*
     * "-n" argument: Disable swap file by setting 'updatecount' to 0.
     * Note that this overrides anything from a vimrc file.
     */
    if (no_swap_file)
	p_uc = 0;

#ifdef FKMAP
    if (curwin->w_p_rl && p_altkeymap)
    {
	p_hkmap = FALSE;	/* Reset the Hebrew keymap mode */
	p_fkmap = TRUE;		/* Set the Farsi keymap mode */
    }
#endif

    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

#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

#ifdef QUICKFIX
    /*
     * "-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)
    {
	if (use_ef != NULL)
	    set_string_option_direct((char_u *)"ef", -1, use_ef, TRUE);
	if (qf_init(p_ef, p_efm) < 0)
	{
	    out_char('\n');
	    mch_windexit(3);
	}
    }
#endif

    /*
     * 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(50L);
#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
					)
	must_redraw = 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.
	 * Need to stop Raw mode for terminal in case stdin and stderr are the
	 * same terminal: "cat | vim -".
	 */
	if (edit_type == EDIT_STDIN)
	{
	    stoptermcap();
	    settmode(TMODE_COOK);	/* set to normal mode */
	    (void)open_buffer(TRUE);	/* create memfile and read file */
	    if (!termcap_active)	/* if readfile() didn't do it already */
	    {
		settmode(TMODE_RAW);	/* set to raw mode */
		starttermcap();
	    }
	}

	/*
	 * 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, curbuf);
#endif
    setpcmark();

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

    /*
     * 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++]);

    /*
     * Now shorten any of the filenames if possible
     */
    shorten_fnames();

    /*
     * 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 (n_commands > 0)
    {
	/*
	 * 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";
	for (i = 0; i < n_commands; ++i)
	    do_cmdline(commands[i], NULL, NULL, DOCMD_NOWAIT|DOCMD_VERBOSE);
	sourcing_name = NULL;
	if (curwin->w_cursor.lnum == 0)
	    curwin->w_cursor.lnum = 1;

#ifdef QUICKFIX
	/* When started with "-q errorfile" jump to first again. */
	if (edit_type == EDIT_QF)
	    qf_jump(0, 0, FALSE);
#endif
    }

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

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

#ifdef AUTOCMD
    apply_autocmds(EVENT_VIMENTER, NULL, NULL, FALSE, curbuf);
#endif

#if defined(WIN32) && !defined(USE_GUI_WIN32)
    mch_set_winsize_now();	    /* Allow winsize changes from now on */
#endif

    /*
     * 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 && goto_im())
	    {
		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;

	/*
	 * 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, and w_skipcol if lines wrap.
	     */
	    update_topline();
	    validate_cursor();

	    if (VIsual_active)
		update_curbuf(INVERTED);/* update inverted part */
	    else if (must_redraw)
		update_screen(must_redraw);
	    else if (redraw_cmdline || clear_cmdline)
		showmode();
	    redraw_statuslines();
	    /* display message after redraw */
	    if (keep_msg != NULL)
		msg_attr(keep_msg, keep_msg_attr);
	    if (need_fileinfo)		/* show file info after redraw */
	    {
		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();
	}
#ifdef USE_GUI
	if (need_mouse_correct)
	    gui_mouse_correct();
#endif

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

	/*
	 * 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, TRUE);
    }
    /*NOTREACHED*/
#if !defined(MSDOS) || defined(DJGPP)
    return 0;	/* Borland C++ gives a "not reached" error message here */
#endif
}
#endif /* PROTO */

/*
 * Get a (optional) count for a Vim argument.
 */
    static int
get_number_arg(p, idx, def)
    char_u	*p;	    /* pointer to argument */
    int		*idx;	    /* index in argument, is incremented */
    int		def;	    /* default value */
{
    if (isdigit(p[*idx]))
    {
	def = atoi((char *)&(p[*idx]));
	while (isdigit(p[*idx]))
	    *idx = *idx + 1;
    }
    return def;
}

/*
 * Get an evironment variable, and execute it as Ex commands.
 * Returns FAIL if the environment variable was not executed, OK otherwise.
 */
    int
process_env(env)
    char_u	*env;
{
    char_u	*initstr;
    char_u	*save_sourcing_name;

    if ((initstr = mch_getenv(env)) != NULL && *initstr != NUL)
    {
	save_sourcing_name = sourcing_name;
	sourcing_name = env;
	do_cmdline(initstr, NULL, NULL, DOCMD_NOWAIT|DOCMD_VERBOSE);
	sourcing_name = save_sourcing_name;
	return OK;
    }
    return FAIL;
}

    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 AUTOCMD
    apply_autocmds(EVENT_VIMLEAVEPRE, NULL, NULL, FALSE, curbuf);
#endif

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

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

    /* 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 HAVE_PERL_INTERP
    perl_end();
#endif

    mch_windexit(r);
}

/*
 * When FKMAP is defined, also compile the Farsi source code.
 */
#if defined(FKMAP) || defined(PROTO)
# include "farsi.c"
#endif

⌨️ 快捷键说明

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