aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/normal.c
diff options
context:
space:
mode:
authorThiago de Arruda <tpadilha84@gmail.com>2015-10-05 12:02:13 -0300
committerThiago de Arruda <tpadilha84@gmail.com>2015-10-26 10:52:01 -0300
commit350ffc63dbd26e17c389b35d4b8b36e4ef362137 (patch)
treee9294c3189e45f77649447eada66a544810cb861 /src/nvim/normal.c
parent32594a33a3d815b0da6634cb41692e412276cb91 (diff)
downloadrneovim-350ffc63dbd26e17c389b35d4b8b36e4ef362137.tar.gz
rneovim-350ffc63dbd26e17c389b35d4b8b36e4ef362137.tar.bz2
rneovim-350ffc63dbd26e17c389b35d4b8b36e4ef362137.zip
main: Refactor normal_enter to call `os_inchar` directly
This makes it impossible for K_EVENT to interfere with mappings, but it also disables processing of events while in the middle of a mapping (Though this will be fixed later as this refactoring progresses). `may_sync_undo` is now called when K_EVENT is received. This is necessary to correctly update undo entry lists before executing some action.
Diffstat (limited to 'src/nvim/normal.c')
-rw-r--r--src/nvim/normal.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 1f2d6f9caf..8f08fe2eed 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -464,10 +464,34 @@ void normal_enter(bool cmdwin, bool noexmode)
continue;
}
- input_enable_events();
- int c = safe_vgetc();
- input_disable_events();
- if (!normal_execute(&state, c)) {
+ int key;
+
+ 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();
+ }
+
+ if (!normal_execute(&state, key)) {
break;
}
}