mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 19:38:20 +00:00
vim-patch:8.2.1622: loop to handle keys for the command line is too long (#21307)
Problem: Loop to handle keys for the command line is too long.
Solution: Move code to functions. (Yegappan Lakshmanan, closes vim/vim#6880)
2f3cd2e4ec
Use the command line state as only argument instead.
This commit is contained in:
@@ -1410,72 +1410,14 @@ static int may_do_command_line_next_incsearch(int firstc, long count, incsearch_
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void command_line_next_histidx(CommandLineState *s, bool next_match)
|
/// Handle backspace, delete and CTRL-W keys in the command-line mode.
|
||||||
|
static int command_line_erase_chars(CommandLineState *s)
|
||||||
{
|
{
|
||||||
int j = (int)strlen(s->lookfor);
|
|
||||||
for (;;) {
|
|
||||||
// one step backwards
|
|
||||||
if (!next_match) {
|
|
||||||
if (s->hiscnt == get_hislen()) {
|
|
||||||
// first time
|
|
||||||
s->hiscnt = *get_hisidx(s->histype);
|
|
||||||
} else if (s->hiscnt == 0 && *get_hisidx(s->histype) != get_hislen() - 1) {
|
|
||||||
s->hiscnt = get_hislen() - 1;
|
|
||||||
} else if (s->hiscnt != *get_hisidx(s->histype) + 1) {
|
|
||||||
s->hiscnt--;
|
|
||||||
} else {
|
|
||||||
// at top of list
|
|
||||||
s->hiscnt = s->save_hiscnt;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else { // one step forwards
|
|
||||||
// on last entry, clear the line
|
|
||||||
if (s->hiscnt == *get_hisidx(s->histype)) {
|
|
||||||
s->hiscnt = get_hislen();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// not on a history line, nothing to do
|
|
||||||
if (s->hiscnt == get_hislen()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s->hiscnt == get_hislen() - 1) {
|
|
||||||
// wrap around
|
|
||||||
s->hiscnt = 0;
|
|
||||||
} else {
|
|
||||||
s->hiscnt++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s->hiscnt < 0 || get_histentry(s->histype)[s->hiscnt].hisstr == NULL) {
|
|
||||||
s->hiscnt = s->save_hiscnt;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((s->c != K_UP && s->c != K_DOWN)
|
|
||||||
|| s->hiscnt == s->save_hiscnt
|
|
||||||
|| strncmp(get_histentry(s->histype)[s->hiscnt].hisstr,
|
|
||||||
s->lookfor, (size_t)j) == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int command_line_handle_key(CommandLineState *s)
|
|
||||||
{
|
|
||||||
// Big switch for a typed command line character.
|
|
||||||
switch (s->c) {
|
|
||||||
case K_BS:
|
|
||||||
case Ctrl_H:
|
|
||||||
case K_DEL:
|
|
||||||
case K_KDEL:
|
|
||||||
case Ctrl_W:
|
|
||||||
if (s->c == K_KDEL) {
|
if (s->c == K_KDEL) {
|
||||||
s->c = K_DEL;
|
s->c = K_DEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete current character is the same as backspace on next
|
// Delete current character is the same as backspace on next
|
||||||
// character, except at end of line
|
// character, except at end of line
|
||||||
if (s->c == K_DEL && ccline.cmdpos != ccline.cmdlen) {
|
if (s->c == K_DEL && ccline.cmdpos != ccline.cmdlen) {
|
||||||
ccline.cmdpos++;
|
ccline.cmdpos++;
|
||||||
@@ -1545,15 +1487,12 @@ static int command_line_handle_key(CommandLineState *s)
|
|||||||
return 0; // back to cmd mode
|
return 0; // back to cmd mode
|
||||||
}
|
}
|
||||||
return command_line_changed(s);
|
return command_line_changed(s);
|
||||||
|
}
|
||||||
|
|
||||||
case K_INS:
|
/// Handle the CTRL-^ key in the command-line mode and toggle the use of the
|
||||||
case K_KINS:
|
/// language :lmap mappings and/or Input Method.
|
||||||
ccline.overstrike = !ccline.overstrike;
|
static void command_line_toggle_langmap(CommandLineState *s)
|
||||||
|
{
|
||||||
ui_cursor_shape(); // may show different cursor shape
|
|
||||||
return command_line_not_changed(s);
|
|
||||||
|
|
||||||
case Ctrl_HAT:
|
|
||||||
if (map_to_exists_mode("", MODE_LANGMAP, false)) {
|
if (map_to_exists_mode("", MODE_LANGMAP, false)) {
|
||||||
// ":lmap" mappings exists, toggle use of mappings.
|
// ":lmap" mappings exists, toggle use of mappings.
|
||||||
State ^= MODE_LANGMAP;
|
State ^= MODE_LANGMAP;
|
||||||
@@ -1576,42 +1515,12 @@ static int command_line_handle_key(CommandLineState *s)
|
|||||||
ui_cursor_shape(); // may show different cursor shape
|
ui_cursor_shape(); // may show different cursor shape
|
||||||
// Show/unshow value of 'keymap' in status lines later.
|
// Show/unshow value of 'keymap' in status lines later.
|
||||||
status_redraw_curbuf();
|
status_redraw_curbuf();
|
||||||
return command_line_not_changed(s);
|
}
|
||||||
|
|
||||||
case Ctrl_U: {
|
/// Handle the CTRL-R key in the command-line mode and insert the contents of a
|
||||||
// delete all characters left of the cursor
|
/// numbered or named register.
|
||||||
int j = ccline.cmdpos;
|
static int command_line_insert_reg(CommandLineState *s)
|
||||||
ccline.cmdlen -= j;
|
{
|
||||||
int i = ccline.cmdpos = 0;
|
|
||||||
while (i < ccline.cmdlen) {
|
|
||||||
ccline.cmdbuff[i++] = ccline.cmdbuff[j++];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Truncate at the end, required for multi-byte chars.
|
|
||||||
ccline.cmdbuff[ccline.cmdlen] = NUL;
|
|
||||||
if (ccline.cmdlen == 0) {
|
|
||||||
s->is_state.search_start = s->is_state.save_cursor;
|
|
||||||
}
|
|
||||||
redrawcmd();
|
|
||||||
return command_line_changed(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
case ESC: // get here if p_wc != ESC or when ESC typed twice
|
|
||||||
case Ctrl_C:
|
|
||||||
// In exmode it doesn't make sense to return. Except when
|
|
||||||
// ":normal" runs out of characters. Also when highlight callback is active
|
|
||||||
// <C-c> should interrupt only it.
|
|
||||||
if ((exmode_active && (ex_normal_busy == 0 || typebuf.tb_len > 0))
|
|
||||||
|| (getln_interrupted_highlight && s->c == Ctrl_C)) {
|
|
||||||
getln_interrupted_highlight = false;
|
|
||||||
return command_line_not_changed(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
s->gotesc = true; // will free ccline.cmdbuff after
|
|
||||||
// putting it in history
|
|
||||||
return 0; // back to cmd mode
|
|
||||||
|
|
||||||
case Ctrl_R: { // insert register
|
|
||||||
const int save_new_cmdpos = new_cmdpos;
|
const int save_new_cmdpos = new_cmdpos;
|
||||||
|
|
||||||
putcmdline('"', true);
|
putcmdline('"', true);
|
||||||
@@ -1666,87 +1575,11 @@ static int command_line_handle_key(CommandLineState *s)
|
|||||||
redrawcmd();
|
redrawcmd();
|
||||||
|
|
||||||
return command_line_changed(s);
|
return command_line_changed(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
case Ctrl_D:
|
/// Handle the Left and Right mouse clicks in the command-line mode.
|
||||||
if (showmatches(&s->xpc, false) == EXPAND_NOTHING) {
|
static void command_line_left_right_mouse(CommandLineState *s)
|
||||||
break; // Use ^D as normal char instead
|
{
|
||||||
}
|
|
||||||
|
|
||||||
wild_menu_showing = WM_LIST;
|
|
||||||
redrawcmd();
|
|
||||||
return 1; // don't do incremental search now
|
|
||||||
|
|
||||||
case K_RIGHT:
|
|
||||||
case K_S_RIGHT:
|
|
||||||
case K_C_RIGHT:
|
|
||||||
do {
|
|
||||||
if (ccline.cmdpos >= ccline.cmdlen) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cells = cmdline_charsize(ccline.cmdpos);
|
|
||||||
if (KeyTyped && ccline.cmdspos + cells >= Columns * Rows) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ccline.cmdspos += cells;
|
|
||||||
ccline.cmdpos += utfc_ptr2len(ccline.cmdbuff + ccline.cmdpos);
|
|
||||||
} while ((s->c == K_S_RIGHT || s->c == K_C_RIGHT
|
|
||||||
|| (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)))
|
|
||||||
&& ccline.cmdbuff[ccline.cmdpos] != ' ');
|
|
||||||
ccline.cmdspos = cmd_screencol(ccline.cmdpos);
|
|
||||||
return command_line_not_changed(s);
|
|
||||||
|
|
||||||
case K_LEFT:
|
|
||||||
case K_S_LEFT:
|
|
||||||
case K_C_LEFT:
|
|
||||||
if (ccline.cmdpos == 0) {
|
|
||||||
return command_line_not_changed(s);
|
|
||||||
}
|
|
||||||
do {
|
|
||||||
ccline.cmdpos--;
|
|
||||||
// Move to first byte of possibly multibyte char.
|
|
||||||
ccline.cmdpos -= utf_head_off(ccline.cmdbuff,
|
|
||||||
ccline.cmdbuff + ccline.cmdpos);
|
|
||||||
ccline.cmdspos -= cmdline_charsize(ccline.cmdpos);
|
|
||||||
} while (ccline.cmdpos > 0
|
|
||||||
&& (s->c == K_S_LEFT || s->c == K_C_LEFT
|
|
||||||
|| (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)))
|
|
||||||
&& ccline.cmdbuff[ccline.cmdpos - 1] != ' ');
|
|
||||||
|
|
||||||
ccline.cmdspos = cmd_screencol(ccline.cmdpos);
|
|
||||||
if (ccline.special_char != NUL) {
|
|
||||||
putcmdline(ccline.special_char, ccline.special_shift);
|
|
||||||
}
|
|
||||||
|
|
||||||
return command_line_not_changed(s);
|
|
||||||
|
|
||||||
case K_IGNORE:
|
|
||||||
// Ignore mouse event or open_cmdwin() result.
|
|
||||||
return command_line_not_changed(s);
|
|
||||||
|
|
||||||
case K_MIDDLEDRAG:
|
|
||||||
case K_MIDDLERELEASE:
|
|
||||||
return command_line_not_changed(s); // Ignore mouse
|
|
||||||
|
|
||||||
case K_MIDDLEMOUSE:
|
|
||||||
cmdline_paste(eval_has_provider("clipboard") ? '*' : 0, true, true);
|
|
||||||
redrawcmd();
|
|
||||||
return command_line_changed(s);
|
|
||||||
|
|
||||||
case K_LEFTDRAG:
|
|
||||||
case K_LEFTRELEASE:
|
|
||||||
case K_RIGHTDRAG:
|
|
||||||
case K_RIGHTRELEASE:
|
|
||||||
// Ignore drag and release events when the button-down wasn't
|
|
||||||
// seen before.
|
|
||||||
if (s->ignore_drag_release) {
|
|
||||||
return command_line_not_changed(s);
|
|
||||||
}
|
|
||||||
FALLTHROUGH;
|
|
||||||
case K_LEFTMOUSE:
|
|
||||||
case K_RIGHTMOUSE:
|
|
||||||
if (s->c == K_LEFTRELEASE || s->c == K_RIGHTRELEASE) {
|
if (s->c == K_LEFTRELEASE || s->c == K_RIGHTRELEASE) {
|
||||||
s->ignore_drag_release = true;
|
s->ignore_drag_release = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -1767,88 +1600,64 @@ static int command_line_handle_key(CommandLineState *s)
|
|||||||
ccline.cmdpos += utfc_ptr2len(ccline.cmdbuff + ccline.cmdpos) - 1;
|
ccline.cmdpos += utfc_ptr2len(ccline.cmdbuff + ccline.cmdpos) - 1;
|
||||||
ccline.cmdspos += cells;
|
ccline.cmdspos += cells;
|
||||||
}
|
}
|
||||||
return command_line_not_changed(s);
|
}
|
||||||
|
|
||||||
// Mouse scroll wheel: ignored here
|
static void command_line_next_histidx(CommandLineState *s, bool next_match)
|
||||||
case K_MOUSEDOWN:
|
{
|
||||||
case K_MOUSEUP:
|
int j = (int)strlen(s->lookfor);
|
||||||
case K_MOUSELEFT:
|
for (;;) {
|
||||||
case K_MOUSERIGHT:
|
// one step backwards
|
||||||
// Alternate buttons ignored here
|
if (!next_match) {
|
||||||
case K_X1MOUSE:
|
if (s->hiscnt == get_hislen()) {
|
||||||
case K_X1DRAG:
|
// first time
|
||||||
case K_X1RELEASE:
|
s->hiscnt = *get_hisidx(s->histype);
|
||||||
case K_X2MOUSE:
|
} else if (s->hiscnt == 0 && *get_hisidx(s->histype) != get_hislen() - 1) {
|
||||||
case K_X2DRAG:
|
s->hiscnt = get_hislen() - 1;
|
||||||
case K_X2RELEASE:
|
} else if (s->hiscnt != *get_hisidx(s->histype) + 1) {
|
||||||
case K_MOUSEMOVE:
|
s->hiscnt--;
|
||||||
return command_line_not_changed(s);
|
} else {
|
||||||
|
// at top of list
|
||||||
case K_SELECT: // end of Select mode mapping - ignore
|
s->hiscnt = s->save_hiscnt;
|
||||||
return command_line_not_changed(s);
|
|
||||||
|
|
||||||
case Ctrl_B: // begin of command line
|
|
||||||
case K_HOME:
|
|
||||||
case K_KHOME:
|
|
||||||
case K_S_HOME:
|
|
||||||
case K_C_HOME:
|
|
||||||
ccline.cmdpos = 0;
|
|
||||||
ccline.cmdspos = cmd_startcol();
|
|
||||||
return command_line_not_changed(s);
|
|
||||||
|
|
||||||
case Ctrl_E: // end of command line
|
|
||||||
case K_END:
|
|
||||||
case K_KEND:
|
|
||||||
case K_S_END:
|
|
||||||
case K_C_END:
|
|
||||||
ccline.cmdpos = ccline.cmdlen;
|
|
||||||
ccline.cmdspos = cmd_screencol(ccline.cmdpos);
|
|
||||||
return command_line_not_changed(s);
|
|
||||||
|
|
||||||
case Ctrl_A: // all matches
|
|
||||||
if (cmdline_pum_active()) {
|
|
||||||
// As Ctrl-A completes all the matches, close the popup
|
|
||||||
// menu (if present)
|
|
||||||
cmdline_pum_cleanup(&ccline);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nextwild(&s->xpc, WILD_ALL, 0, s->firstc != '@') == FAIL) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
s->xpc.xp_context = EXPAND_NOTHING;
|
} else { // one step forwards
|
||||||
s->did_wild_list = false;
|
// on last entry, clear the line
|
||||||
return command_line_changed(s);
|
if (s->hiscnt == *get_hisidx(s->histype)) {
|
||||||
|
s->hiscnt = get_hislen();
|
||||||
case Ctrl_L:
|
|
||||||
if (may_add_char_to_search(s->firstc, &s->c, &s->is_state) == OK) {
|
|
||||||
return command_line_not_changed(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
// completion: longest common part
|
|
||||||
if (nextwild(&s->xpc, WILD_LONGEST, 0, s->firstc != '@') == FAIL) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return command_line_changed(s);
|
|
||||||
|
|
||||||
case Ctrl_N: // next match
|
// not on a history line, nothing to do
|
||||||
case Ctrl_P: // previous match
|
if (s->hiscnt == get_hislen()) {
|
||||||
if (s->xpc.xp_numfiles > 0) {
|
|
||||||
if (nextwild(&s->xpc, (s->c == Ctrl_P) ? WILD_PREV : WILD_NEXT,
|
|
||||||
0, s->firstc != '@') == FAIL) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return command_line_not_changed(s);
|
|
||||||
}
|
|
||||||
FALLTHROUGH;
|
|
||||||
|
|
||||||
case K_UP:
|
if (s->hiscnt == get_hislen() - 1) {
|
||||||
case K_DOWN:
|
// wrap around
|
||||||
case K_S_UP:
|
s->hiscnt = 0;
|
||||||
case K_S_DOWN:
|
} else {
|
||||||
case K_PAGEUP:
|
s->hiscnt++;
|
||||||
case K_KPAGEUP:
|
}
|
||||||
case K_PAGEDOWN:
|
}
|
||||||
case K_KPAGEDOWN:
|
|
||||||
|
if (s->hiscnt < 0 || get_histentry(s->histype)[s->hiscnt].hisstr == NULL) {
|
||||||
|
s->hiscnt = s->save_hiscnt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((s->c != K_UP && s->c != K_DOWN)
|
||||||
|
|| s->hiscnt == s->save_hiscnt
|
||||||
|
|| strncmp(get_histentry(s->histype)[s->hiscnt].hisstr,
|
||||||
|
s->lookfor, (size_t)j) == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Handle the Up, Down, Page Up, Page down, CTRL-N and CTRL-P key in the
|
||||||
|
/// command-line mode. The pressed key is in 'c'.
|
||||||
|
static int command_line_browse_history(CommandLineState *s)
|
||||||
|
{
|
||||||
if (s->histype == HIST_INVALID || get_hislen() == 0 || s->firstc == NUL) {
|
if (s->histype == HIST_INVALID || get_hislen() == 0 || s->firstc == NUL) {
|
||||||
// no history
|
// no history
|
||||||
return command_line_not_changed(s);
|
return command_line_not_changed(s);
|
||||||
@@ -1931,6 +1740,229 @@ static int command_line_handle_key(CommandLineState *s)
|
|||||||
}
|
}
|
||||||
beep_flush();
|
beep_flush();
|
||||||
return command_line_not_changed(s);
|
return command_line_not_changed(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int command_line_handle_key(CommandLineState *s)
|
||||||
|
{
|
||||||
|
// Big switch for a typed command line character.
|
||||||
|
switch (s->c) {
|
||||||
|
case K_BS:
|
||||||
|
case Ctrl_H:
|
||||||
|
case K_DEL:
|
||||||
|
case K_KDEL:
|
||||||
|
case Ctrl_W:
|
||||||
|
return command_line_erase_chars(s);
|
||||||
|
|
||||||
|
case K_INS:
|
||||||
|
case K_KINS:
|
||||||
|
ccline.overstrike = !ccline.overstrike;
|
||||||
|
|
||||||
|
ui_cursor_shape(); // may show different cursor shape
|
||||||
|
return command_line_not_changed(s);
|
||||||
|
|
||||||
|
case Ctrl_HAT:
|
||||||
|
command_line_toggle_langmap(s);
|
||||||
|
return command_line_not_changed(s);
|
||||||
|
|
||||||
|
case Ctrl_U: {
|
||||||
|
// delete all characters left of the cursor
|
||||||
|
int j = ccline.cmdpos;
|
||||||
|
ccline.cmdlen -= j;
|
||||||
|
int i = ccline.cmdpos = 0;
|
||||||
|
while (i < ccline.cmdlen) {
|
||||||
|
ccline.cmdbuff[i++] = ccline.cmdbuff[j++];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Truncate at the end, required for multi-byte chars.
|
||||||
|
ccline.cmdbuff[ccline.cmdlen] = NUL;
|
||||||
|
if (ccline.cmdlen == 0) {
|
||||||
|
s->is_state.search_start = s->is_state.save_cursor;
|
||||||
|
}
|
||||||
|
redrawcmd();
|
||||||
|
return command_line_changed(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
case ESC: // get here if p_wc != ESC or when ESC typed twice
|
||||||
|
case Ctrl_C:
|
||||||
|
// In exmode it doesn't make sense to return. Except when
|
||||||
|
// ":normal" runs out of characters. Also when highlight callback is active
|
||||||
|
// <C-c> should interrupt only it.
|
||||||
|
if ((exmode_active && (ex_normal_busy == 0 || typebuf.tb_len > 0))
|
||||||
|
|| (getln_interrupted_highlight && s->c == Ctrl_C)) {
|
||||||
|
getln_interrupted_highlight = false;
|
||||||
|
return command_line_not_changed(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
s->gotesc = true; // will free ccline.cmdbuff after
|
||||||
|
// putting it in history
|
||||||
|
return 0; // back to cmd mode
|
||||||
|
|
||||||
|
case Ctrl_R: // insert register
|
||||||
|
return command_line_insert_reg(s);
|
||||||
|
|
||||||
|
case Ctrl_D:
|
||||||
|
if (showmatches(&s->xpc, false) == EXPAND_NOTHING) {
|
||||||
|
break; // Use ^D as normal char instead
|
||||||
|
}
|
||||||
|
|
||||||
|
wild_menu_showing = WM_LIST;
|
||||||
|
redrawcmd();
|
||||||
|
return 1; // don't do incremental search now
|
||||||
|
|
||||||
|
case K_RIGHT:
|
||||||
|
case K_S_RIGHT:
|
||||||
|
case K_C_RIGHT:
|
||||||
|
do {
|
||||||
|
if (ccline.cmdpos >= ccline.cmdlen) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cells = cmdline_charsize(ccline.cmdpos);
|
||||||
|
if (KeyTyped && ccline.cmdspos + cells >= Columns * Rows) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ccline.cmdspos += cells;
|
||||||
|
ccline.cmdpos += utfc_ptr2len(ccline.cmdbuff + ccline.cmdpos);
|
||||||
|
} while ((s->c == K_S_RIGHT || s->c == K_C_RIGHT
|
||||||
|
|| (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)))
|
||||||
|
&& ccline.cmdbuff[ccline.cmdpos] != ' ');
|
||||||
|
ccline.cmdspos = cmd_screencol(ccline.cmdpos);
|
||||||
|
return command_line_not_changed(s);
|
||||||
|
|
||||||
|
case K_LEFT:
|
||||||
|
case K_S_LEFT:
|
||||||
|
case K_C_LEFT:
|
||||||
|
if (ccline.cmdpos == 0) {
|
||||||
|
return command_line_not_changed(s);
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
ccline.cmdpos--;
|
||||||
|
// Move to first byte of possibly multibyte char.
|
||||||
|
ccline.cmdpos -= utf_head_off(ccline.cmdbuff,
|
||||||
|
ccline.cmdbuff + ccline.cmdpos);
|
||||||
|
ccline.cmdspos -= cmdline_charsize(ccline.cmdpos);
|
||||||
|
} while (ccline.cmdpos > 0
|
||||||
|
&& (s->c == K_S_LEFT || s->c == K_C_LEFT
|
||||||
|
|| (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)))
|
||||||
|
&& ccline.cmdbuff[ccline.cmdpos - 1] != ' ');
|
||||||
|
|
||||||
|
ccline.cmdspos = cmd_screencol(ccline.cmdpos);
|
||||||
|
if (ccline.special_char != NUL) {
|
||||||
|
putcmdline(ccline.special_char, ccline.special_shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
return command_line_not_changed(s);
|
||||||
|
|
||||||
|
case K_IGNORE:
|
||||||
|
// Ignore mouse event or open_cmdwin() result.
|
||||||
|
return command_line_not_changed(s);
|
||||||
|
|
||||||
|
case K_MIDDLEDRAG:
|
||||||
|
case K_MIDDLERELEASE:
|
||||||
|
return command_line_not_changed(s); // Ignore mouse
|
||||||
|
|
||||||
|
case K_MIDDLEMOUSE:
|
||||||
|
cmdline_paste(eval_has_provider("clipboard") ? '*' : 0, true, true);
|
||||||
|
redrawcmd();
|
||||||
|
return command_line_changed(s);
|
||||||
|
|
||||||
|
case K_LEFTDRAG:
|
||||||
|
case K_LEFTRELEASE:
|
||||||
|
case K_RIGHTDRAG:
|
||||||
|
case K_RIGHTRELEASE:
|
||||||
|
// Ignore drag and release events when the button-down wasn't
|
||||||
|
// seen before.
|
||||||
|
if (s->ignore_drag_release) {
|
||||||
|
return command_line_not_changed(s);
|
||||||
|
}
|
||||||
|
FALLTHROUGH;
|
||||||
|
case K_LEFTMOUSE:
|
||||||
|
case K_RIGHTMOUSE:
|
||||||
|
command_line_left_right_mouse(s);
|
||||||
|
return command_line_not_changed(s);
|
||||||
|
|
||||||
|
// Mouse scroll wheel: ignored here
|
||||||
|
case K_MOUSEDOWN:
|
||||||
|
case K_MOUSEUP:
|
||||||
|
case K_MOUSELEFT:
|
||||||
|
case K_MOUSERIGHT:
|
||||||
|
// Alternate buttons ignored here
|
||||||
|
case K_X1MOUSE:
|
||||||
|
case K_X1DRAG:
|
||||||
|
case K_X1RELEASE:
|
||||||
|
case K_X2MOUSE:
|
||||||
|
case K_X2DRAG:
|
||||||
|
case K_X2RELEASE:
|
||||||
|
case K_MOUSEMOVE:
|
||||||
|
return command_line_not_changed(s);
|
||||||
|
|
||||||
|
case K_SELECT: // end of Select mode mapping - ignore
|
||||||
|
return command_line_not_changed(s);
|
||||||
|
|
||||||
|
case Ctrl_B: // begin of command line
|
||||||
|
case K_HOME:
|
||||||
|
case K_KHOME:
|
||||||
|
case K_S_HOME:
|
||||||
|
case K_C_HOME:
|
||||||
|
ccline.cmdpos = 0;
|
||||||
|
ccline.cmdspos = cmd_startcol();
|
||||||
|
return command_line_not_changed(s);
|
||||||
|
|
||||||
|
case Ctrl_E: // end of command line
|
||||||
|
case K_END:
|
||||||
|
case K_KEND:
|
||||||
|
case K_S_END:
|
||||||
|
case K_C_END:
|
||||||
|
ccline.cmdpos = ccline.cmdlen;
|
||||||
|
ccline.cmdspos = cmd_screencol(ccline.cmdpos);
|
||||||
|
return command_line_not_changed(s);
|
||||||
|
|
||||||
|
case Ctrl_A: // all matches
|
||||||
|
if (cmdline_pum_active()) {
|
||||||
|
// As Ctrl-A completes all the matches, close the popup
|
||||||
|
// menu (if present)
|
||||||
|
cmdline_pum_cleanup(&ccline);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextwild(&s->xpc, WILD_ALL, 0, s->firstc != '@') == FAIL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s->xpc.xp_context = EXPAND_NOTHING;
|
||||||
|
s->did_wild_list = false;
|
||||||
|
return command_line_changed(s);
|
||||||
|
|
||||||
|
case Ctrl_L:
|
||||||
|
if (may_add_char_to_search(s->firstc, &s->c, &s->is_state) == OK) {
|
||||||
|
return command_line_not_changed(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// completion: longest common part
|
||||||
|
if (nextwild(&s->xpc, WILD_LONGEST, 0, s->firstc != '@') == FAIL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return command_line_changed(s);
|
||||||
|
|
||||||
|
case Ctrl_N: // next match
|
||||||
|
case Ctrl_P: // previous match
|
||||||
|
if (s->xpc.xp_numfiles > 0) {
|
||||||
|
if (nextwild(&s->xpc, (s->c == Ctrl_P) ? WILD_PREV : WILD_NEXT,
|
||||||
|
0, s->firstc != '@') == FAIL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return command_line_not_changed(s);
|
||||||
|
}
|
||||||
|
FALLTHROUGH;
|
||||||
|
|
||||||
|
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:
|
||||||
|
return command_line_browse_history(s);
|
||||||
|
|
||||||
case Ctrl_G: // next match
|
case Ctrl_G: // next match
|
||||||
case Ctrl_T: // previous match
|
case Ctrl_T: // previous match
|
||||||
|
Reference in New Issue
Block a user