📄 ex_getln.c
字号:
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 + -