📄 main.c
字号:
* 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 + -