aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ex_docmd.c
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2025-02-10 10:21:47 -0800
committerGitHub <noreply@github.com>2025-02-10 10:21:47 -0800
commitc7d13f2895fa657ff3d9d45741f9abec25072b56 (patch)
tree0b61d786b8fb318a0e9b2c53eb633332af5aa05d /src/nvim/ex_docmd.c
parentad60b3fb4806c0917010bbe97876c22fb57cabcd (diff)
parenta1906c23ddab6fa4d15bc5ceddee97df8034d8cb (diff)
downloadrneovim-c7d13f2895fa657ff3d9d45741f9abec25072b56.tar.gz
rneovim-c7d13f2895fa657ff3d9d45741f9abec25072b56.tar.bz2
rneovim-c7d13f2895fa657ff3d9d45741f9abec25072b56.zip
Merge #32385 UI :detach command
Diffstat (limited to 'src/nvim/ex_docmd.c')
-rw-r--r--src/nvim/ex_docmd.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index ceb17a995d..3b78092daf 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -14,6 +14,7 @@
#include "auto/config.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
+#include "nvim/api/ui.h"
#include "nvim/arglist.h"
#include "nvim/ascii_defs.h"
#include "nvim/autocmd.h"
@@ -21,6 +22,7 @@
#include "nvim/buffer.h"
#include "nvim/buffer_defs.h"
#include "nvim/change.h"
+#include "nvim/channel.h"
#include "nvim/charset.h"
#include "nvim/cmdexpand.h"
#include "nvim/cmdexpand_defs.h"
@@ -67,6 +69,7 @@
#include "nvim/message.h"
#include "nvim/mouse.h"
#include "nvim/move.h"
+#include "nvim/msgpack_rpc/server.h"
#include "nvim/normal.h"
#include "nvim/normal_defs.h"
#include "nvim/ops.h"
@@ -5530,6 +5533,56 @@ static void ex_tabs(exarg_T *eap)
}
}
+/// ":detach"
+///
+/// Detaches the current UI.
+///
+/// ":detach!" with bang (!) detaches all UIs _except_ the current UI.
+static void ex_detach(exarg_T *eap)
+{
+ // come on pooky let's burn this mf down
+ if (eap && eap->forceit) {
+ emsg("bang (!) not supported yet");
+ } else {
+ // 1. (TODO) Send "detach" UI-event (notification only).
+ // 2. Perform server-side `nvim_ui_detach`.
+ // 3. Close server-side channel without self-exit.
+
+ if (!current_ui) {
+ emsg("UI not attached");
+ return;
+ }
+
+ Channel *chan = find_channel(current_ui);
+ if (!chan) {
+ emsg(e_invchan);
+ return;
+ }
+ chan->detach = true; // Prevent self-exit on channel-close.
+
+ // Server-side UI detach. Doesn't close the channel.
+ Error err2 = ERROR_INIT;
+ nvim_ui_detach(chan->id, &err2);
+ if (ERROR_SET(&err2)) {
+ emsg(err2.msg); // UI disappeared already?
+ api_clear_error(&err2);
+ return;
+ }
+
+ // Server-side channel close.
+ const char *err = NULL;
+ bool rv = channel_close(chan->id, kChannelPartAll, &err);
+ if (!rv && err) {
+ emsg(err); // UI disappeared already?
+ return;
+ }
+ // XXX: Can't do this, channel_decref() is async...
+ // assert(!find_channel(chan->id));
+
+ ILOG("detach current_ui=%" PRId64, chan->id);
+ }
+}
+
/// ":mode":
/// If no argument given, get the screen size and redraw.
static void ex_mode(exarg_T *eap)