📄 ex_docmd.c
字号:
/* for '=' register: accept the rest of the line as an expression */
if (ea.arg[-1] == '=' && ea.arg[0] != NUL)
{
set_expr_line(vim_strsave(ea.arg));
ea.arg += STRLEN(ea.arg);
}
#endif
ea.arg = skipwhite(ea.arg);
}
/*
* Check for a count. When accepting a BUFNAME, don't use "123foo" as a
* count, it's a buffer name.
*/
if ((ea.argt & COUNT) && isdigit(*ea.arg)
&& (!(ea.argt & BUFNAME) || *(p = skipdigits(ea.arg)) == NUL
|| vim_iswhite(*p)))
{
n = getdigits(&ea.arg);
ea.arg = skipwhite(ea.arg);
if (n <= 0)
{
errormsg = e_zerocount;
goto doend;
}
if (ea.argt & NOTADR) /* e.g. :buffer 2, :sleep 3 */
{
ea.line2 = n;
if (ea.addr_count == 0)
ea.addr_count = 1;
}
else
{
ea.line1 = ea.line2;
ea.line2 += n - 1;
++ea.addr_count;
/*
* Be vi compatible: no error message for out of range.
*/
if (ea.line2 > curbuf->b_ml.ml_line_count)
ea.line2 = curbuf->b_ml.ml_line_count;
}
}
/* no arguments allowed */
if (!(ea.argt & EXTRA) && *ea.arg != NUL &&
vim_strchr((char_u *)"|\"", *ea.arg) == NULL)
{
errormsg = e_trailing;
goto doend;
}
if ((ea.argt & NEEDARG) && *ea.arg == NUL)
{
errormsg = e_argreq;
goto doend;
}
if (ea.argt & XFILE)
{
if (expand_filename(&ea, cmdlinep, &errormsg) == FAIL)
goto doend;
}
#ifdef WANT_EVAL
/*
* Skip the command when it's not going to be executed.
* The commands like :if, :endif, etc. always need to be executed.
* Also make an exception for commands that handle a trailing command
* themselves.
*/
if (ea.skip)
{
switch (ea.cmdidx)
{
/* commands that need evaluation */
case CMD_while:
case CMD_endwhile:
case CMD_if:
case CMD_elseif:
case CMD_else:
case CMD_endif:
case CMD_function:
break;
/* commands that handle '|' themselves */
case CMD_call:
case CMD_djump:
case CMD_dlist:
case CMD_dsearch:
case CMD_dsplit:
case CMD_echo:
case CMD_echon:
case CMD_execute:
case CMD_help:
case CMD_ijump:
case CMD_ilist:
case CMD_isearch:
case CMD_isplit:
case CMD_let:
case CMD_return:
case CMD_substitute:
case CMD_smagic:
case CMD_snomagic:
case CMD_syntax:
case CMD_and:
case CMD_tilde:
break;
default: goto doend;
}
}
#endif
/*
* Accept buffer name. Cannot be used at the same time with a buffer
* number.
*/
if ((ea.argt & BUFNAME) && *ea.arg && ea.addr_count == 0)
{
/*
* :bdelete and :bunload take several arguments, separated by spaces:
* find next space (skipping over escaped characters).
* The others take one argument: ignore trailing spaces.
*/
if (ea.cmdidx == CMD_bdelete || ea.cmdidx == CMD_bunload)
p = skiptowhite_esc(ea.arg);
else
{
p = ea.arg + STRLEN(ea.arg);
while (p > ea.arg && vim_iswhite(p[-1]))
--p;
}
ea.line2 = buflist_findpat(ea.arg, p);
if (ea.line2 < 0) /* failed */
goto doend;
ea.addr_count = 1;
ea.arg = skipwhite(p);
}
/*
* 6. switch on command name
*
* The "ea" structure holds the arguments that can be used.
*/
switch (ea.cmdidx)
{
case CMD_quit:
do_quit(&ea);
break;
case CMD_qall:
do_quit_all(ea.forceit);
break;
case CMD_close:
do_close(&ea);
break;
case CMD_hide:
#ifdef USE_GUI
need_mouse_correct = TRUE;
#endif
close_window(curwin, FALSE); /* don't free buffer */
break;
case CMD_only:
#ifdef USE_GUI
need_mouse_correct = TRUE;
#endif
close_others(TRUE, ea.forceit);
break;
case CMD_stop:
case CMD_suspend:
do_suspend(ea.forceit);
break;
case CMD_exit:
case CMD_xit:
case CMD_wq:
do_exit(&ea);
break;
case CMD_xall:
case CMD_wqall:
exiting = TRUE;
/* FALLTHROUGH */
case CMD_wall:
do_wqall(&ea);
break;
case CMD_preserve:
ml_preserve(curbuf, TRUE);
break;
case CMD_recover:
do_recover(&ea);
break;
case CMD_args:
do_args(&ea);
break;
case CMD_wnext:
case CMD_wNext:
case CMD_wprevious:
do_wnext(&ea);
break;
case CMD_next:
case CMD_snext:
do_next(&ea);
break;
case CMD_previous:
case CMD_sprevious:
case CMD_Next:
case CMD_sNext:
do_argfile(&ea, curwin->w_arg_idx - (int)ea.line2);
break;
case CMD_rewind:
case CMD_srewind:
do_argfile(&ea, 0);
break;
case CMD_last:
case CMD_slast:
do_argfile(&ea, arg_file_count - 1);
break;
case CMD_argument:
case CMD_sargument:
if (ea.addr_count)
i = ea.line2 - 1;
else
i = curwin->w_arg_idx;
do_argfile(&ea, i);
break;
case CMD_all:
case CMD_sall:
if (ea.addr_count == 0)
ea.line2 = 9999;
do_arg_all((int)ea.line2, ea.forceit);
break;
case CMD_buffer: /* :[N]buffer [N] to buffer N */
case CMD_sbuffer: /* :[N]sbuffer [N] to buffer N */
if (*ea.arg)
errormsg = e_trailing;
else
{
if (ea.addr_count == 0) /* default is current buffer */
(void)do_buffer(*ea.cmd == 's' ? DOBUF_SPLIT
: DOBUF_GOTO,
DOBUF_CURRENT, FORWARD, 0, ea.forceit);
else
(void)do_buffer(*ea.cmd == 's' ? DOBUF_SPLIT
: DOBUF_GOTO,
DOBUF_FIRST, FORWARD, (int)ea.line2, ea.forceit);
}
break;
case CMD_bmodified: /* :[N]bmod [N] to next mod. buffer */
case CMD_sbmodified: /* :[N]sbmod [N] to next mod. buffer */
(void)do_buffer(*ea.cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO,
DOBUF_MOD, FORWARD, (int)ea.line2, ea.forceit);
break;
case CMD_bnext: /* :[N]bnext [N] to next buffer */
case CMD_sbnext: /* :[N]sbnext [N] to next buffer */
(void)do_buffer(*ea.cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO,
DOBUF_CURRENT, FORWARD, (int)ea.line2, ea.forceit);
break;
case CMD_bNext: /* :[N]bNext [N] to previous buffer */
case CMD_bprevious: /* :[N]bprevious [N] to previous buffer */
case CMD_sbNext: /* :[N]sbNext [N] to previous buffer */
case CMD_sbprevious: /* :[N]sbprevious [N] to previous buffer */
(void)do_buffer(*ea.cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO,
DOBUF_CURRENT, BACKWARD, (int)ea.line2, ea.forceit);
break;
case CMD_brewind: /* :brewind to first buffer */
case CMD_sbrewind: /* :sbrewind to first buffer */
(void)do_buffer(*ea.cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO,
DOBUF_FIRST, FORWARD, 0, ea.forceit);
break;
case CMD_blast: /* :blast to last buffer */
case CMD_sblast: /* :sblast to last buffer */
(void)do_buffer(*ea.cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO,
DOBUF_LAST, FORWARD, 0, ea.forceit);
break;
case CMD_bunload: /* :[N]bunload[!] [N] [bufname] unload buffer */
case CMD_bdelete: /* :[N]bdelete[!] [N] [bufname] delete buffer */
errormsg = do_bufdel(ea.cmdidx == CMD_bdelete ? DOBUF_DEL
: DOBUF_UNLOAD,
ea.arg, ea.addr_count, (int)ea.line1,
(int)ea.line2, ea.forceit);
break;
case CMD_unhide:
case CMD_sunhide:
if (ea.addr_count == 0)
ea.line2 = 9999;
(void)do_buffer_all((int)ea.line2, FALSE);
break;
case CMD_ball:
case CMD_sball:
if (ea.addr_count == 0)
ea.line2 = 9999;
(void)do_buffer_all((int)ea.line2, TRUE);
break;
case CMD_buffers:
case CMD_files:
case CMD_ls:
buflist_list();
break;
case CMD_update:
if (curbuf_changed())
(void)do_write(&ea);
break;
case CMD_write:
if (ea.usefilter) /* input lines to shell command */
do_bang(1, ea.line1, ea.line2, FALSE, ea.arg, TRUE, FALSE);
else
(void)do_write(&ea);
break;
/*
* set screen mode
* if no argument given, just get the screen size and redraw
*/
case CMD_mode:
if (*ea.arg == NUL || mch_screenmode(ea.arg) != FAIL)
set_winsize(0, 0, FALSE);
break;
case CMD_resize:
do_resize(&ea);
break;
case CMD_sview:
case CMD_split:
case CMD_new:
do_splitview(&ea);
break;
case CMD_edit:
case CMD_ex:
case CMD_visual:
case CMD_view:
case CMD_badd:
do_exedit(&ea, NULL);
break;
#ifdef USE_GUI
/*
* Change from the terminal version to the GUI version. File names
* may be given to redefine the args list -- webb
*/
case CMD_gvim:
case CMD_gui:
do_gui(&ea);
break;
#endif
#ifdef USE_GUI_WIN32
case CMD_tearoff:
gui_make_tearoff(ea.arg);
break;
#endif
case CMD_behave:
ex_behave(ea.arg);
break;
case CMD_browse:
#ifdef USE_BROWSE
/* don't browse in an xterm! */
if (gui.in_use)
browse = TRUE;
#endif
ea.nextcmd = ea.arg;
break;
#ifdef USE_GUI_WIN32
case CMD_simalt:
gui_simulate_alt_key(ea.arg);
break;
case CMD_promptfind:
gui_mch_find_dialog(ea.arg);
break;
case CMD_promptrepl:
gui_mch_replace_dialog(ea.arg);
break;
#endif
case CMD_confirm:
#if defined(GUI_DIALOG) || defined(CON_DIALOG)
confirm = TRUE;
#endif
ea.nextcmd = ea.arg;
break;
case CMD_file:
do_file(ea.arg, ea.forceit);
break;
case CMD_swapname:
do_swapname();
break;
case CMD_read:
do_read(&ea);
break;
case CMD_cd:
case CMD_chdir:
do_cd(&ea);
break;
case CMD_pwd:
do_pwd();
break;
case CMD_equal:
smsg((char_u *)"line %ld", (long)ea.line2);
break;
case CMD_list:
i = curwin->w_p_list;
curwin->w_p_list = 1;
do_print(&ea);
curwin->w_p_list = i;
break;
case CMD_number:
case CMD_pound: /* :# */
case CMD_print:
case CMD_Print: /* ":Print" does as ":print" */
do_print(&ea);
break;
case CMD_shell:
do_shell(NULL, 0);
break;
case CMD_sleep:
do_sleep(&ea);
break;
case CMD_stag:
postponed_split = -1;
/*FALLTHROUGH*/
case CMD_tag:
#ifdef USE_CSCOPE
if (p_cst)
do_cstag(&ea);
else
#endif
do_tag(ea.arg, DT_TAG,
ea.addr_count ? (int)ea.line2 : 1, ea.forceit, TRUE);
break;
case CMD_stselect:
postponed_split = -1;
/*FALLTHROUGH*/
case CMD_tselect:
do_tag(ea.arg, DT_SELECT, 0, ea.forceit, TRUE);
break;
case CMD_stjump:
postponed_split = -1;
/*FALLTHROUGH*/
case CMD_tjump:
do_tag(ea.arg, DT_JUMP, 0, ea.forceit, TRUE);
break;
case CMD_pop: do_ex_tag(&ea, DT_POP); break;
case CMD_tnext: do_ex_tag(&ea, DT_NEXT); break;
case CMD_tNext:
case CMD_tprevious: do_ex_tag(&ea, DT_PREV); break;
case CMD_trewind: do_ex_tag(&ea, DT_FIRST); break;
case CMD_tlast: do_ex_tag(&ea, DT_LAST); break;
case CMD_tags:
do_tags();
break;
#ifdef USE_CSCOPE
case CMD_cscope:
do_cscope(&ea);
break;
case CMD_cstag:
do_cstag(&ea);
break;
#endif
case CMD_marks:
do_marks(ea.arg);
break;
case CMD_jumps:
do_jumps();
break;
case CMD_ascii:
do_ascii();
break;
#ifdef FIND_IN_PATH
case CMD_checkpath:
find_pattern_in_path(NULL, 0, 0, FALSE, FALSE, CHECK_PATH, 1L,
ea.forceit ? ACTION_SHOW_ALL : ACTION_SHOW,
(linenr_t)1, (linenr_t)MAXLNUM);
break;
#endif
case CMD_digraphs:
#ifdef DIGRAPHS
if (*ea.arg)
putdigraph(ea.arg);
else
listdigraphs();
#else
EMSG("No digraphs in this version");
#endif
break;
case CMD_set:
(void)do_set(ea.arg);
break;
case CMD_fixdel:
do_fixdel();
break;
#ifdef AUTOCMD
case CMD_augroup:
case CMD_autocmd:
/*
* Disallow auto commands from .exrc and .vimrc in current
* directory for security reasons.
*/
if (secure)
{
secure = 2;
errormsg = e_curdir;
}
else if (ea.cmdidx == CMD_autocmd)
do_autocmd(ea.arg, ea.forceit);
else
do_augroup(ea.arg);
break;
/*
* Apply the automatic commands to all loaded buffers.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -