From 77cc078c41c4348a3649cc366a262e6fab43980b Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Mon, 20 Oct 2014 08:44:46 -0300 Subject: event: Remove EventType enum and pass a callback to `event_push` This approach is more flexible because we don't need to support a fixed set of "event types", any module can push events to be handled in main loop by simply passing a callback to the Event structure. --- src/nvim/os/signal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/os/signal.c') diff --git a/src/nvim/os/signal.c b/src/nvim/os/signal.c index 2f93cfb08a..b330c7f788 100644 --- a/src/nvim/os/signal.c +++ b/src/nvim/os/signal.c @@ -164,7 +164,7 @@ static void signal_cb(uv_signal_t *handle, int signum) Event event = { .source = signal_event_source(), - .type = kEventSignal, + .handler = signal_handle, .data = { .signum = signum } -- cgit From 264e0d872c598062be2b2a118d38c89a6ed5a023 Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Mon, 20 Oct 2014 09:25:58 -0300 Subject: event: Remove automatic event deferall This is how asynchronous events are currently handled by Nvim: - Libuv event loop is entered when Nvim blocks for user input(os_inchar is called) - Any event delivered by libuv that is not user input is queued for processing - The `K_EVENT` special key code is returned by os_inchar - `K_EVENT` is returned to a loop that is reading keys for the current Nvim mode, which will be handled by calling event_process() This approach has the advantage of integrating nicely with the current codebase, eg: vimscript code can be executed asynchronously with little surprises(Its the same as if the user typed a key). The problem with using keys to represent any event is that it also interferes with operators, and not every event needs or should do that. For example, consider this scenario: - A msgpack-rpc client calls vim_feedkeys("d") - Nvim processes K_EVENT, pushing "d" to the input queue - Nvim processes "d", entering operator-pending mode to wait for a motion - The client calls vim_feedkeys("w"), expecting Nvim to delete a word - Nvim processes K_EVENT, breaking out of operator-pending and pushing "w" - Nvim processes "w", moving a word This commit fixes the above problem by removing all automatic calls to `event_push`(which is what generates K_EVENT input). Right now this also breaks redrawing initiated by asynchronous events(and possibly other stuff too, Nvim is a complex state machine and we can't simply run vimscript code anywhere). In future commits the calls to `event_push` will be inserted only where it's absolutely necessary to run code in "key reading loops", such as when executing vimscript code or mutating editor data structures in ways that currently can only be done by the user. --- src/nvim/os/signal.c | 81 +++++++++++++++++----------------------------------- 1 file changed, 26 insertions(+), 55 deletions(-) (limited to 'src/nvim/os/signal.c') diff --git a/src/nvim/os/signal.c b/src/nvim/os/signal.c index b330c7f788..36f7b37c48 100644 --- a/src/nvim/os/signal.c +++ b/src/nvim/os/signal.c @@ -12,8 +12,6 @@ #include "nvim/memory.h" #include "nvim/misc1.h" #include "nvim/misc2.h" -#include "nvim/os/event_defs.h" -#include "nvim/os/event.h" #include "nvim/os/signal.h" static uv_signal_t sint, spipe, shup, squit, sterm, swinch; @@ -72,45 +70,6 @@ void signal_accept_deadly(void) rejecting_deadly = false; } -void signal_handle(Event event) -{ - int signum = event.data.signum; - - switch (signum) { - case SIGINT: - got_int = true; - break; -#ifdef SIGPWR - case SIGPWR: - // Signal of a power failure(eg batteries low), flush the swap files to - // be safe - ml_sync_all(false, false); - break; -#endif - case SIGPIPE: - // Ignore - break; - case SIGWINCH: - shell_resized(); - break; - case SIGTERM: - case SIGQUIT: - case SIGHUP: - if (!rejecting_deadly) { - deadly_signal(signum); - } - break; - default: - fprintf(stderr, "Invalid signal %d", signum); - break; - } -} - -EventSource signal_event_source(void) -{ - return &sint; -} - static char * signal_name(int signum) { switch (signum) { @@ -154,20 +113,32 @@ static void deadly_signal(int signum) static void signal_cb(uv_signal_t *handle, int signum) { - if (rejecting_deadly) { - if (signum == SIGINT) { + switch (signum) { + case SIGINT: got_int = true; - } - - return; + break; +#ifdef SIGPWR + case SIGPWR: + // Signal of a power failure(eg batteries low), flush the swap files to + // be safe + ml_sync_all(false, false); + break; +#endif + case SIGPIPE: + // Ignore + break; + case SIGWINCH: + shell_resized(); + break; + case SIGTERM: + case SIGQUIT: + case SIGHUP: + if (!rejecting_deadly) { + deadly_signal(signum); + } + break; + default: + fprintf(stderr, "Invalid signal %d", signum); + break; } - - Event event = { - .source = signal_event_source(), - .handler = signal_handle, - .data = { - .signum = signum - } - }; - event_push(event); } -- cgit