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

📄 ex_getln.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
		    goto cmdline_not_changed;
		/* FALLTHROUGH */
	case K_LEFTMOUSE:
	case K_RIGHTMOUSE:
		if (c == K_LEFTRELEASE || c == K_RIGHTRELEASE)
		    ignore_drag_release = TRUE;
		else
		    ignore_drag_release = FALSE;
# ifdef USE_GUI
		/* When GUI is active, also move when 'mouse' is empty */
		if (!gui.in_use)
# endif
		    if (!mouse_has(MOUSE_COMMAND))
			goto cmdline_not_changed;   /* Ignore mouse */
		set_cmdspos();
		for (ccline.cmdpos = 0; ccline.cmdpos < ccline.cmdlen;
							      ++ccline.cmdpos)
		{
		    i = charsize(ccline.cmdbuff[ccline.cmdpos]);
		    if (mouse_row <= cmdline_row + ccline.cmdspos / Columns &&
				     mouse_col < ccline.cmdspos % Columns + i)
			break;
		    ccline.cmdspos += i;
		}
		goto cmdline_not_changed;
#endif	/* USE_MOUSE */

#ifdef USE_GUI
	case K_SCROLLBAR:
		if (!msg_scrolled)
		{
		    gui_do_scroll();
		    redrawcmd();
		}
		goto cmdline_not_changed;

	case K_HORIZ_SCROLLBAR:
		if (!msg_scrolled)
		{
		    gui_do_horiz_scroll();
		    redrawcmd();
		}
		goto cmdline_not_changed;
#endif
	case K_SELECT:	    /* end of Select mode mapping - ignore */
		goto cmdline_not_changed;

	case Ctrl('B'):	    /* begin of command line */
	case K_HOME:
	case K_KHOME:
	case K_S_HOME:
		ccline.cmdpos = 0;
		set_cmdspos();
		goto cmdline_not_changed;

	case Ctrl('E'):	    /* end of command line */
	case K_END:
	case K_KEND:
	case K_S_END:
		ccline.cmdpos = ccline.cmdlen;
		ccline.cmdbuff[ccline.cmdlen] = NUL;
		set_cmdspos();
		ccline.cmdspos += vim_strsize(ccline.cmdbuff);
		goto cmdline_not_changed;

	case Ctrl('A'):	    /* all matches */
		if (nextwild(WILD_ALL, 0) == FAIL)
		    break;
		goto cmdline_changed;

	case Ctrl('L'):	    /* longest common part */
		if (nextwild(WILD_LONGEST, 0) == FAIL)
		    break;
		goto cmdline_changed;

	case Ctrl('N'):	    /* next match */
	case Ctrl('P'):	    /* previous match */
		if (cmd_numfiles > 0)
		{
		    if (nextwild((c == Ctrl('P')) ? WILD_PREV : WILD_NEXT, 0)
								      == FAIL)
			break;
		    goto cmdline_changed;
		}

	case K_UP:
	case K_DOWN:
	case K_S_UP:
	case K_S_DOWN:
	case K_PAGEUP:
	case K_KPAGEUP:
	case K_PAGEDOWN:
	case K_KPAGEDOWN:
		if (hislen == 0 || firstc == NUL)	/* no history */
		    goto cmdline_not_changed;

		i = hiscnt;

		/* save current command string so it can be restored later */
		ccline.cmdbuff[ccline.cmdlen] = NUL;
		if (lookfor == NULL)
		{
		    if ((lookfor = vim_strsave(ccline.cmdbuff)) == NULL)
			goto cmdline_not_changed;
		    lookfor[ccline.cmdpos] = NUL;
		}

		j = STRLEN(lookfor);
		for (;;)
		{
		    /* one step backwards */
		    if (c == K_UP || c == K_S_UP || c == Ctrl('P') ||
			    c == K_PAGEUP || c == K_KPAGEUP)
		    {
			if (hiscnt == hislen)	/* first time */
			    hiscnt = hisidx[histype];
			else if (hiscnt == 0 && hisidx[histype] != hislen - 1)
			    hiscnt = hislen - 1;
			else if (hiscnt != hisidx[histype] + 1)
			    --hiscnt;
			else			/* at top of list */
			{
			    hiscnt = i;
			    break;
			}
		    }
		    else    /* one step forwards */
		    {
			/* on last entry, clear the line */
			if (hiscnt == hisidx[histype])
			{
			    hiscnt = hislen;
			    break;
			}

			/* not on a history line, nothing to do */
			if (hiscnt == hislen)
			    break;
			if (hiscnt == hislen - 1)   /* wrap around */
			    hiscnt = 0;
			else
			    ++hiscnt;
		    }
		    if (hiscnt < 0 || history[histype][hiscnt] == NULL)
		    {
			hiscnt = i;
			break;
		    }
		    if ((c != K_UP && c != K_DOWN) || hiscnt == i ||
			    STRNCMP(history[histype][hiscnt],
						    lookfor, (size_t)j) == 0)
			break;
		}

		if (hiscnt != i)	/* jumped to other entry */
		{
		    vim_free(ccline.cmdbuff);
		    if (hiscnt == hislen)
			p = lookfor;	/* back to the old one */
		    else
			p = history[histype][hiscnt];

		    alloc_cmdbuff((int)STRLEN(p));
		    if (ccline.cmdbuff == NULL)
			goto returncmd;
		    STRCPY(ccline.cmdbuff, p);

		    ccline.cmdpos = ccline.cmdlen = STRLEN(ccline.cmdbuff);
		    redrawcmd();
		    goto cmdline_changed;
		}
		beep_flush();
		goto cmdline_not_changed;

	case Ctrl('V'):
	case Ctrl('Q'):
#ifdef USE_MOUSE
		ignore_drag_release = TRUE;
#endif
		putcmdline('^');
		c = get_literal();	    /* get next (two) character(s) */
		do_abbr = FALSE;	    /* don't do abbreviation now */
		break;

#ifdef DIGRAPHS
	case Ctrl('K'):
#ifdef USE_MOUSE
		ignore_drag_release = TRUE;
#endif
		putcmdline('?');
#ifdef USE_GUI_WIN32
		dont_scroll = TRUE;	    /* disallow scrolling here */
#endif
		++no_mapping;
		++allow_keys;
		c = vgetc();
		--no_mapping;
		--allow_keys;
		if (c != ESC)		    /* ESC cancels CTRL-K */
		{
		    if (IS_SPECIAL(c))	    /* insert special key code */
			break;
		    if (charsize(c) == 1)
			putcmdline(c);
		    ++no_mapping;
		    ++allow_keys;
		    cc = vgetc();
		    --no_mapping;
		    --allow_keys;
		    if (cc != ESC)	    /* ESC cancels CTRL-K */
		    {
			c = getdigraph(c, cc, TRUE);
			break;
		    }
		}
		redrawcmd();
		goto cmdline_not_changed;
#endif /* DIGRAPHS */

#ifdef RIGHTLEFT
	case Ctrl('_'):	    /* CTRL-_: switch language mode */
		if (!p_ari)
		    break;
#ifdef FKMAP
		if (p_altkeymap)
		{
		    cmd_fkmap = !cmd_fkmap;
		    if (cmd_fkmap)	/* in Farsi always in Insert mode */
			ccline.overstrike = FALSE;
		}
		else			    /* Hebrew is default */
#endif
		    cmd_hkmap = !cmd_hkmap;
		goto cmdline_not_changed;
#endif

	    /* keypad keys: When not mapped they produce a normal char */
	case K_KPLUS:		c = '+'; break;
	case K_KMINUS:		c = '-'; break;
	case K_KDIVIDE:		c = '/'; break;
	case K_KMULTIPLY:	c = '*'; break;

	default:
#ifdef UNIX
		if (c == intr_char)
		{
		    gotesc = TRUE;	/* will free ccline.cmdbuff after
					   putting it in history */
		    goto returncmd;	/* back to cmd mode */
		}
#endif
		/*
		 * Normal character with no special meaning.  Just set mod_mask
		 * to 0x0 so that typing Shift-Space in the GUI doesn't enter
		 * the string <S-Space>.  This should only happen after ^V.
		 */
		if (!IS_SPECIAL(c))
		    mod_mask = 0x0;
		break;
	}

	/* we come here if we have a normal character */

	if (do_abbr && (IS_SPECIAL(c) || !vim_iswordc(c)) && ccheck_abbr(c))
	    goto cmdline_changed;

	/*
	 * put the character in the command line
	 */
	if (IS_SPECIAL(c) || mod_mask != 0x0)
	    put_on_cmdline(get_special_key_name(c, mod_mask), -1, TRUE);
	else
	{
	    IObuff[0] = c;

#ifdef MULTI_BYTE
	    /* prevent from splitting a multi-byte character into two
	       indivisual characters in command line. */
	    if (is_dbcs && IsLeadByte(c))
	    {
		IObuff[1] = vgetc();
		put_on_cmdline(IObuff, 2, TRUE);
	    }
	    else
		put_on_cmdline(IObuff, 1, TRUE);
#else
	    put_on_cmdline(IObuff, 1, TRUE);
#endif
	}
	goto cmdline_changed;

/*
 * This part implements incremental searches for "/" and "?"
 * Jump to cmdline_not_changed when a character has been read but the command
 * line did not change. Then we only search and redraw if something changed in
 * the past.
 * Jump to cmdline_changed when the command line did change.
 * (Sorry for the goto's, I know it is ugly).
 */
cmdline_not_changed:
#ifdef EXTRA_SEARCH
	if (!incsearch_postponed)
	    continue;
#endif

cmdline_changed:
#ifdef EXTRA_SEARCH
	if (p_is && (firstc == '/' || firstc == '?'))
	{
	    /* if there is a character waiting, search and redraw later */
	    if (char_avail())
	    {
		incsearch_postponed = TRUE;
		continue;
	    }
	    incsearch_postponed = FALSE;
	    curwin->w_cursor = old_cursor;  /* start at old position */

	    /* If there is no command line, don't do anything */
	    if (ccline.cmdlen == 0)
		i = 0;
	    else
	    {
		ccline.cmdbuff[ccline.cmdlen] = NUL;
		emsg_off = TRUE;    /* So it doesn't beep if bad expr */
		i = do_search(NULL, firstc, ccline.cmdbuff, count,
				      SEARCH_KEEP + SEARCH_OPT + SEARCH_NOOF);
		emsg_off = FALSE;
	    }
	    if (i)
		highlight_match = TRUE;		/* highlight position */
	    else
		highlight_match = FALSE;	    /* don't highlight */

	    /* first restore the old curwin values, so the screen is
	     * positioned in the same way as the actual search command */
	    curwin->w_leftcol = old_leftcol;
	    curwin->w_topline = old_topline;
	    curwin->w_botline = old_botline;
	    update_topline();
	    /*
	     * First move cursor to end of match, then to start.  This moves
	     * the whole match onto the screen when 'nowrap' is set.
	     */
	    curwin->w_cursor.col += search_match_len;
	    validate_cursor();
	    curwin->w_cursor.col -= search_match_len;
	    validate_cursor();

	    update_screen(NOT_VALID);
	    redrawcmdline();
	    did_incsearch = TRUE;
	}
#else
	;
#endif
    }

returncmd:

#ifdef FKMAP
    cmd_fkmap = 0;
#endif

#ifdef EXTRA_SEARCH
    if (did_incsearch)
    {
	curwin->w_cursor = old_cursor;
	curwin->w_curswant = old_curswant;
	curwin->w_leftcol = old_leftcol;
	curwin->w_topline = old_topline;
	curwin->w_botline = old_botline;
	highlight_match = FALSE;
	validate_cursor();	/* needed for TAB */
	redraw_later(NOT_VALID);
    }
#endif

    if (ccline.cmdbuff != NULL)
    {
	/*
	 * Put line in history buffer (":" and "=" only when it was typed).
	 */
	ccline.cmdbuff[ccline.cmdlen] = NUL;
	if (ccline.cmdlen && firstc &&
				   (some_key_typed || histype == HIST_SEARCH))
	{
	    add_to_history(histype, ccline.cmdbuff);
	    if (firstc == ':')
	    {
		vim_free(new_last_cmdline);
		new_last_cmdline = vim_strsave(ccline.cmdbuff);
	    }
	}

	if (gotesc)	    /* abandon command line */
	{
	    vim_free(ccline.cmdbuff);
	    ccline.cmdbuff = NULL;
	    MSG("");
	    redraw_cmdline = TRUE;
	}
    }

    /*
     * If the screen was shifted up, redraw the whole screen (later).
     * If the line is too long, clear it, so ruler and shown command do
     * not get printed in the middle of it.
     */
    msg_check();
    msg_scroll = save_msg_scroll;
    redir_off = FALSE;

    State = save_State;
#ifdef USE_MOUSE
    setmouse();
#endif

    return ccline.cmdbuff;
}

    static void
set_cmdspos()
{
    if (ccline.cmdfirstc)
	ccline.cmdspos = 1 + ccline.cmdindent;
    else
	ccline.cmdspos = 0 + ccline.cmdindent;
}

/*
 * Get an Ex command line for the ":" command.
 */
/* ARGSUSED */
    char_u *
getexline(c, dummy, indent)
    int		c;		/* normally ':', NUL for ":append" */
    void	*dummy;		/* cookie not used */
    int		indent;		/* indent for inside conditionals */
{
    return getcmdline(c, 1L, indent);
}

/*
 * Get an Ex command line for Ex mode.
 * In Ex mode we only use the OS supplied line editing features and no
 * mappings or abbreviations.
 */
/* ARGSUSED */
    char_u *
getexmodeline(c, dummy, indent)
    int		c;		/* normally ':', NUL for ":append" */
    void	*dummy;		/* cookie not used */
    int		indent;		/* indent for inside conditionals */
{
    struct growarray	line_ga;
    int			len;
    int			off = 0;
    char_u		*p;
    int			finished = FALSE;
#if defined(USE_GUI) || defined(NO_COOKED_INPUT)
    int			startcol = 0;
    int			c1;
    int			escaped = FALSE;	/* CTRL-V typed */
    int			vcol = 0;
#endif

    /* always start in column 0; write a newline if necessary */
    compute_cmdrow();
    if (msg_col)
	msg_putchar('\n');
    if (c == ':')
    {
	msg_putchar(':');
	while (indent-- > 0)
	    msg_putchar(' ');
#if defined(USE_GUI) || defined(NO_COOKED_INPUT)
	startcol = msg_col;
#endif
    }

    ga_init2(&line_ga, 1, 30);

    /*
     * Get the line, one character at a time.
     */
    got_int = FALSE;
    while (!got_int && !finished)
    {
	if (ga_grow(&line_ga, 40) == FAIL)
	    break;
	p = (char_u *)line_ga.ga_data + line_ga.ga_len;

	/* Get one character (inchar gets a third of maxlen characters!) */
	len = inchar(p + off, 3, -1L);
	if (len < 0)
	    continue;	    /* end of input script reached */
	/* for a special character, we need at least three characters */
	if ((*p == K_SPECIAL || *p == CSI) && off + len < 3)
	{
	    off += len;
	    continue;
	}
	len += off;
	off = 0;

	/*
	 * When using the GUI, and for systems that don't have cooked input,
	 * handle line editing here.
	 */
#if defined(USE_GUI) || defined(NO_COOKED_INPUT)
# ifndef NO_COOKED_INPUT
	if (gui.in_use)
# endif
	{
	    if (got_int)

⌨️ 快捷键说明

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