diff options
Diffstat (limited to 'src/nvim/state.c')
-rw-r--r-- | src/nvim/state.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/nvim/state.c b/src/nvim/state.c new file mode 100644 index 0000000000..b2f3f0bebe --- /dev/null +++ b/src/nvim/state.c @@ -0,0 +1,62 @@ +#include <assert.h> + +#include "nvim/lib/kvec.h" + +#include "nvim/state.h" +#include "nvim/vim.h" +#include "nvim/getchar.h" +#include "nvim/ui.h" +#include "nvim/os/input.h" + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "state.c.generated.h" +#endif + + +void state_enter(VimState *s) +{ + for (;;) { + int check_result = s->check ? s->check(s) : 1; + + if (!check_result) { + break; + } else if (check_result == -1) { + continue; + } + + int key; + +getkey: + if (char_avail() || using_script() || input_available()) { + // Don't block for events if there's a character already available for + // processing. Characters can come from mappings, scripts and other + // sources, so this scenario is very common. + key = safe_vgetc(); + } else if (!queue_empty(loop.events)) { + // Event was made available after the last queue_process_events call + key = K_EVENT; + } else { + input_enable_events(); + // Flush screen updates before blocking + ui_flush(); + // Call `os_inchar` directly to block for events or user input without + // consuming anything from `input_buffer`(os/input.c) or calling the + // mapping engine. If an event was put into the queue, we send K_EVENT + // directly. + (void)os_inchar(NULL, 0, -1, 0); + input_disable_events(); + key = !queue_empty(loop.events) ? K_EVENT : safe_vgetc(); + } + + if (key == K_EVENT) { + may_sync_undo(); + } + + int execute_result = s->execute(s, key); + if (!execute_result) { + break; + } else if (execute_result == -1) { + goto getkey; + } + } +} |