diff options
-rw-r--r-- | src/edit.c | 5 | ||||
-rw-r--r-- | src/ex_getln.c | 13 | ||||
-rw-r--r-- | src/getchar.c | 15 | ||||
-rw-r--r-- | src/keymap.h | 2 | ||||
-rw-r--r-- | src/message.c | 4 | ||||
-rw-r--r-- | src/normal.c | 8 | ||||
-rw-r--r-- | src/os/event.c | 94 | ||||
-rw-r--r-- | src/os/event.h | 2 | ||||
-rw-r--r-- | src/os/input.c | 20 | ||||
-rw-r--r-- | src/os/job.c | 1 |
10 files changed, 86 insertions, 78 deletions
diff --git a/src/edit.c b/src/edit.c index fcb45209cd..4a17c9aa44 100644 --- a/src/edit.c +++ b/src/edit.c @@ -52,6 +52,7 @@ #include "ui.h" #include "undo.h" #include "window.h" +#include "os/event.h" /* * definitions used for CTRL-X submode @@ -1025,7 +1026,9 @@ doESCkey: did_cursorhold = TRUE; break; - + case K_EVENT: + event_process(); + break; case K_HOME: /* <Home> */ case K_KHOME: diff --git a/src/ex_getln.c b/src/ex_getln.c index 498d53904c..51c596e1ce 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -56,6 +56,7 @@ #include "window.h" #include "ui.h" #include "os/os.h" +#include "os/event.h" /* * Variables shared between getcmdline(), redrawcmdline() and others. @@ -788,6 +789,11 @@ getcmdline ( * Big switch for a typed command line character. */ switch (c) { + case K_EVENT: + event_process(); + // Force a redraw even though the command line didn't change + shell_resized(); + goto cmdline_not_changed; case K_BS: case Ctrl_H: case K_DEL: @@ -1904,9 +1910,12 @@ redraw: continue; } - /* Ignore special key codes: mouse movement, K_IGNORE, etc. */ - if (IS_SPECIAL(c1)) + if (IS_SPECIAL(c1)) { + // Process pending events + event_process(); + // Ignore other special key codes continue; + } } if (IS_SPECIAL(c1)) diff --git a/src/getchar.c b/src/getchar.c index 93f896e1c3..736d72aa6b 100644 --- a/src/getchar.c +++ b/src/getchar.c @@ -164,6 +164,7 @@ static void map_free(mapblock_T **); static void validate_maphash(void); static void showmap(mapblock_T *mp, int local); static char_u *eval_map_expr(char_u *str, int c); +static bool is_user_input(int k); /* * Free and clear a buffer. @@ -2552,11 +2553,10 @@ fix_input_buffer ( * Don't replace K_SPECIAL when reading a script file. */ for (i = len; --i >= 0; ++p) { - if (p[0] == NUL || (p[0] == K_SPECIAL && !script - /* timeout may generate K_CURSORHOLD */ - && (i < 2 || p[1] != KS_EXTRA || p[2] != - (int)KE_CURSORHOLD) - )) { + if (p[0] == NUL + || (p[0] == K_SPECIAL + && !script + && (i < 2 || p[1] != KS_EXTRA || is_user_input(p[2])))) { memmove(p + 3, p + 1, (size_t)i); p[2] = K_THIRD(p[0]); p[1] = K_SECOND(p[0]); @@ -3816,6 +3816,11 @@ eval_map_expr ( return res; } +static bool is_user_input(int k) +{ + return k != (int)KE_EVENT && k != (int)KE_CURSORHOLD; +} + /* * Copy "p" to allocated memory, escaping K_SPECIAL and CSI so that the result * can be put in the typeahead buffer. diff --git a/src/keymap.h b/src/keymap.h index dd9138e05b..a08eb300a9 100644 --- a/src/keymap.h +++ b/src/keymap.h @@ -270,6 +270,7 @@ enum key_extra { , KE_NOP /* doesn't do something */ , KE_FOCUSGAINED /* focus gained */ , KE_FOCUSLOST /* focus lost */ + , KE_EVENT // event }; /* @@ -467,6 +468,7 @@ enum key_extra { #define K_FOCUSLOST TERMCAP2KEY(KS_EXTRA, KE_FOCUSLOST) #define K_CURSORHOLD TERMCAP2KEY(KS_EXTRA, KE_CURSORHOLD) +#define K_EVENT TERMCAP2KEY(KS_EXTRA, KE_EVENT) /* Bits for modifier mask */ /* 0x01 cannot be used, because the modifier must be 0x02 or higher */ diff --git a/src/message.c b/src/message.c index 57942de2c6..6553e0bd5f 100644 --- a/src/message.c +++ b/src/message.c @@ -35,6 +35,7 @@ #include "term.h" #include "ui.h" #include "os/os.h" +#include "os/event.h" #if defined(FEAT_FLOAT) # include <math.h> @@ -2094,6 +2095,9 @@ static int do_more_prompt(int typed_char) toscroll = 0; switch (c) { + case K_EVENT: + event_process(); + break; case BS: /* scroll one line back */ case K_BS: case 'k': diff --git a/src/normal.c b/src/normal.c index 27428d5dd0..cafb73cac6 100644 --- a/src/normal.c +++ b/src/normal.c @@ -54,6 +54,7 @@ #include "ui.h" #include "undo.h" #include "window.h" +#include "os/event.h" /* * The Visual area is remembered for reselection. @@ -177,6 +178,7 @@ static void nv_join(cmdarg_T *cap); static void nv_put(cmdarg_T *cap); static void nv_open(cmdarg_T *cap); static void nv_cursorhold(cmdarg_T *cap); +static void nv_event(cmdarg_T *cap); static char *e_noident = N_("E349: No identifier under cursor"); @@ -409,6 +411,7 @@ static const struct nv_cmd { {K_F8, 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[]. */ @@ -7485,3 +7488,8 @@ static void nv_cursorhold(cmdarg_T *cap) did_cursorhold = TRUE; cap->retval |= CA_COMMAND_BUSY; /* don't call edit() now */ } + +static void nv_event(cmdarg_T *cap) +{ + event_process(); +} diff --git a/src/os/event.c b/src/os/event.c index fb3fffc35a..7fc374e40e 100644 --- a/src/os/event.c +++ b/src/os/event.c @@ -20,8 +20,6 @@ KLIST_INIT(Event, Event, _destroy_event) static klist_t(Event) *event_queue; static uv_timer_t timer; static uv_prepare_t timer_prepare; -static bool poll_uv_loop(int ms); -static void process_all_events(void); static void timer_cb(uv_timer_t *handle, int); static void timer_prepare_cb(uv_prepare_t *, int); @@ -42,66 +40,8 @@ void event_init() uv_prepare_init(uv_default_loop(), &timer_prepare); } -bool event_poll(int32_t ms) -{ - int64_t remaining = ms; - uint64_t end; - bool result; - - if (ms > 0) { - // Calculate end time in nanoseconds - end = uv_hrtime() + ms * 1e6; - } - - for (;;) { - result = poll_uv_loop((int32_t)remaining); - // Process queued events - process_all_events(); - - if (ms > 0) { - // Calculate remaining time in milliseconds - remaining = (end - uv_hrtime()) / 1e6; - } - - if (input_ready() || got_int) { - // Bail out if we have pending input - return true; - } - - if (!result || (ms >= 0 && remaining <= 0)) { - // Or if we timed out - return false; - } - } -} - -// Push an event to the queue -void event_push(Event event) -{ - *kl_pushp(Event, event_queue) = event; -} - -// Runs the appropriate action for each queued event -static void process_all_events() -{ - Event event; - - while (kl_shift(Event, event_queue, &event) == 0) { - switch (event.type) { - case kEventSignal: - signal_handle(event); - break; - case kEventJobActivity: - job_handle(event); - break; - default: - abort(); - } - } -} - // Wait for some event -static bool poll_uv_loop(int32_t ms) +bool event_poll(int32_t ms) { bool timed_out; uv_run_mode run_mode = UV_RUN_ONCE; @@ -145,7 +85,37 @@ static bool poll_uv_loop(int32_t ms) uv_timer_stop(&timer); } - return input_ready() || !kl_empty(event_queue); + return input_ready() || event_is_pending(); +} + +bool event_is_pending() +{ + return !kl_empty(event_queue); +} + +// Push an event to the queue +void event_push(Event event) +{ + *kl_pushp(Event, event_queue) = event; +} + +// Runs the appropriate action for each queued event +void event_process() +{ + Event event; + + while (kl_shift(Event, event_queue, &event) == 0) { + switch (event.type) { + case kEventSignal: + signal_handle(event); + break; + case kEventJobActivity: + job_handle(event); + break; + default: + abort(); + } + } } // Set a flag in the `event_poll` loop for signaling of a timeout diff --git a/src/os/event.h b/src/os/event.h index 7aee717213..93dc96d55e 100644 --- a/src/os/event.h +++ b/src/os/event.h @@ -9,7 +9,9 @@ void event_init(void); bool event_poll(int32_t ms); +bool event_is_pending(void); void event_push(Event event); +void event_process(void); #endif // NEOVIM_OS_EVENT_H diff --git a/src/os/input.c b/src/os/input.c index 122600630d..ce1dd69fc0 100644 --- a/src/os/input.c +++ b/src/os/input.c @@ -145,9 +145,18 @@ int os_inchar(char_u *buf, int maxlen, int32_t ms, int tb_change_cnt) } } + // If there are pending events, return the keys directly + if (maxlen >= 3 && event_is_pending()) { + buf[0] = K_SPECIAL; + buf[1] = KS_EXTRA; + buf[2] = KE_EVENT; + return 3; + } + // If input was put directly in typeahead buffer bail out here. - if (typebuf_changed(tb_change_cnt)) + if (typebuf_changed(tb_change_cnt)) { return 0; + } if (result == kInputEof) { read_error_exit(); @@ -174,15 +183,12 @@ void os_breakcheck() // This is a replacement for the old `WaitForChar` function in os_unix.c static InbufPollResult inbuf_poll(int32_t ms) { - if (input_available()) + if (input_available()) { return kInputAvail; + } if (event_poll(ms)) { - if (!got_int && rbuffer.rpos == rbuffer.wpos && eof) { - return kInputEof; - } - - return kInputAvail; + return eof && rbuffer.rpos == rbuffer.wpos ? kInputEof : kInputAvail; } return kInputNone; diff --git a/src/os/job.c b/src/os/job.c index 8a02de35b7..08e8164015 100644 --- a/src/os/job.c +++ b/src/os/job.c @@ -228,7 +228,6 @@ void job_handle(Event event) job->length, job->lock == kBufferLockStdout); - shell_resized(); // restart reading job->lock = kBufferLockNone; uv_read_start((uv_stream_t *)&job->proc_stdout, alloc_cb, read_cb); |