mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
input: Remove CURSORHOLD key
Refactor input.c, normal.c and edit.c to use the K_EVENT special key to trigger the CURSORHOLD event. In normal and edit mode, K_EVENT is treated as K_CURSORHOLD, which enables better handling of arbitrary actions in those states(eg: In normal mode the previous operator counts will be restored). Also fix a test in vim_spec.lua. The test had a wrong assumption: cmdheight is only used to determine when the press enter screen will be shown, not to limit how many lines or control pagination.
This commit is contained in:
parent
d8055f8eab
commit
e5165bae11
@ -626,14 +626,9 @@ edit (
|
|||||||
} while (c == K_IGNORE);
|
} while (c == K_IGNORE);
|
||||||
input_disable_events();
|
input_disable_events();
|
||||||
|
|
||||||
if (c == K_EVENT) {
|
// Don't want K_EVENT with cursorhold for the second key, e.g., after
|
||||||
c = lastc;
|
// CTRL-V.
|
||||||
queue_process_events(loop.events);
|
did_cursorhold = true;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Don't want K_CURSORHOLD for the second key, e.g., after CTRL-V. */
|
|
||||||
did_cursorhold = TRUE;
|
|
||||||
|
|
||||||
if (p_hkmap && KeyTyped)
|
if (p_hkmap && KeyTyped)
|
||||||
c = hkmap(c); /* Hebrew mode mapping */
|
c = hkmap(c); /* Hebrew mode mapping */
|
||||||
@ -974,9 +969,8 @@ doESCkey:
|
|||||||
case K_IGNORE: /* Something mapped to nothing */
|
case K_IGNORE: /* Something mapped to nothing */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case K_CURSORHOLD: /* Didn't type something for a while. */
|
case K_EVENT: // some event
|
||||||
apply_autocmds(EVENT_CURSORHOLDI, NULL, NULL, FALSE, curbuf);
|
queue_process_events(loop.events);
|
||||||
did_cursorhold = TRUE;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case K_HOME: /* <Home> */
|
case K_HOME: /* <Home> */
|
||||||
@ -1223,9 +1217,10 @@ normalchar:
|
|||||||
break;
|
break;
|
||||||
} /* end of switch (c) */
|
} /* end of switch (c) */
|
||||||
|
|
||||||
/* If typed something may trigger CursorHoldI again. */
|
// If typed something may trigger CursorHoldI again.
|
||||||
if (c != K_CURSORHOLD)
|
if (c != K_EVENT) {
|
||||||
did_cursorhold = FALSE;
|
did_cursorhold = false;
|
||||||
|
}
|
||||||
|
|
||||||
/* If the cursor was moved we didn't just insert a space */
|
/* If the cursor was moved we didn't just insert a space */
|
||||||
if (arrow_used)
|
if (arrow_used)
|
||||||
|
@ -283,7 +283,6 @@ static struct key_name_entry {
|
|||||||
{K_ZERO, (char_u *)"Nul"},
|
{K_ZERO, (char_u *)"Nul"},
|
||||||
{K_SNR, (char_u *)"SNR"},
|
{K_SNR, (char_u *)"SNR"},
|
||||||
{K_PLUG, (char_u *)"Plug"},
|
{K_PLUG, (char_u *)"Plug"},
|
||||||
{K_CURSORHOLD, (char_u *)"CursorHold"},
|
|
||||||
{K_PASTE, (char_u *)"Paste"},
|
{K_PASTE, (char_u *)"Paste"},
|
||||||
{0, NULL}
|
{0, NULL}
|
||||||
};
|
};
|
||||||
|
@ -242,7 +242,6 @@ enum key_extra {
|
|||||||
, KE_X2RELEASE
|
, KE_X2RELEASE
|
||||||
|
|
||||||
, KE_DROP /* DnD data is available */
|
, KE_DROP /* DnD data is available */
|
||||||
, KE_CURSORHOLD /* CursorHold event */
|
|
||||||
, KE_NOP /* doesn't do something */
|
, KE_NOP /* doesn't do something */
|
||||||
, KE_FOCUSGAINED /* focus gained */
|
, KE_FOCUSGAINED /* focus gained */
|
||||||
, KE_FOCUSLOST /* focus lost */
|
, KE_FOCUSLOST /* focus lost */
|
||||||
@ -437,7 +436,6 @@ enum key_extra {
|
|||||||
#define K_FOCUSGAINED TERMCAP2KEY(KS_EXTRA, KE_FOCUSGAINED)
|
#define K_FOCUSGAINED TERMCAP2KEY(KS_EXTRA, KE_FOCUSGAINED)
|
||||||
#define K_FOCUSLOST TERMCAP2KEY(KS_EXTRA, KE_FOCUSLOST)
|
#define K_FOCUSLOST TERMCAP2KEY(KS_EXTRA, KE_FOCUSLOST)
|
||||||
|
|
||||||
#define K_CURSORHOLD TERMCAP2KEY(KS_EXTRA, KE_CURSORHOLD)
|
|
||||||
#define K_EVENT TERMCAP2KEY(KS_EXTRA, KE_EVENT)
|
#define K_EVENT TERMCAP2KEY(KS_EXTRA, KE_EVENT)
|
||||||
#define K_PASTE TERMCAP2KEY(KS_EXTRA, KE_PASTE)
|
#define K_PASTE TERMCAP2KEY(KS_EXTRA, KE_PASTE)
|
||||||
|
|
||||||
|
@ -336,7 +336,7 @@ static const struct nv_cmd {
|
|||||||
{K_SELECT, nv_select, 0, 0},
|
{K_SELECT, nv_select, 0, 0},
|
||||||
{K_F8, farsi_fkey, 0, 0},
|
{K_F8, farsi_fkey, 0, 0},
|
||||||
{K_F9, farsi_fkey, 0, 0},
|
{K_F9, farsi_fkey, 0, 0},
|
||||||
{K_CURSORHOLD, nv_cursorhold, NV_KEEPREG, 0},
|
{K_EVENT, nv_event, NV_KEEPREG, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Number of commands in nv_cmds[]. */
|
/* Number of commands in nv_cmds[]. */
|
||||||
@ -492,8 +492,8 @@ static void normal_prepare(NormalState *s)
|
|||||||
s->set_prevcount = true;
|
s->set_prevcount = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore counts from before receiving K_CURSORHOLD. This means after
|
// Restore counts from before receiving K_EVENT. This means after
|
||||||
// typing "3", handling K_CURSORHOLD and then typing "2" we get "32", not
|
// typing "3", handling K_EVENT and then typing "2" we get "32", not
|
||||||
// "3 * 2".
|
// "3 * 2".
|
||||||
if (s->oa.prev_opcount > 0 || s->oa.prev_count0 > 0) {
|
if (s->oa.prev_opcount > 0 || s->oa.prev_count0 > 0) {
|
||||||
s->ca.opcount = s->oa.prev_opcount;
|
s->ca.opcount = s->oa.prev_opcount;
|
||||||
@ -616,9 +616,9 @@ getcount:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == K_CURSORHOLD) {
|
if (c == K_EVENT) {
|
||||||
// Save the count values so that ca.opcount and ca.count0 are exactly
|
// Save the count values so that ca.opcount and ca.count0 are exactly
|
||||||
// the same when coming back here after handling K_CURSORHOLD.
|
// the same when coming back here after handling K_EVENT.
|
||||||
s->oa.prev_opcount = s->ca.opcount;
|
s->oa.prev_opcount = s->ca.opcount;
|
||||||
s->oa.prev_count0 = s->ca.count0;
|
s->oa.prev_count0 = s->ca.count0;
|
||||||
} else if (s->ca.opcount != 0) {
|
} else if (s->ca.opcount != 0) {
|
||||||
@ -891,7 +891,7 @@ getcount:
|
|||||||
if (need_flushbuf) {
|
if (need_flushbuf) {
|
||||||
ui_flush();
|
ui_flush();
|
||||||
}
|
}
|
||||||
if (s->ca.cmdchar != K_IGNORE) {
|
if (s->ca.cmdchar != K_IGNORE && s->ca.cmdchar != K_EVENT) {
|
||||||
did_cursorhold = false;
|
did_cursorhold = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1022,7 +1022,7 @@ normal_end:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (s->oa.op_type == OP_NOP && s->oa.regname == 0
|
if (s->oa.op_type == OP_NOP && s->oa.regname == 0
|
||||||
&& s->ca.cmdchar != K_CURSORHOLD) {
|
&& s->ca.cmdchar != K_EVENT) {
|
||||||
clear_showcmd();
|
clear_showcmd();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3147,7 +3147,7 @@ bool add_to_showcmd(int c)
|
|||||||
K_RIGHTMOUSE, K_RIGHTDRAG, K_RIGHTRELEASE,
|
K_RIGHTMOUSE, K_RIGHTDRAG, K_RIGHTRELEASE,
|
||||||
K_MOUSEDOWN, K_MOUSEUP, K_MOUSELEFT, K_MOUSERIGHT,
|
K_MOUSEDOWN, K_MOUSEUP, K_MOUSELEFT, K_MOUSERIGHT,
|
||||||
K_X1MOUSE, K_X1DRAG, K_X1RELEASE, K_X2MOUSE, K_X2DRAG, K_X2RELEASE,
|
K_X1MOUSE, K_X1DRAG, K_X1RELEASE, K_X2MOUSE, K_X2DRAG, K_X2RELEASE,
|
||||||
K_CURSORHOLD,
|
K_EVENT,
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -7567,16 +7567,11 @@ static void nv_open(cmdarg_T *cap)
|
|||||||
n_opencmd(cap);
|
n_opencmd(cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Handle an arbitrary event in normal mode
|
||||||
* Trigger CursorHold event.
|
static void nv_event(cmdarg_T *cap)
|
||||||
* When waiting for a character for 'updatetime' K_CURSORHOLD is put in the
|
|
||||||
* input buffer. "did_cursorhold" is set to avoid retriggering.
|
|
||||||
*/
|
|
||||||
static void nv_cursorhold(cmdarg_T *cap)
|
|
||||||
{
|
{
|
||||||
apply_autocmds(EVENT_CURSORHOLD, NULL, NULL, false, curbuf);
|
queue_process_events(loop.events);
|
||||||
did_cursorhold = true;
|
cap->retval |= CA_COMMAND_BUSY; // don't call edit() now
|
||||||
cap->retval |= CA_COMMAND_BUSY; /* don't call edit() now */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -7594,18 +7589,9 @@ void normal_cmd(oparg_T *oap, bool toplevel)
|
|||||||
s.toplevel = toplevel;
|
s.toplevel = toplevel;
|
||||||
s.oa = *oap;
|
s.oa = *oap;
|
||||||
normal_prepare(&s);
|
normal_prepare(&s);
|
||||||
|
|
||||||
input_enable_events();
|
input_enable_events();
|
||||||
int c = safe_vgetc();
|
int c = safe_vgetc();
|
||||||
input_disable_events();
|
input_disable_events();
|
||||||
|
|
||||||
if (c == K_EVENT) {
|
|
||||||
queue_process_events(loop.events);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
(void)normal_execute(&s, c);
|
(void)normal_execute(&s, c);
|
||||||
|
|
||||||
end:
|
|
||||||
*oap = s.oa;
|
*oap = s.oa;
|
||||||
}
|
}
|
||||||
|
@ -36,8 +36,8 @@ typedef struct oparg_S {
|
|||||||
bool block_mode; /* current operator is Visual block mode */
|
bool block_mode; /* current operator is Visual block mode */
|
||||||
colnr_T start_vcol; /* start col for block mode operator */
|
colnr_T start_vcol; /* start col for block mode operator */
|
||||||
colnr_T end_vcol; /* end col for block mode operator */
|
colnr_T end_vcol; /* end col for block mode operator */
|
||||||
long prev_opcount; /* ca.opcount saved for K_CURSORHOLD */
|
long prev_opcount; // ca.opcount saved for K_EVENT
|
||||||
long prev_count0; /* ca.count0 saved for K_CURSORHOLD */
|
long prev_count0; // ca.count0 saved for K_EVENT
|
||||||
} oparg_T;
|
} oparg_T;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -73,6 +73,21 @@ void input_stop(void)
|
|||||||
stream_close(&read_stream, NULL);
|
stream_close(&read_stream, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cursorhold_event(void **argv)
|
||||||
|
{
|
||||||
|
event_T event = State & INSERT ? EVENT_CURSORHOLDI : EVENT_CURSORHOLD;
|
||||||
|
apply_autocmds(event, NULL, NULL, false, curbuf);
|
||||||
|
did_cursorhold = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void create_cursorhold_event(void)
|
||||||
|
{
|
||||||
|
// If the queue had any items, this function should not have been
|
||||||
|
// called(inbuf_poll would return kInputAvail)
|
||||||
|
assert(queue_empty(loop.events));
|
||||||
|
queue_put(loop.events, cursorhold_event, 0);
|
||||||
|
}
|
||||||
|
|
||||||
// Low level input function
|
// Low level input function
|
||||||
int os_inchar(uint8_t *buf, int maxlen, int ms, int tb_change_cnt)
|
int os_inchar(uint8_t *buf, int maxlen, int ms, int tb_change_cnt)
|
||||||
{
|
{
|
||||||
@ -87,16 +102,12 @@ int os_inchar(uint8_t *buf, int maxlen, int ms, int tb_change_cnt)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((result = inbuf_poll((int)p_ut)) == kInputNone) {
|
if ((result = inbuf_poll((int)p_ut)) == kInputNone) {
|
||||||
if (trigger_cursorhold() && maxlen >= 3
|
if (trigger_cursorhold() && !typebuf_changed(tb_change_cnt)) {
|
||||||
&& !typebuf_changed(tb_change_cnt)) {
|
create_cursorhold_event();
|
||||||
buf[0] = K_SPECIAL;
|
} else {
|
||||||
buf[1] = KS_EXTRA;
|
before_blocking();
|
||||||
buf[2] = KE_CURSORHOLD;
|
result = inbuf_poll(-1);
|
||||||
return 3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
before_blocking();
|
|
||||||
result = inbuf_poll(-1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,33 +247,21 @@ describe('vim_* functions', function()
|
|||||||
~ |
|
~ |
|
||||||
{1:very fail} |
|
{1:very fail} |
|
||||||
]])
|
]])
|
||||||
|
helpers.wait()
|
||||||
|
|
||||||
-- shows up to &cmdheight lines
|
-- shows up to &cmdheight lines
|
||||||
nvim_async('err_write', 'more fail\n')
|
nvim_async('err_write', 'more fail\ntoo fail\n')
|
||||||
nvim_async('err_write', 'too fail\n')
|
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
~ |
|
~ |
|
||||||
~ |
|
~ |
|
||||||
~ |
|
~ |
|
||||||
~ |
|
~ |
|
||||||
~ |
|
~ |
|
||||||
{1:very fail} |
|
|
||||||
{1:more fail} |
|
{1:more fail} |
|
||||||
{2:Press ENTER or type command to continue}^ |
|
|
||||||
]])
|
|
||||||
|
|
||||||
-- shows the rest after return
|
|
||||||
feed('<cr>')
|
|
||||||
screen:expect([[
|
|
||||||
~ |
|
|
||||||
~ |
|
|
||||||
~ |
|
|
||||||
{1:very fail} |
|
|
||||||
{1:more fail} |
|
|
||||||
{2:Press ENTER or type command to continue} |
|
|
||||||
{1:too fail} |
|
{1:too fail} |
|
||||||
{2:Press ENTER or type command to continue}^ |
|
{2:Press ENTER or type command to continue}^ |
|
||||||
]])
|
]])
|
||||||
|
feed('<cr>') -- exit the press ENTER screen
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user