mirror of
https://github.com/neovim/neovim.git
synced 2025-09-19 17:58:18 +00:00
api: nvim_get_mode()
Asynchronous API functions are served immediately, which means pending input could change the state of Nvim shortly after an async API function result is returned. nvim_get_mode() is different: - If RPCs are known to be blocked, it responds immediately (without flushing the input/event queue) - else it is handled just-in-time before waiting for input, after pending input was processed. This makes the result more reliable (but not perfect). Internally this is handled as a special case, but _semantically_ nothing has changed: API users never know when input flushes, so this internal special-case doesn't violate that. As far as API users are concerned, nvim_get_mode() is just another asynchronous API function. In all cases nvim_get_mode() never blocks for more than the time it takes to flush the input/event queue (~µs). Note: This doesn't address #6166; nvim_get_mode() will provoke #6166 if e.g. `d` is operator-pending. Closes #6159
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#include "nvim/main.h"
|
||||
#include "nvim/misc1.h"
|
||||
#include "nvim/state.h"
|
||||
#include "nvim/log.h"
|
||||
|
||||
#define READ_BUFFER_SIZE 0xfff
|
||||
#define INPUT_BUFFER_SIZE (READ_BUFFER_SIZE * 4)
|
||||
@@ -38,6 +39,7 @@ static RBuffer *input_buffer = NULL;
|
||||
static bool input_eof = false;
|
||||
static int global_fd = 0;
|
||||
static int events_enabled = 0;
|
||||
static bool blocking = false;
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "os/input.c.generated.h"
|
||||
@@ -327,13 +329,27 @@ static unsigned int handle_mouse_event(char **ptr, uint8_t *buf,
|
||||
return bufsize;
|
||||
}
|
||||
|
||||
/// @return true if the main loop is blocked and waiting for input.
|
||||
bool input_blocking(void)
|
||||
{
|
||||
return blocking;
|
||||
}
|
||||
|
||||
static bool input_poll(int ms)
|
||||
{
|
||||
if (do_profiling == PROF_YES && ms) {
|
||||
prof_inchar_enter();
|
||||
}
|
||||
|
||||
if ((ms == - 1 || ms > 0)
|
||||
&& !(events_enabled || input_ready() || input_eof)
|
||||
) {
|
||||
blocking = true;
|
||||
multiqueue_process_debug(main_loop.events);
|
||||
multiqueue_process_events(main_loop.events);
|
||||
}
|
||||
LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, ms, input_ready() || input_eof);
|
||||
blocking = false;
|
||||
|
||||
if (do_profiling == PROF_YES && ms) {
|
||||
prof_inchar_exit();
|
||||
|
Reference in New Issue
Block a user