aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/state.c
diff options
context:
space:
mode:
authorBjörn Linse <bjorn.linse@gmail.com>2021-01-04 19:04:21 +0100
committerBjörn Linse <bjorn.linse@gmail.com>2021-03-08 16:08:58 +0100
commitf901149de4bc69f7aa4abe00dea13bca99b9c765 (patch)
tree60857ad16af1a036af89ab7c125dc250f9423f54 /src/nvim/state.c
parentc12ea02e0b5d465e2c4b7d8bba028d069bdf7008 (diff)
downloadrneovim-f901149de4bc69f7aa4abe00dea13bca99b9c765.tar.gz
rneovim-f901149de4bc69f7aa4abe00dea13bca99b9c765.tar.bz2
rneovim-f901149de4bc69f7aa4abe00dea13bca99b9c765.zip
state: throttle batched event processing when input is available
before, calling vim.schedule() from inside an event would execute the scheduled callback immediately after this event without checking for user input in between. Break event processing whenever user input or an interrupt is available.
Diffstat (limited to 'src/nvim/state.c')
-rw-r--r--src/nvim/state.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/nvim/state.c b/src/nvim/state.c
index b195c1d96b..a3c74789d1 100644
--- a/src/nvim/state.c
+++ b/src/nvim/state.c
@@ -75,6 +75,34 @@ getkey:
}
}
+/// process events on main_loop, but interrupt if input is available
+///
+/// This should be used to handle K_EVENT in states accepting input
+/// otherwise bursts of events can block break checking indefinitely.
+void state_handle_k_event(void)
+{
+ while (true) {
+ Event event = multiqueue_get(main_loop.events);
+ if (event.handler) {
+ event.handler(event.argv);
+ }
+
+ if (multiqueue_empty(main_loop.events)) {
+ // don't breakcheck before return, caller should return to main-loop
+ // and handle input already.
+ return;
+ }
+
+ // TODO(bfredl): as an further micro-optimization, we could check whether
+ // event.handler already checked input.
+ os_breakcheck();
+ if (input_available() || got_int) {
+ return;
+ }
+ }
+}
+
+
/// Return true if in the current mode we need to use virtual.
bool virtual_active(void)
{