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

📄 normal.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
 * Variables available here:
 * ca.cmdchar	command character
 * ca.nchar	extra command character
 * ca.count0	count before command (0 if no count given)
 * ca.count1	count before command (1 if no count given)
 * oap		Operator Arguments (same as ca.oap)
 * flag		is FALSE, use as you like.
 * dir		is FORWARD, use as you like.
 */
    switch (ca.cmdchar)
    {
/*
 * 0: Macros
 */
    case 'q':
	if (oap->op_type == OP_FORMAT)
	    nv_operator(&ca);		/* "gqq": format line */
	else if (!checkclearop(oap))
	{
	    /* (stop) recording into a named register */
	    /* command is ignored while executing a register */
	    if (!Exec_reg && do_record(ca.nchar) == FAIL)
		clearopbeep(oap);
	}
	break;

    case '@':		/* execute a named register */
	nv_at(&ca);
	break;

/*
 * 1: Screen positioning commands
 */
    case Ctrl('D'):
    case Ctrl('U'):
	nv_halfpage(&ca);
	break;

    case Ctrl('B'):
    case K_S_UP:
    case K_PAGEUP:
    case K_KPAGEUP:
	dir = BACKWARD;

    case Ctrl('F'):
    case K_S_DOWN:
    case K_PAGEDOWN:
    case K_KPAGEDOWN:
	if (checkclearop(oap))
	    break;
	(void)onepage(dir, ca.count1);
	break;

    case Ctrl('E'):
	flag = TRUE;
	/* FALLTHROUGH */

    case Ctrl('Y'):
	nv_scroll_line(&ca, flag);
	break;

    case 'z':
	if (!checkclearop(oap))
	    nv_zet(&ca);
	break;

/*
 * 2: Control commands
 */
    case ':':
	   nv_colon(&ca);
	   break;

    case 'Q':
	/*
	 * Ignore 'Q' in Visual mode, just give a beep.
	 */
	if (VIsual_active)
	    vim_beep();
	else if (!checkclearop(oap))
	    do_exmode();
	break;

    case K_HELP:
    case K_F1:
	if (!checkclearopq(oap))
	    do_help(NULL);
	break;

    case Ctrl('L'):
	if (!checkclearop(oap))
	{
#if defined(__BEOS__) && !USE_THREAD_FOR_INPUT_WITH_TIMEOUT
	    /*
	     * Right now, the BeBox doesn't seem to have an easy way to detect
	     * window resizing, so we cheat and make the user detect it
	     * manually with CTRL-L instead
	     */
	    ui_get_winsize();
#endif
	    update_screen(CLEAR);
	}
	break;

    case Ctrl('G'):
	nv_ctrlg(&ca);
	break;

    case K_CCIRCM:	    /* CTRL-^, short for ":e #" */
	if (!checkclearopq(oap))
	    (void)buflist_getfile((int)ca.count0, (linenr_t)0,
						GETF_SETMARK|GETF_ALT, FALSE);
	break;

    case 'Z':
	nv_zzet(&ca);
	break;

    case 163:			/* the pound sign, '#' for English keyboards */
	ca.cmdchar = '#';
	/*FALLTHROUGH*/

    case Ctrl(']'):		/* :ta to current identifier */
    case 'K':			/* run program for current identifier */
    case '*':			/* / to current identifier or string */
    case K_KMULTIPLY:		/* same as '*' */
    case '#':			/* ? to current identifier or string */
	if (ca.cmdchar == K_KMULTIPLY)
	    ca.cmdchar = '*';
	nv_ident(&ca, &searchbuff);
	break;

    case Ctrl('T'):		/* backwards in tag stack */
	if (!checkclearopq(oap))
	    do_tag((char_u *)"", DT_POP, (int)ca.count1, FALSE, TRUE);
	break;

/*
 * Cursor motions
 */
    case 'G':
	nv_goto(oap, ca.count0 == 0 ? (long)curbuf->b_ml.ml_line_count
				    : ca.count0);
	break;

    case 'H':
    case 'M':
    case 'L':
	nv_scroll(&ca);
	break;

    case K_RIGHT:
	if (mod_mask & MOD_MASK_CTRL)
	{
	    oap->inclusive = FALSE;
	    nv_wordcmd(&ca, 1);
	    break;
	}
    case 'l':
    case ' ':
	nv_right(&ca);
	break;

    case K_LEFT:
	if (mod_mask & MOD_MASK_CTRL)
	{
	    nv_bck_word(&ca, 1);
	    break;
	}
    case 'h':
	dont_adjust_op_end = nv_left(&ca);
	break;

    case K_BS:
    case Ctrl('H'):
	if (VIsual_active && VIsual_select)
	{
	    ca.cmdchar = 'x';	/* BS key behaves like 'x' in Select mode */
	    v_visop(&ca);
	}
	else
	    dont_adjust_op_end = nv_left(&ca);
	break;

    case '-':
    case K_KMINUS:
	flag = TRUE;
	/* FALLTHROUGH */

    case 'k':
    case K_UP:
    case Ctrl('P'):
	oap->motion_type = MLINE;
	if (cursor_up(ca.count1, oap->op_type == OP_NOP) == FAIL)
	    clearopbeep(oap);
	else if (flag)
	    beginline(BL_WHITE | BL_FIX);
	break;

    case '+':
    case K_KPLUS:
    case CR:
    case K_KENTER:
	flag = TRUE;
	/* FALLTHROUGH */

    case 'j':
    case K_DOWN:
    case Ctrl('N'):
    case NL:
	oap->motion_type = MLINE;
	if (cursor_down(ca.count1, oap->op_type == OP_NOP) == FAIL)
	    clearopbeep(oap);
	else if (flag)
	    beginline(BL_WHITE | BL_FIX);
	break;

	/*
	 * This is a strange motion command that helps make operators more
	 * logical. It is actually implemented, but not documented in the
	 * real Vi. This motion command actually refers to "the current
	 * line". Commands like "dd" and "yy" are really an alternate form of
	 * "d_" and "y_". It does accept a count, so "d3_" works to delete 3
	 * lines.
	 */
    case '_':
	nv_lineop(&ca);
	break;

    case K_HOME:
    case K_KHOME:
    case K_S_HOME:
	if ((mod_mask & MOD_MASK_CTRL))	    /* CTRL-HOME = goto line 1 */
	{
	    nv_goto(oap, 1L);
	    break;
	}
	ca.count0 = 1;
	/* FALLTHROUGH */

    case '|':
	nv_pipe(&ca);
	break;

    /*
     * Word Motions
     */
    case 'B':
	type = 1;
	/* FALLTHROUGH */

    case 'b':
    case K_S_LEFT:
	nv_bck_word(&ca, type);
	break;

    case 'E':
	type = TRUE;
	/* FALLTHROUGH */

    case 'e':
	oap->inclusive = TRUE;
	nv_wordcmd(&ca, type);
	break;

    case 'W':
	type = TRUE;
	/* FALLTHROUGH */

    case 'w':
    case K_S_RIGHT:
	oap->inclusive = FALSE;
	nv_wordcmd(&ca, type);
	break;

    case K_END:
    case K_KEND:
    case K_S_END:
	if ((mod_mask & MOD_MASK_CTRL))	    /* CTRL-END = goto last line */
	    nv_goto(oap, curbuf->b_ml.ml_line_count);
	/* FALLTHROUGH */

    case '$':
	oap->motion_type = MCHAR;
	oap->inclusive = TRUE;
	curwin->w_curswant = MAXCOL;		    /* so we stay at the end */
	if (cursor_down((long)(ca.count1 - 1), oap->op_type == OP_NOP) == FAIL)
	    clearopbeep(oap);
	break;

    case '^':
	flag = BL_WHITE | BL_FIX;
	/* FALLTHROUGH */

    case '0':
	oap->motion_type = MCHAR;
	oap->inclusive = FALSE;
	beginline(flag);
	break;

/*
 * 4: Searches
 */
    case K_KDIVIDE:
	ca.cmdchar = '/';
	/* FALLTHROUGH */
    case '?':
    case '/':
	nv_search(&ca, &searchbuff, FALSE);
	break;

    case 'N':
	flag = SEARCH_REV;
	/* FALLTHROUGH */

    case 'n':
	nv_next(&ca, flag);
	break;

	/*
	 * Character searches
	 */
    case 'T':
	dir = BACKWARD;
	/* FALLTHROUGH */

    case 't':
	nv_csearch(&ca, dir, TRUE);
	break;

    case 'F':
	dir = BACKWARD;
	/* FALLTHROUGH */

    case 'f':
	nv_csearch(&ca, dir, FALSE);
	break;

    case ',':
	flag = 1;
	/* FALLTHROUGH */

    case ';':
	/* ca.nchar == NUL, thus repeat previous search */
	nv_csearch(&ca, flag, FALSE);
	break;

	/*
	 * section or C function searches
	 */
    case '[':
	dir = BACKWARD;
	/* FALLTHROUGH */

    case ']':
	nv_brackets(&ca, dir);
	break;

    case '%':
	nv_percent(&ca);
	break;

    case '(':
	dir = BACKWARD;
	/* FALLTHROUGH */

    case ')':
	nv_brace(&ca, dir);
	break;

    case '{':
	dir = BACKWARD;
	/* FALLTHROUGH */

    case '}':
	oap->motion_type = MCHAR;
	oap->inclusive = FALSE;
	curwin->w_set_curswant = TRUE;
	if (!findpar(oap, dir, ca.count1, NUL, FALSE))
	    clearopbeep(oap);
	break;

/*
 * 5: Edits
 */
    case '.':		    /* redo command */
	if (!checkclearopq(oap))
	{
	    /*
	     * if restart_edit is TRUE, the last but one command is repeated
	     * instead of the last command (inserting text). This is used for
	     * CTRL-O <.> in insert mode
	     */
	    if (start_redo(ca.count0, restart_edit && !arrow_used) == FAIL)
		clearopbeep(oap);
	}
	break;

    case 'u':		    /* undo */
	if (VIsual_active || oap->op_type == OP_LOWER)
	{
	    nv_operator(&ca);
	    break;
	}
	/* FALLTHROUGH */

    case K_UNDO:
	if (!checkclearopq(oap))
	{
	    u_undo((int)ca.count1);
	    curwin->w_set_curswant = TRUE;
	}
	break;

    case Ctrl('R'):	/* undo undo */
	if (!checkclearopq(oap))
	{
	    u_redo((int)ca.count1);
	    curwin->w_set_curswant = TRUE;
	}
	break;

    case 'U':		    /* Undo line */
	nv_Undo(&ca);
	break;

    case 'r':
	if (VIsual_active)
	{
	    ca.cmdchar = 'c';
	    nv_operator(&ca);
	    break;
	}
	if (!checkclearop(oap))
	    command_busy = n_replace(&ca);
	break;

    case 'J':
	ca.oap->op_prechar = NUL;	/* Thus not 'g', as in "gJ" */
	nv_join(&ca);
	break;

    case 'P':
    case 'p':
	nv_put(&ca);
	break;

    case Ctrl('A'):	    /* add to number */
    case Ctrl('X'):	    /* subtract from number */
	if (!checkclearopq(oap) && do_addsub((int)ca.cmdchar, ca.count1) == OK)
	    prep_redo_cmd(&ca);
	break;

/*
 * 6: Inserts
 */
    case 'A':
	if (checkclearopq(oap))
	    break;
	/* FALLTHROUGH */

    case 'a':
	command_busy = nv_append(&ca);
	break;

    case 'I':
	if (checkclearopq(oap))
	    break;
	beginline(BL_WHITE);
	/* FALLTHROUGH */

    case 'i':
	if (ca.cmdchar == 'i' && (oap->op_type != OP_NOP || VIsual_active))
	{
#ifdef TEXT_OBJECTS
	    nv_object(&ca);	/* 'i'nner text object */
#else
	    clearopbeep(oap);
#endif
	    break;
	}
	/* FALLTHROUGH */

    case K_INS:
	if (!checkclearopq(oap))
	{
	    if (u_save_cursor() == OK)
		command_busy = edit(ca.cmdchar, FALSE, ca.count1);
	}
	break;

    case 'o':
    case 'O':
	if (VIsual_active)  /* switch start and end of visual */
	    v_swap_corners(&ca);
	else
	    command_busy = n_opencmd(&ca);
	break;

    case 'R':
	command_busy = nv_replace(&ca);
	break;

/*
 * 7: Operators
 */
    case '~':	    /* swap case */
	/*
	 * if tilde is not an operator and Visual is off: swap case
	 * of a single character
	 */
	if (	   !p_to

⌨️ 快捷键说明

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