mirror of
https://github.com/neovim/neovim.git
synced 2025-10-06 18:06:30 +00:00
fix(tui): more work in the TUI
This commit is contained in:
@@ -250,8 +250,8 @@ static void parse_msgpack(Channel *channel)
|
||||
ui_client_event_raw_line(p->grid_line_event);
|
||||
} else if (p->ui_handler.fn != NULL && p->result.type == kObjectTypeArray) {
|
||||
p->ui_handler.fn(p->result.data.array);
|
||||
arena_mem_free(arena_finish(&p->arena));
|
||||
}
|
||||
arena_mem_free(arena_finish(&p->arena));
|
||||
} else if (p->type == kMessageTypeResponse) {
|
||||
ChannelCallFrame *frame = kv_last(channel->rpc.call_stack);
|
||||
if (p->request_id != frame->request_id) {
|
||||
@@ -299,7 +299,7 @@ static void handle_request(Channel *channel, Unpacker *p, Array args)
|
||||
assert(p->type == kMessageTypeRequest || p->type == kMessageTypeNotification);
|
||||
|
||||
if (!p->handler.fn) {
|
||||
send_error(channel, p->type, p->request_id, p->unpack_error.msg);
|
||||
send_error(channel, p->handler, p->type, p->request_id, p->unpack_error.msg);
|
||||
api_clear_error(&p->unpack_error);
|
||||
arena_mem_free(arena_finish(&p->arena));
|
||||
return;
|
||||
@@ -358,6 +358,7 @@ static void request_event(void **argv)
|
||||
msgpack_packer response;
|
||||
msgpack_packer_init(&response, &out_buffer, msgpack_sbuffer_write);
|
||||
channel_write(channel, serialize_response(channel->id,
|
||||
e->handler,
|
||||
e->type,
|
||||
e->request_id,
|
||||
&error,
|
||||
@@ -440,11 +441,13 @@ static void internal_read_event(void **argv)
|
||||
wstream_release_wbuffer(buffer);
|
||||
}
|
||||
|
||||
static void send_error(Channel *chan, MessageType type, uint32_t id, char *err)
|
||||
static void send_error(Channel *chan, MsgpackRpcRequestHandler handler, MessageType type,
|
||||
uint32_t id, char *err)
|
||||
{
|
||||
Error e = ERROR_INIT;
|
||||
api_set_error(&e, kErrorTypeException, "%s", err);
|
||||
channel_write(chan, serialize_response(chan->id,
|
||||
handler,
|
||||
type,
|
||||
id,
|
||||
&e,
|
||||
@@ -543,26 +546,8 @@ void rpc_close(Channel *channel)
|
||||
channel_decref(channel);
|
||||
|
||||
if (channel->streamtype == kChannelStreamStdio
|
||||
|| channel->id == ui_client_channel_id) {
|
||||
multiqueue_put(main_loop.fast_events, exit_event, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void exit_delay_cb(uv_timer_t *handle)
|
||||
{
|
||||
uv_timer_stop(&main_loop.exit_delay_timer);
|
||||
multiqueue_put(main_loop.fast_events, exit_event, 0);
|
||||
}
|
||||
|
||||
static void exit_event(void **argv)
|
||||
{
|
||||
if (exit_need_delay) {
|
||||
uv_timer_start(&main_loop.exit_delay_timer, exit_delay_cb, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!exiting) {
|
||||
os_exit(0);
|
||||
|| (channel->id == ui_client_channel_id && channel->streamtype != kChannelStreamProc)) {
|
||||
exit_from_channel(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -612,18 +597,27 @@ static WBuffer *serialize_request(uint64_t channel_id, uint32_t request_id, cons
|
||||
return rv;
|
||||
}
|
||||
|
||||
static WBuffer *serialize_response(uint64_t channel_id, MessageType type, uint32_t response_id,
|
||||
Error *err, Object arg, msgpack_sbuffer *sbuffer)
|
||||
static WBuffer *serialize_response(uint64_t channel_id, MsgpackRpcRequestHandler handler,
|
||||
MessageType type, uint32_t response_id, Error *err, Object arg,
|
||||
msgpack_sbuffer *sbuffer)
|
||||
{
|
||||
msgpack_packer pac;
|
||||
msgpack_packer_init(&pac, sbuffer, msgpack_sbuffer_write);
|
||||
if (ERROR_SET(err) && type == kMessageTypeNotification) {
|
||||
Array args = ARRAY_DICT_INIT;
|
||||
ADD(args, INTEGER_OBJ(err->type));
|
||||
ADD(args, STRING_OBJ(cstr_to_string(err->msg)));
|
||||
msgpack_rpc_serialize_request(0, cstr_as_string("nvim_error_event"),
|
||||
args, &pac);
|
||||
api_free_array(args);
|
||||
if (handler.fn == handle_nvim_paste) {
|
||||
// TODO(bfredl): this is pretty much ad-hoc. maybe TUI and UI:s should be
|
||||
// allowed to ask nvim to just scream directly in the users face
|
||||
// instead of sending nvim_error_event, in general.
|
||||
semsg("paste: %s", err->msg);
|
||||
api_clear_error(err);
|
||||
} else {
|
||||
Array args = ARRAY_DICT_INIT;
|
||||
ADD(args, INTEGER_OBJ(err->type));
|
||||
ADD(args, STRING_OBJ(cstr_to_string(err->msg)));
|
||||
msgpack_rpc_serialize_request(0, cstr_as_string("nvim_error_event"),
|
||||
args, &pac);
|
||||
api_free_array(args);
|
||||
}
|
||||
} else {
|
||||
msgpack_rpc_serialize_response(response_id, err, arg, &pac);
|
||||
}
|
||||
|
@@ -298,7 +298,7 @@ error:
|
||||
//
|
||||
// When method is "grid_line", we furthermore decode a cell at a time like:
|
||||
//
|
||||
// <0>[2, "redraw", <10>[{11}["grid_line", <13>[g, r, c, [<14>[cell], <14>[cell], ...]], ...], <11>[...], ...]]
|
||||
// <0>[2, "redraw", <10>[{11}["grid_line", <14>[g, r, c, [<15>[cell], <15>[cell], ...]], ...], <11>[...], ...]]
|
||||
//
|
||||
// where [cell] is [char, repeat, attr], where 'repeat' and 'attr' is optional
|
||||
|
||||
@@ -318,17 +318,19 @@ bool unpacker_advance(Unpacker *p)
|
||||
}
|
||||
}
|
||||
|
||||
if (p->state >= 10 && p->state != 12) {
|
||||
if (p->state >= 10 && p->state != 13) {
|
||||
if (!unpacker_parse_redraw(p)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (p->state == 14) {
|
||||
if (p->state == 15) {
|
||||
// grid_line event already unpacked
|
||||
goto done;
|
||||
} else {
|
||||
assert(p->state == 12);
|
||||
// unpack other ui events using mpack_parse()
|
||||
p->arena = (Arena)ARENA_EMPTY;
|
||||
p->state = 13;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,11 +357,11 @@ done:
|
||||
case 2:
|
||||
p->state = 0;
|
||||
return true;
|
||||
case 12:
|
||||
case 14:
|
||||
case 13:
|
||||
case 15:
|
||||
p->ncalls--;
|
||||
if (p->ncalls > 0) {
|
||||
p->state = (p->state == 14) ? 13 : 12;
|
||||
p->state = (p->state == 15) ? 14 : 12;
|
||||
} else if (p->nevents > 0) {
|
||||
p->state = 11;
|
||||
} else {
|
||||
@@ -428,14 +430,14 @@ redo:
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
p->state = 13;
|
||||
p->state = 14;
|
||||
p->arena = (Arena)ARENA_EMPTY;
|
||||
p->grid_line_event = arena_alloc(&p->arena, sizeof *p->grid_line_event, true);
|
||||
g = p->grid_line_event;
|
||||
}
|
||||
FALLTHROUGH;
|
||||
|
||||
case 13:
|
||||
case 14:
|
||||
NEXT_TYPE(tok, MPACK_TOKEN_ARRAY);
|
||||
int eventarrsize = (int)tok.length;
|
||||
if (eventarrsize != 4) {
|
||||
@@ -456,10 +458,10 @@ redo:
|
||||
|
||||
p->read_ptr = data;
|
||||
p->read_size = size;
|
||||
p->state = 14;
|
||||
p->state = 15;
|
||||
FALLTHROUGH;
|
||||
|
||||
case 14:
|
||||
case 15:
|
||||
assert(g->icell < g->ncells);
|
||||
|
||||
NEXT_TYPE(tok, MPACK_TOKEN_ARRAY);
|
||||
@@ -513,6 +515,9 @@ redo:
|
||||
}
|
||||
goto redo;
|
||||
|
||||
case 12:
|
||||
return true;
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
Reference in New Issue
Block a user