aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/vim.c21
-rw-r--r--src/nvim/eval.c55
-rw-r--r--src/nvim/event/loop.c3
-rw-r--r--src/nvim/event/multiqueue.c35
-rw-r--r--src/nvim/memory.c4
-rw-r--r--src/nvim/msgpack_rpc/channel.c10
-rw-r--r--src/nvim/msgpack_rpc/helpers.c2
-rw-r--r--src/nvim/normal.c5
-rw-r--r--src/nvim/os/input.c16
-rw-r--r--src/nvim/state.c49
-rw-r--r--src/nvim/tui/tui.c3
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;