aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/edit.c5
-rw-r--r--src/ex_getln.c13
-rw-r--r--src/getchar.c15
-rw-r--r--src/keymap.h2
-rw-r--r--src/message.c4
-rw-r--r--src/normal.c8
-rw-r--r--src/os/event.c94
-rw-r--r--src/os/event.h2
-rw-r--r--src/os/input.c20
-rw-r--r--src/os/job.c1
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);