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

📄 ex_docmd.c

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