mirror of
https://github.com/neovim/neovim.git
synced 2024-09-17 20:58:20 -04:00
feat(ui): detach UI via [count]ctrl-z
how to get server-side channel-id from client: diff --git a/src/nvim/main.c b/src/nvim/main.c index f699d4484fe2..421277a396f1 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -656,7 +656,6 @@ int main(int argc, char **argv) TIME_MSG("before starting main loop"); ILOG("starting main loop"); - ELOG("xxx %" PRId64, ui_client_channel_id); // Main loop: never returns. normal_enter(false, false); @@ -917,26 +916,6 @@ static uint64_t server_connect(char *server_addr, const char **errmsg) *errmsg = error; return 0; } - - Error err = ERROR_INIT; - Arena arena = ARENA_EMPTY; - - Array args = arena_array(&arena, (size_t)1); - ADD(args, INTEGER_OBJ(0)); - ArenaMem res_mem = NULL; - Object result = rpc_send_call(chan, "nvim_get_chan_info", args, &res_mem, &err); - if (!ERROR_SET(&err)) { - arena_mem_free(res_mem); - ui_server_chan = result.data.dictionary.items[0].value.data.integer; - assert(ui_server_chan > 0); - } - arena_mem_free(arena_finish(&arena)); - - if (ERROR_SET(&err)) { - ELOG("nvim_get_chan_info failed: %s", err.msg); - api_clear_error(&err); - } - return chan; } @@ -966,7 +945,6 @@ static void remote_request(mparm_T *params, int remote_args, char *server_addr, } ui_client_channel_id = chan; - ELOG("xxx main:remote_request ui_channel=%" PRId64, ui_client_channel_id); return; } diff --git a/src/nvim/ui_client.h b/src/nvim/ui_client.h index b59972022613..928bd4c0a525 100644 --- a/src/nvim/ui_client.h +++ b/src/nvim/ui_client.h @@ -16,8 +16,6 @@ EXTERN sattr_T *grid_line_buf_attr INIT( = NULL); // Client-side UI channel. Zero during early startup or if not a (--remote-ui) UI client. EXTERN uint64_t ui_client_channel_id INIT( = 0); -// UI client server-side channel id. -EXTERN int64_t ui_server_chan INIT( = 0); // exit status from embedded nvim process EXTERN int ui_client_exit_status INIT( = 0);
This commit is contained in:
parent
7ed9fd0573
commit
b6b9b71c43
@ -359,11 +359,11 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_ks)
|
||||
/// @param keys to be typed
|
||||
/// @return Number of bytes actually written (can be fewer than
|
||||
/// requested if the buffer becomes full).
|
||||
Integer nvim_input(String keys)
|
||||
Integer nvim_input(uint64_t channel_id, String keys)
|
||||
FUNC_API_SINCE(1) FUNC_API_FAST
|
||||
{
|
||||
may_trigger_vim_suspend_resume(false);
|
||||
return (Integer)input_enqueue(keys);
|
||||
return (Integer)input_enqueue(channel_id, keys);
|
||||
}
|
||||
|
||||
/// Send mouse event from GUI.
|
||||
|
@ -416,13 +416,19 @@ static void exit_event(void **argv)
|
||||
os_exit(status);
|
||||
} else {
|
||||
assert(status == 0); // Called from rpc_close(), which passes 0 as status.
|
||||
preserve_exit(NULL);
|
||||
// TODO(justinmk):
|
||||
// - make this optional ("nvim --nohup")?
|
||||
// - dynamic: can be set on the channel at any time
|
||||
// - TUI sets this on SIGUP
|
||||
// preserve_exit(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs self-exit when the RPC channel is closed.
|
||||
void exit_from_channel(int status)
|
||||
{
|
||||
DLOG("self-exit triggered by closed RPC channel...");
|
||||
multiqueue_put(main_loop.fast_events, exit_event, (void *)(intptr_t)status);
|
||||
}
|
||||
|
||||
|
@ -220,8 +220,7 @@ static size_t receive_msgpack(RStream *stream, const char *rbuf, size_t c, void
|
||||
if (eof) {
|
||||
channel_close(channel->id, kChannelPartRpc, NULL);
|
||||
char buf[256];
|
||||
snprintf(buf, sizeof(buf), "ch %" PRIu64 " was closed by the client",
|
||||
channel->id);
|
||||
snprintf(buf, sizeof(buf), "ch %" PRIu64 " was closed by the peer", channel->id);
|
||||
chan_close_with_error(channel, buf, LOGLVL_INF);
|
||||
}
|
||||
|
||||
|
@ -14,13 +14,16 @@
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "nvim/api/private/defs.h"
|
||||
#include "nvim/api/private/helpers.h"
|
||||
#include "nvim/api/ui.h"
|
||||
#include "nvim/ascii_defs.h"
|
||||
#include "nvim/autocmd.h"
|
||||
#include "nvim/autocmd_defs.h"
|
||||
#include "nvim/buffer.h"
|
||||
#include "nvim/buffer_defs.h"
|
||||
#include "nvim/change.h"
|
||||
#include "nvim/channel.h"
|
||||
#include "nvim/charset.h"
|
||||
#include "nvim/cmdhist.h"
|
||||
#include "nvim/cursor.h"
|
||||
@ -58,11 +61,13 @@
|
||||
#include "nvim/message.h"
|
||||
#include "nvim/mouse.h"
|
||||
#include "nvim/move.h"
|
||||
#include "nvim/msgpack_rpc/channel.h"
|
||||
#include "nvim/normal.h"
|
||||
#include "nvim/ops.h"
|
||||
#include "nvim/option.h"
|
||||
#include "nvim/option_vars.h"
|
||||
#include "nvim/os/input.h"
|
||||
#include "nvim/os/os.h"
|
||||
#include "nvim/os/time.h"
|
||||
#include "nvim/plines.h"
|
||||
#include "nvim/profile.h"
|
||||
@ -5121,14 +5126,55 @@ static void nv_window(cmdarg_T *cap)
|
||||
}
|
||||
}
|
||||
|
||||
/// CTRL-Z: Suspend
|
||||
/// CTRL-Z: Suspend, or Detach UI
|
||||
static void nv_suspend(cmdarg_T *cap)
|
||||
{
|
||||
clearop(cap->oap);
|
||||
if (VIsual_active) {
|
||||
end_visual_mode(); // stop Visual mode
|
||||
}
|
||||
do_cmdline_cmd("st");
|
||||
|
||||
if (input_chan_id == 0 || /*input_chan_id == 1 ||*/ is_internal_call(input_chan_id)) {
|
||||
if (input_chan_id == 1) {
|
||||
ILOG("xxx ui_channel=%" PRId64, input_chan_id);
|
||||
}
|
||||
// TODO(justinmk): show a confirm dialog if multiple UIs are attached?
|
||||
if (ui_active() > 1) {
|
||||
emsg("UIs are connected, no sussy baka");
|
||||
} else {
|
||||
do_cmdline_cmd("suspend");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// come on pooky let's burn this burn this mf down
|
||||
ILOG("xxx DETACHED ui_channel=%" PRId64, input_chan_id);
|
||||
|
||||
// MAXSIZE_TEMP_ARRAY(args2, 1);
|
||||
// ADD_C(args2, INTEGER_OBJ((Integer)ui_client_channel_id));
|
||||
// MAXSIZE_TEMP_ARRAY(args, 2);
|
||||
// ADD_C(args, CSTR_TO_OBJ("chanclose")); // CSTR_AS_OBJ
|
||||
// ADD_C(args, ARRAY_OBJ(args2));
|
||||
// rpc_send_event(ui_client_channel_id, "nvim_call_function", args);
|
||||
|
||||
// Only detaches UI, but we want to exit the client fully.
|
||||
// rpc_send_event(input_chan_id, "nvim_ui_detach", (Array)ARRAY_DICT_INIT);
|
||||
// {
|
||||
// Error err;
|
||||
// nvim_ui_detach(input_chan_id, &err);
|
||||
// if (ERROR_SET(&err)) {
|
||||
// emsg(err.msg); // UI may have disappeared already.
|
||||
// }
|
||||
// api_clear_error(&err);
|
||||
// }
|
||||
|
||||
{
|
||||
const char *err;
|
||||
bool rv = channel_close(input_chan_id, kChannelPartAll, &err);
|
||||
if (!rv) {
|
||||
emsg(err); // UI may have disappeared already.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// "gv": Reselect the previous Visual area. If Visual already active,
|
||||
|
@ -273,7 +273,7 @@ void input_enqueue_raw(const char *data, size_t size)
|
||||
input_write_pos += to_write;
|
||||
}
|
||||
|
||||
size_t input_enqueue(String keys)
|
||||
size_t input_enqueue(uint64_t chan_id, String keys)
|
||||
{
|
||||
const char *ptr = keys.data;
|
||||
const char *end = ptr + keys.size;
|
||||
@ -323,6 +323,8 @@ size_t input_enqueue(String keys)
|
||||
|
||||
size_t rv = (size_t)(ptr - keys.data);
|
||||
process_ctrl_c();
|
||||
input_chan_id = chan_id;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,9 @@
|
||||
#include "nvim/macros_defs.h"
|
||||
|
||||
EXTERN bool used_stdin INIT( = false);
|
||||
/// Last channel that invoked 'nvim_input`.
|
||||
/// TODO(justinmk): race condition if multiple UIs/scripts send input?
|
||||
EXTERN uint64_t input_chan_id INIT( = 0);
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "os/input.h.generated.h"
|
||||
|
@ -61,12 +61,17 @@ uint64_t ui_client_start_server(int argc, char **argv)
|
||||
|
||||
Channel *channel = channel_job_start(args, get_vim_var_str(VV_PROGPATH),
|
||||
CALLBACK_READER_INIT, on_err, CALLBACK_NONE,
|
||||
false, true, true, false, kChannelStdinPipe,
|
||||
false, true, true, true, kChannelStdinPipe,
|
||||
NULL, 0, 0, NULL, &exit_status);
|
||||
if (!channel) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// channel->stream.proc.out.s.close_cb = on_stdio_close;
|
||||
// channel->stream.proc.in.close_cb = on_stdio_close;
|
||||
channel->stream.proc.in.internal_close_cb = on_stdio_close;
|
||||
channel->stream.proc.in.internal_data = channel;
|
||||
|
||||
// If stdin is not a pty, it is forwarded to the client.
|
||||
// Replace stdin in the TUI process with the tty fd.
|
||||
if (ui_client_forward_stdin) {
|
||||
@ -81,6 +86,14 @@ uint64_t ui_client_start_server(int argc, char **argv)
|
||||
return channel->id;
|
||||
}
|
||||
|
||||
static void on_stdio_close(Stream *stream, void *data)
|
||||
FUNC_ATTR_NORETURN
|
||||
{
|
||||
// Channel *chan = data;
|
||||
ELOG("xxxxxxxxxxxxxxxxxxxxxxxxxxx");
|
||||
os_exit(0);
|
||||
}
|
||||
|
||||
/// Attaches this client to the UI channel, and sets its client info.
|
||||
void ui_client_attach(int width, int height, char *term, bool rgb)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user