diff options
Diffstat (limited to 'src/nvim/os/channel.c')
-rw-r--r-- | src/nvim/os/channel.c | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/src/nvim/os/channel.c b/src/nvim/os/channel.c index 1a2efca513..2c1928f3b3 100644 --- a/src/nvim/os/channel.c +++ b/src/nvim/os/channel.c @@ -20,11 +20,14 @@ #include "nvim/vim.h" #include "nvim/ascii.h" #include "nvim/memory.h" +#include "nvim/os_unix.h" #include "nvim/message.h" #include "nvim/map.h" #include "nvim/log.h" #include "nvim/lib/kvec.h" +#define CHANNEL_BUFFER_SIZE 0xffff + typedef struct { uint64_t request_id; bool errored; @@ -64,6 +67,10 @@ void channel_init(void) channels = pmap_new(uint64_t)(); event_strings = pmap_new(cstr_t)(); msgpack_sbuffer_init(&out_buffer); + + if (embedded_mode) { + channel_from_stdio(); + } } /// Teardown the module @@ -117,7 +124,10 @@ void channel_from_stream(uv_stream_t *stream) stream->data = NULL; channel->is_job = false; // read stream - channel->data.streams.read = rstream_new(parse_msgpack, 1024, channel, NULL); + channel->data.streams.read = rstream_new(parse_msgpack, + CHANNEL_BUFFER_SIZE, + channel, + NULL); rstream_set_stream(channel->data.streams.read, stream); rstream_start(channel->data.streams.read); // write stream @@ -256,6 +266,25 @@ void channel_unsubscribe(uint64_t id, char *event) unsubscribe(channel, event); } +/// Creates an API channel from stdin/stdout. This is used when embedding +/// Neovim +static void channel_from_stdio(void) +{ + Channel *channel = register_channel(); + channel->is_job = false; + // read stream + channel->data.streams.read = rstream_new(parse_msgpack, + CHANNEL_BUFFER_SIZE, + channel, + NULL); + rstream_set_file(channel->data.streams.read, 0); + rstream_start(channel->data.streams.read); + // write stream + channel->data.streams.write = wstream_new(0); + wstream_set_file(channel->data.streams.write, 1); + channel->data.streams.uv = NULL; +} + static void job_out(RStream *rstream, void *data, bool eof) { Job *job = data; @@ -278,6 +307,7 @@ static void job_err(RStream *rstream, void *data, bool eof) static void parse_msgpack(RStream *rstream, void *data, bool eof) { Channel *channel = data; + channel->rpc_call_level++; if (eof) { char buf[256]; @@ -287,10 +317,9 @@ static void parse_msgpack(RStream *rstream, void *data, bool eof) "closed by the client", channel->id); call_set_error(channel, buf); - return; + goto end; } - channel->rpc_call_level++; uint32_t count = rstream_available(rstream); DLOG("Feeding the msgpack parser with %u bytes of data from RStream(%p)", count, @@ -469,7 +498,12 @@ static void close_channel(Channel *channel) } else { rstream_free(channel->data.streams.read); wstream_free(channel->data.streams.write); - uv_close((uv_handle_t *)channel->data.streams.uv, close_cb); + if (channel->data.streams.uv) { + uv_close((uv_handle_t *)channel->data.streams.uv, close_cb); + } else { + // When the stdin channel closes, it's time to go + mch_exit(0); + } } free(channel); |