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

📄 normal.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
		&& !VIsual_active
		&& oap->op_type != OP_TILDE)
	{
	    n_swapchar(&ca);
	    break;
	}
	/*FALLTHROUGH*/

    case 'd':
    case 'c':
    case 'y':
    case '>':
    case '<':
    case '!':
    case '=':
	nv_operator(&ca);
	break;

/*
 * 8: Abbreviations
 */

    case 'S':
    case 's':
	if (VIsual_active)	/* "vs" and "vS" are the same as "vc" */
	{
	    if (ca.cmdchar == 'S')
		VIsual_mode = 'V';
	    ca.cmdchar = 'c';
	    nv_operator(&ca);
	    break;
	}
	/* FALLTHROUGH */
    case K_DEL:
    case 'Y':
    case 'D':
    case 'C':
    case 'x':
    case 'X':
	if (ca.cmdchar == K_DEL)
	    ca.cmdchar = 'x';		/* DEL key behaves like 'x' */

	/* with Visual these commands are operators */
	if (VIsual_active)
	{
	    v_visop(&ca);
	    break;
	}
	/* FALLTHROUGH */

    case '&':
	nv_optrans(&ca);
	opnum = 0;
	break;

/*
 * 9: Marks
 */
    case 'm':
	if (!checkclearop(oap))
	{
	    if (setmark(ca.nchar) == FAIL)
		clearopbeep(oap);
	}
	break;

    case '\'':
	flag = TRUE;
	/* FALLTHROUGH */

    case '`':
	nv_gomark(&ca, flag);
	break;

    case Ctrl('O'):
	/* switch from Select to Visual mode for one command */
	if (VIsual_active && VIsual_select)
	{
	    VIsual_select = FALSE;
	    showmode();
	    restart_VIsual_select = 2;
	    break;
	}
	ca.count1 = -ca.count1;	/* goto older pcmark */
	/* FALLTHROUGH */

    case Ctrl('I'):		/* goto newer pcmark */
	nv_pcmark(&ca);
	break;

/*
 * 10. Register name setting
 */
    case '"':
	nv_regname(&ca, &opnum);
	break;

/*
 * 11. Visual
 */
    case 'v':
    case 'V':
    case Ctrl('V'):
	if (!checkclearop(oap))
	    nv_visual(&ca, FALSE);
	break;

/*
 * 12. Suspend
 */

    case Ctrl('Z'):
	clearop(oap);
	if (VIsual_active)
	    end_visual_mode();		    /* stop Visual */
	stuffReadbuff((char_u *)":st\r");   /* with autowrite */
	break;

/*
 * 13. Window commands
 */

    case Ctrl('W'):
	if (!checkclearop(oap))
	    do_window(ca.nchar, ca.count0);	/* everything is in window.c */
	break;

/*
 *   14. extended commands (starting with 'g')
 */
    case 'g':
	command_busy = nv_g_cmd(&ca, &searchbuff);
	break;

/*
 * 15. mouse click
 */
#ifdef USE_MOUSE
    case K_MIDDLEMOUSE:
    case K_MIDDLEDRAG:
    case K_MIDDLERELEASE:
    case K_LEFTMOUSE:
    case K_LEFTDRAG:
    case K_LEFTRELEASE:
    case K_RIGHTMOUSE:
    case K_RIGHTDRAG:
    case K_RIGHTRELEASE:
	(void)do_mouse(oap, ca.cmdchar, BACKWARD, ca.count1, 0);
	break;

    case K_IGNORE:
	break;
#endif

#ifdef USE_GUI
/*
 * 16. scrollbar movement
 */
    case K_SCROLLBAR:
	if (oap->op_type != OP_NOP)
	    clearopbeep(oap);

	/* Even if an operator was pending, we still want to scroll */
	gui_do_scroll();
	break;

    case K_HORIZ_SCROLLBAR:
	if (oap->op_type != OP_NOP)
	    clearopbeep(oap);

	/* Even if an operator was pending, we still want to scroll */
	gui_do_horiz_scroll();
	break;
#endif

    case K_SELECT:	    /* end of Select mode mapping */
	nv_select(&ca);
	break;

#ifdef FKMAP
      case K_F8:
      case K_F9:
	farsi_fkey(ca.cmdchar);
	break;
#endif

#ifdef USE_SNIFF
      case K_SNIFF:
	ProcessSniffRequests();
	break;
#endif

/*
 * 17. The end
 */
    case Ctrl('C'):
	restart_edit = 0;
	/*FALLTHROUGH*/

    case ESC:
	nv_esc(&ca, opnum);
	break;

    default:			/* not a known command */
	clearopbeep(oap);
	break;

    }	/* end of switch on command character */

/*
 * if we didn't start or finish an operator, reset oap->regname, unless we
 * need it later.
 */
    if (!finish_op && !oap->op_type &&
		       vim_strchr((char_u *)"\"DCYSsXx.", ca.cmdchar) == NULL)
	oap->regname = 0;

/*
 * If an operation is pending, handle it...
 */
    do_pending_operator(&ca, searchbuff,
			   &command_busy, old_col, FALSE, dont_adjust_op_end);

    /*
     * Wait when a message is displayed that will be overwritten by the mode
     * message.
     * In Visual mode and with "^O" in Insert mode, a short message will be
     * overwritten by the mode message.  Wait a bit, until a key is hit.
     * In Visual mode, it's more important to keep the Visual area updated
     * than keeping a message (e.g. from a /pat search).
     * Only do this if the command was typed, not from a mapping.
     * Also wait a bit after an error message, e.g. for "^O:".
     * Don't redraw the screen, it would remove the message.
     */
    if (       ((p_smd
		    && ((VIsual_active
			    && old_pos.lnum == curwin->w_cursor.lnum
			    && old_pos.col == curwin->w_cursor.col)
			|| restart_edit)
		    && (clear_cmdline
			|| redraw_cmdline)
		    && msg_didany
		    && !msg_nowait
		    && KeyTyped)
		|| (restart_edit
		    && !VIsual_active
		    && (msg_scroll
			|| emsg_on_display)))
	    && oap->regname == 0
	    && !command_busy
	    && stuff_empty()
	    && typebuf_typed()
	    && oap->op_type == OP_NOP)
    {
	/* If need to redraw, and there is a "keep_msg", redraw before the
	 * delay */
	if (must_redraw && keep_msg != NULL && !emsg_on_display)
	{
	    char_u	*kmsg = keep_msg;

	    /* showmode() will clear keep_msg, but we want to use it anyway */
	    update_screen(must_redraw);
	    msg_attr(kmsg, keep_msg_attr);
	}
	setcursor();
	cursor_on();
	out_flush();
	if (msg_scroll || emsg_on_display)
	    ui_delay(1000L, TRUE);	/* wait at least one second */
	ui_delay(3000L, FALSE);		/* wait up to three seconds */

	msg_scroll = FALSE;
	emsg_on_display = FALSE;
    }

    /*
     * Finish up after executing a Normal mode command.
     */
normal_end:

    msg_nowait = FALSE;

    /* Reset finish_op, in case it was set */
#ifdef USE_GUI
    c = finish_op;
#endif
    finish_op = FALSE;
#ifdef CURSOR_SHAPE
    /* Redraw the cursor with another shape, if we were in Operator-pending
     * mode or did a replace command. */
    if ((c && !finish_op) || ca.cmdchar == 'r')
	ui_cursor_shape();		/* may show different cursor shape */
#endif

#ifdef SHOWCMD
    if (oap->op_type == OP_NOP && oap->regname == 0)
	clear_showcmd();
#endif

    /*
     * Update the other windows for the current buffer if modified has been
     * set in set_Changed() (This should be done more efficiently)
     */
    if (modified)
    {
	update_other_win();
	modified = FALSE;
    }

    checkpcmark();		/* check if we moved since setting pcmark */
    vim_free(searchbuff);

    /*
     * May restart edit(), if we got here with CTRL-O in Insert mode (but not
     * if still inside a mapping that started in Visual mode).
     * May switch from Visual to Select mode after CTRL-O command.
     */
    if (      ((restart_edit && !VIsual_active && old_mapped_len == 0)
		|| restart_VIsual_select == 1)
	    && oap->op_type == OP_NOP
	    && !command_busy
	    && stuff_empty()
	    && oap->regname == 0)
    {
	if (restart_VIsual_select == 1)
	{
	    VIsual_select = TRUE;
	    showmode();
	    restart_VIsual_select = 0;
	}
	if (restart_edit && !VIsual_active && old_mapped_len == 0)
	    (void)edit(restart_edit, FALSE, 1L);
    }

    if (restart_VIsual_select == 2)
	restart_VIsual_select = 1;

#ifdef MULTI_BYTE
    if (is_dbcs)
	AdjustCursorForMultiByteCharacter();
#endif
}

/*
 * Handle an operator after visual mode or when the movement is finished
 */
    void
do_pending_operator(cap, searchbuff,
			  command_busy, old_col, gui_yank, dont_adjust_op_end)
    CMDARG	*cap;
    char_u	*searchbuff;
    int		*command_busy;
    int		old_col;
    int		gui_yank;	    /* yanking visual area for GUI */
    int		dont_adjust_op_end;
{
    OPARG	*oap = cap->oap;
    FPOS	old_cursor;
    int		empty_region_error;

    /* The visual area is remembered for redo */
    static int	    redo_VIsual_mode = NUL; /* 'v', 'V', or Ctrl-V */
    static linenr_t redo_VIsual_line_count; /* number of lines */
    static colnr_t  redo_VIsual_col;	    /* number of cols or end column */
    static long	    redo_VIsual_count;	    /* count for Visual operator */

#if defined(USE_CLIPBOARD) && !defined(WIN32)
    /*
     * Yank the visual area into the GUI selection register before we operate
     * on it and lose it forever.  This could call do_pending_operator()
     * recursively, but that's OK because gui_yank will be TRUE for the
     * nested call.  Note also that we call clip_copy_selection() and not
     * clip_auto_select().  This is because even when 'autoselect' is not set,
     * if we operate on the text, eg by deleting it, then this is considered to
     * be an explicit request for it to be put in the global cut buffer, so we
     * always want to do it here. -- webb
     */
    /* WIN32: don't do this, there is no automatic copy to the clipboard */
    /* Don't do it if a specific register was specified, so that ""x"*P works */
    if (clipboard.available
	    && oap->op_type != OP_NOP
	    && !gui_yank
	    && VIsual_active
	    && oap->regname == 0
	    && !redo_VIsual_busy)
	clip_copy_selection();
#endif
    old_cursor = curwin->w_cursor;

    /*
     * If an operation is pending, handle it...
     */
    if ((VIsual_active || finish_op) && oap->op_type != OP_NOP)
    {
	oap->is_VIsual = VIsual_active;

	/* only redo yank when 'y' flag is in 'cpoptions' */
	if ((vim_strchr(p_cpo, CPO_YANK) != NULL || oap->op_type != OP_YANK)
		&& !VIsual_active)
	{
	    prep_redo(oap->regname, cap->count0, oap->op_prechar,
			op_chars[oap->op_type - 1], cap->cmdchar, cap->nchar);
	    if (cap->cmdchar == '/' || cap->cmdchar == '?') /* was a search */
	    {
		/*
		 * If 'cpoptions' does not contain 'r', insert the search
		 * pattern to really repeat the same command.
		 */
		if (vim_strchr(p_cpo, CPO_REDO) == NULL)
		    AppendToRedobuff(searchbuff);
		AppendToRedobuff(NL_STR);
	    }
	}

	if (redo_VIsual_busy)
	{
	    oap->start = curwin->w_cursor;
	    curwin->w_cursor.lnum += redo_VIsual_line_count - 1;
	    if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
		curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
	    VIsual_mode = redo_VIsual_mode;
	    if (VIsual_mode == 'v')
	    {
		if (redo_VIsual_line_count <= 1)
		    curwin->w_cursor.col += redo_VIsual_col - 1;
		else
		    curwin->w_cursor.col = redo_VIsual_col;
	    }
	    if (redo_VIsual_col == MAXCOL)
	    {
		curwin->w_curswant = MAXCOL;
		coladvance(MAXCOL);
	    }
	    cap->count0 = redo_VIsual_count;
	    if (redo_VIsual_count != 0)
		cap->count1 = redo_VIsual_count;
	    else
		cap->count1 = 1;
	}
	else if (VIsual_active)
	{
	    /* In Select mode, a linewise selection is operated upon like a
	     * characterwise selection. */
	    if (VIsual_select && VIsual_mode == 'V')
	    {
		if (lt(VIsual, curwin->w_cursor))
		{
		    VIsual.col = 0;
		    curwin->w_cursor.col =
					STRLEN(ml_get(curwin->w_cursor.lnum));
		}
		else
		{
		    curwin->w_cursor.col = 0;
		    VIsual.col = STRLEN(ml_get(VIsual.lnum));
		}
		VIsual_mode = 'v';
	    }
	    /* If 'selection' is "exclusive", backup one character for
	     * charwise selections. */
	    else if (*p_sel == 'e' && VIsual_mode == 'v'
					  && !equal(VIsual, curwin->w_cursor))
	    {
		FPOS	*pp;

		if (lt(VIsual, curwin->w_cursor))
		    pp = &curwin->w_cursor;
		else
		    pp = &VIsual;
		if (pp->col > 0)
		    --pp->col;
		else if (pp->lnum > 1)
		{
		    --pp->lnum;
		    pp->col = STRLEN(ml_get(pp->lnum));
		}
	    }

	    /* Save the current VIsual area for '< and '> marks, and "gv" */
	    curbuf->b_visual_start = VIsual;
	    curbuf->b_visual_end = curwin->w_cursor;
	    curbuf->b_visual_mode = VIsual_mode;

	    oap->start = VIsual;
	    if (VIsual_mode == 'V')
		oap->start.col = 0;
	}

	/*
	 * Set oap->start to the first position of the operated text, oap->end
	 * to the end of the operated text.  w_cursor is equal to oap->start.
	 */
	if (lt(oap->start, curwin->w_cursor))
	{
	    oap->end = curwin->w_cursor;
	    curwin->w_cursor = oap->start;
	}
	else
	{
	    oap->end = oap->start;
	    oap->start = curwin->w_cursor;
	}
#ifdef MULTI_BYTE
	if (is_dbcs && (VIsual_active || oap->inclusive))
	{
	    char_u *p;

	    p = ml_get(oap->end.lnum);
	    if (IsTrailByte(p, p + oap->end.col + 1))
		oap->end.col++;
	}
#endif

⌨️ 快捷键说明

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