diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/vim.c | 21 | ||||
-rw-r--r-- | src/nvim/eval.c | 55 | ||||
-rw-r--r-- | src/nvim/event/loop.c | 3 | ||||
-rw-r--r-- | src/nvim/event/multiqueue.c | 35 | ||||
-rw-r--r-- | src/nvim/memory.c | 4 | ||||
-rw-r--r-- | src/nvim/msgpack_rpc/channel.c | 10 | ||||
-rw-r--r-- | src/nvim/msgpack_rpc/helpers.c | 2 | ||||
-rw-r--r-- | src/nvim/normal.c | 5 | ||||
-rw-r--r-- | src/nvim/os/input.c | 16 | ||||
-rw-r--r-- | src/nvim/state.c | 49 | ||||
-rw-r--r-- | src/nvim/tui/tui.c | 3 |
11 files changed, 143 insertions, 60 deletions
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index da00fbc6e3..7c57a5b456 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -11,6 +11,7 @@ #include "nvim/api/vim.h" #include "nvim/ascii.h" +#include "nvim/log.h" #include "nvim/api/private/helpers.h" #include "nvim/api/private/defs.h" #include "nvim/api/buffer.h" @@ -27,6 +28,7 @@ #include "nvim/eval.h" #include "nvim/eval/typval.h" #include "nvim/option.h" +#include "nvim/state.h" #include "nvim/syntax.h" #include "nvim/getchar.h" #include "nvim/os/input.h" @@ -701,6 +703,25 @@ Dictionary nvim_get_color_map(void) } +/// Gets the current mode. +/// mode: Mode string. |mode()| +/// blocking: true if Nvim is waiting for input. +/// +/// @returns Dictionary { "mode": String, "blocking": Boolean } +Dictionary nvim_get_mode(void) + FUNC_API_SINCE(2) FUNC_API_ASYNC +{ + Dictionary rv = ARRAY_DICT_INIT; + char *modestr = get_mode(); + bool blocked = input_blocking(); + ILOG("blocked=%d", blocked); + + PUT(rv, "mode", STRING_OBJ(cstr_as_string(modestr))); + PUT(rv, "blocking", BOOLEAN_OBJ(blocked)); + + return rv; +} + Array nvim_get_api_info(uint64_t channel_id) FUNC_API_SINCE(1) FUNC_API_ASYNC FUNC_API_NOEVAL { diff --git a/src/nvim/eval.c b/src/nvim/eval.c index c02d172458..b0f47d8e45 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -12575,59 +12575,18 @@ static void f_mkdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } -/* - * "mode()" function - */ +/// "mode()" function static void f_mode(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - char_u buf[3]; + char *mode = get_mode(); - buf[1] = NUL; - buf[2] = NUL; - - if (VIsual_active) { - if (VIsual_select) - buf[0] = VIsual_mode + 's' - 'v'; - else - buf[0] = VIsual_mode; - } else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE - || State == CONFIRM) { - buf[0] = 'r'; - if (State == ASKMORE) - buf[1] = 'm'; - else if (State == CONFIRM) - buf[1] = '?'; - } else if (State == EXTERNCMD) - buf[0] = '!'; - else if (State & INSERT) { - if (State & VREPLACE_FLAG) { - buf[0] = 'R'; - buf[1] = 'v'; - } else if (State & REPLACE_FLAG) - buf[0] = 'R'; - else - buf[0] = 'i'; - } else if (State & CMDLINE) { - buf[0] = 'c'; - if (exmode_active) - buf[1] = 'v'; - } else if (exmode_active) { - buf[0] = 'c'; - buf[1] = 'e'; - } else if (State & TERM_FOCUS) { - buf[0] = 't'; - } else { - buf[0] = 'n'; - if (finish_op) - buf[1] = 'o'; + // Clear out the minor mode when the argument is not a non-zero number or + // non-empty string. + if (!non_zero_arg(&argvars[0])) { + mode[1] = NUL; } - /* Clear out the minor mode when the argument is not a non-zero number or - * non-empty string. */ - if (!non_zero_arg(&argvars[0])) - buf[1] = NUL; - - rettv->vval.v_string = vim_strsave(buf); + rettv->vval.v_string = (char_u *)mode; rettv->v_type = VAR_STRING; } diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c index 6963978581..c709ce9a1c 100644 --- a/src/nvim/event/loop.c +++ b/src/nvim/event/loop.c @@ -44,8 +44,7 @@ void loop_poll_events(Loop *loop, int ms) // we do not block indefinitely for I/O. uv_timer_start(&loop->poll_timer, timer_cb, (uint64_t)ms, (uint64_t)ms); } else if (ms == 0) { - // For ms == 0, we need to do a non-blocking event poll by - // setting the run mode to UV_RUN_NOWAIT. + // For ms == 0, do a non-blocking event poll. mode = UV_RUN_NOWAIT; } diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c index a17bae31e3..b144347fdb 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -55,6 +55,7 @@ #include "nvim/event/multiqueue.h" #include "nvim/memory.h" +#include "nvim/log.h" #include "nvim/os/time.h" typedef struct multiqueue_item MultiQueueItem; @@ -151,6 +152,40 @@ void multiqueue_process_events(MultiQueue *this) } } +void multiqueue_process_debug(MultiQueue *this) +{ + assert(this); + QUEUE *start = QUEUE_HEAD(&this->headtail); + QUEUE *cur = start; + // MultiQueue *start = this; + // MultiQueue *cur = start; + do { + MultiQueueItem *item = multiqueue_node_data(cur); + Event ev; + if (item->link) { + assert(!this->parent); + // get the next node in the linked queue + MultiQueue *linked = item->data.queue; + assert(!multiqueue_empty(linked)); + MultiQueueItem *child = + multiqueue_node_data(QUEUE_HEAD(&linked->headtail)); + ev = child->data.item.event; + } else { + ev = item->data.item.event; + } + + // Event event = multiqueue_get(this); + // if (event.handler) { + // event.handler(event.argv); + // } + + ILOG("ev: priority=%d, handler=%p arg1=%s", ev.priority, ev.handler, + ev.argv ? ev.argv[0] : "(null)"); + + cur = cur->next; + } while (cur && cur != start); +} + /// Removes all events without processing them. void multiqueue_purge_events(MultiQueue *this) { diff --git a/src/nvim/memory.c b/src/nvim/memory.c index 0ee4776581..74c58fb203 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -345,10 +345,6 @@ char *xstpcpy(char *restrict dst, const char *restrict src) /// WARNING: xstpncpy will ALWAYS write maxlen bytes. If src is shorter than /// maxlen, zeroes will be written to the remaining bytes. /// -/// TODO(aktau): I don't see a good reason to have this last behaviour, and -/// it is potentially wasteful. Could we perhaps deviate from the standard -/// and not zero the rest of the buffer? -/// /// @param dst /// @param src /// @param maxlen diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 59594357de..799e6eadef 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -28,7 +28,9 @@ #include "nvim/map.h" #include "nvim/log.h" #include "nvim/misc1.h" +#include "nvim/state.h" #include "nvim/lib/kvec.h" +#include "nvim/os/input.h" #define CHANNEL_BUFFER_SIZE 0xffff @@ -433,6 +435,14 @@ static void handle_request(Channel *channel, msgpack_object *request) handler.async = true; } + if (handler.async) { + char buf[256] = { 0 }; + memcpy(buf, method->via.bin.ptr, MIN(255, method->via.bin.size)); + if (strcmp("nvim_get_mode", buf) == 0) { + handler.async = input_blocking(); + } + } + RequestEvent *event_data = xmalloc(sizeof(RequestEvent)); event_data->channel = channel; event_data->handler = handler; diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index 0228582d37..91ef5524ea 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -76,7 +76,7 @@ typedef struct { size_t idx; } MPToAPIObjectStackItem; -/// Convert type used by msgpack parser to Neovim own API type +/// Convert type used by msgpack parser to Nvim API type. /// /// @param[in] obj Msgpack value to convert. /// @param[out] arg Location where result of conversion will be saved. diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 51da9429b6..09ad7beb4b 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -14,6 +14,7 @@ #include <stdlib.h> #include "nvim/vim.h" +#include "nvim/log.h" #include "nvim/ascii.h" #include "nvim/normal.h" #include "nvim/buffer.h" @@ -541,7 +542,7 @@ static bool normal_handle_special_visual_command(NormalState *s) return false; } -static bool normal_need_aditional_char(NormalState *s) +static bool normal_need_additional_char(NormalState *s) { int flags = nv_cmds[s->idx].cmd_flags; bool pending_op = s->oa.op_type != OP_NOP; @@ -1083,7 +1084,7 @@ static int normal_execute(VimState *state, int key) } // Get an additional character if we need one. - if (normal_need_aditional_char(s)) { + if (normal_need_additional_char(s)) { normal_get_additional_char(s); } diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index 7b5e14dd19..26f2be6c02 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -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(); diff --git a/src/nvim/state.c b/src/nvim/state.c index 210708c3f4..be6aa21664 100644 --- a/src/nvim/state.c +++ b/src/nvim/state.c @@ -98,3 +98,52 @@ int get_real_state(void) return State; } +/// @returns[allocated] mode string +char *get_mode(void) +{ + char *buf = xcalloc(3, sizeof(char)); + + if (VIsual_active) { + if (VIsual_select) { + buf[0] = (char)(VIsual_mode + 's' - 'v'); + } else { + buf[0] = (char)VIsual_mode; + } + } else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE + || State == CONFIRM) { + buf[0] = 'r'; + if (State == ASKMORE) { + buf[1] = 'm'; + } else if (State == CONFIRM) { + buf[1] = '?'; + } + } else if (State == EXTERNCMD) { + buf[0] = '!'; + } else if (State & INSERT) { + if (State & VREPLACE_FLAG) { + buf[0] = 'R'; + buf[1] = 'v'; + } else if (State & REPLACE_FLAG) { + buf[0] = 'R'; + } else { + buf[0] = 'i'; + } + } else if (State & CMDLINE) { + buf[0] = 'c'; + if (exmode_active) { + buf[1] = 'v'; + } + } else if (exmode_active) { + buf[0] = 'c'; + buf[1] = 'e'; + } else if (State & TERM_FOCUS) { + buf[0] = 't'; + } else { + buf[0] = 'n'; + if (finish_op) { + buf[1] = 'o'; + } + } + + return buf; +} diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 21abc19c47..356221f7ce 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -74,9 +74,6 @@ typedef struct { bool out_isatty; SignalWatcher winch_handle, cont_handle; bool cont_received; - // Event scheduled by the ui bridge. Since the main thread suspends until - // the event is handled, it is fine to use a single field instead of a queue - Event scheduled_event; UGrid grid; kvec_t(Rect) invalid_regions; int out_fd; |