aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/os/channel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/os/channel.c')
-rw-r--r--src/nvim/os/channel.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/nvim/os/channel.c b/src/nvim/os/channel.c
index c103a71f46..4981a268b2 100644
--- a/src/nvim/os/channel.c
+++ b/src/nvim/os/channel.c
@@ -3,6 +3,7 @@
#include <uv.h>
#include <msgpack.h>
+#include "nvim/api/private/helpers.h"
#include "nvim/os/channel.h"
#include "nvim/os/channel_defs.h"
#include "nvim/os/rstream.h"
@@ -38,16 +39,19 @@ typedef struct {
static uint64_t next_id = 1;
static Map(uint64_t) *channels = NULL;
+static msgpack_sbuffer msgpack_event_buffer;
static void on_job_stdout(RStream *rstream, void *data, bool eof);
static void on_job_stderr(RStream *rstream, void *data, bool eof);
static void parse_msgpack(RStream *rstream, void *data, bool eof);
+static void send_msgpack(Channel *channel, String type, Object data);
static void close_channel(Channel *channel);
static void close_cb(uv_handle_t *handle);
void channel_init()
{
channels = map_new(uint64_t)();
+ msgpack_sbuffer_init(&msgpack_event_buffer);
}
void channel_teardown()
@@ -117,6 +121,30 @@ void channel_from_stream(uv_stream_t *stream, ChannelProtocol prot)
map_put(uint64_t)(channels, channel->id, channel);
}
+bool channel_send_event(uint64_t id, char *type, typval_T *data)
+{
+ Channel *channel = map_get(uint64_t)(channels, id);
+
+ if (!channel) {
+ return false;
+ }
+
+ String event_type = {.size = strnlen(type, 1024), .data = type};
+ Object event_data = vim_to_object(data);
+
+ switch (channel->protocol) {
+ case kChannelProtocolMsgpack:
+ send_msgpack(channel, event_type, event_data);
+ break;
+ default:
+ abort();
+ }
+
+ msgpack_rpc_free_object(event_data);
+
+ return true;
+}
+
static void on_job_stdout(RStream *rstream, void *data, bool eof)
{
Job *job = data;
@@ -169,6 +197,21 @@ static void parse_msgpack(RStream *rstream, void *data, bool eof)
}
}
+static void send_msgpack(Channel *channel, String type, Object data)
+{
+ msgpack_packer packer;
+ msgpack_packer_init(&packer, &msgpack_event_buffer, msgpack_sbuffer_write);
+ msgpack_rpc_notification(type, data, &packer);
+ char *bytes = xmemdup(msgpack_event_buffer.data, msgpack_event_buffer.size);
+
+ wstream_write(channel->data.streams.write,
+ bytes,
+ msgpack_event_buffer.size,
+ true);
+
+ msgpack_sbuffer_clear(&msgpack_event_buffer);
+}
+
static void close_channel(Channel *channel)
{
map_del(uint64_t)(channels, channel->id);