aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2024-09-18 04:14:06 -0700
committerGitHub <noreply@github.com>2024-09-18 04:14:06 -0700
commitff85e54939b0aca34a779a2b6381d09db1858b29 (patch)
treeeea30db8b69582af6c206b1a8ac0b4918fc61e20 /src
parent22553e1f38addd867ad659b2944d00129141a499 (diff)
downloadrneovim-ff85e54939b0aca34a779a2b6381d09db1858b29.tar.gz
rneovim-ff85e54939b0aca34a779a2b6381d09db1858b29.tar.bz2
rneovim-ff85e54939b0aca34a779a2b6381d09db1858b29.zip
feat(tui): builtin UI (TUI) sets client info #30397
Problem: The default builtin UI client does not declare its client info. This reduces discoverability and makes it difficult for plugins to identify the UI. Solution: - Call nvim_set_client_info after attaching, as recommended by `:help dev-ui`. - Also set the "pid" field. - Also change `ui_active()` to return a count. Not directly relevant to this commit, but will be useful later.
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/vim.c17
-rw-r--r--src/nvim/main.c3
-rw-r--r--src/nvim/tui/input.c2
-rw-r--r--src/nvim/ui.c7
-rw-r--r--src/nvim/ui_client.c43
5 files changed, 55 insertions, 17 deletions
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index fe263d051d..d10ee91042 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -1586,6 +1586,7 @@ Array nvim_get_api_info(uint64_t channel_id, Arena *arena)
///
/// @param attributes Arbitrary string:string map of informal client properties.
/// Suggested keys:
+/// - "pid": Process id.
/// - "website": Client homepage URL (e.g. GitHub repository)
/// - "license": License description ("Apache 2", "GPLv3", "MIT", …)
/// - "logo": URI or path to image, preferably small logo or icon.
@@ -1627,7 +1628,7 @@ void nvim_set_client_info(uint64_t channel_id, String name, Dictionary version,
/// Gets information about a channel.
///
/// @param chan channel_id, or 0 for current channel
-/// @returns Dictionary describing a channel, with these keys:
+/// @returns Channel info dict with these keys:
/// - "id" Channel id.
/// - "argv" (optional) Job arguments list.
/// - "stream" Stream underlying the channel.
@@ -1639,14 +1640,12 @@ void nvim_set_client_info(uint64_t channel_id, String name, Dictionary version,
/// - "bytes" Send and receive raw bytes.
/// - "terminal" |terminal| instance interprets ASCII sequences.
/// - "rpc" |RPC| communication on the channel is active.
-/// - "pty" (optional) Name of pseudoterminal. On a POSIX system this
-/// is a device path like "/dev/pts/1". If the name is unknown,
-/// the key will still be present if a pty is used (e.g. for
-/// conpty on Windows).
-/// - "buffer" (optional) Buffer with connected |terminal| instance.
-/// - "client" (optional) Info about the peer (client on the other end of
-/// the RPC channel), if provided by it via
-/// |nvim_set_client_info()|.
+/// - "pty" (optional) Name of pseudoterminal. On a POSIX system this is a device path like
+/// "/dev/pts/1". If unknown, the key will still be present if a pty is used (e.g.
+/// for conpty on Windows).
+/// - "buffer" (optional) Buffer connected to |terminal| instance.
+/// - "client" (optional) Info about the peer (client on the other end of the RPC channel),
+/// which it provided via |nvim_set_client_info()|.
///
Dictionary nvim_get_chan_info(uint64_t channel_id, Integer chan, Arena *arena, Error *err)
FUNC_API_SINCE(4)
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 0b49ea13d7..e060d0dcaf 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -351,7 +351,6 @@ int main(int argc, char **argv)
// NORETURN: Start builtin UI client.
if (ui_client_channel_id) {
- time_finish();
ui_client_run(remote_ui); // NORETURN
}
assert(!ui_client_channel_id && !use_builtin_ui);
@@ -1514,7 +1513,7 @@ static void init_startuptime(mparm_T *paramp)
}
for (int i = 1; i < paramp->argc - 1; i++) {
if (STRICMP(paramp->argv[i], "--startuptime") == 0) {
- time_init(paramp->argv[i + 1], is_embed ? "Embedded" : "Primary/TUI");
+ time_init(paramp->argv[i + 1], is_embed ? "Embedded" : "Primary (or UI client)");
time_start("--- NVIM STARTING ---");
break;
}
diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c
index 3eb8d4ba2e..98dd7b4b45 100644
--- a/src/nvim/tui/input.c
+++ b/src/nvim/tui/input.c
@@ -464,7 +464,7 @@ static void tinput_timer_cb(uv_timer_t *handle)
{
TermInput *input = handle->data;
// If the raw buffer is not empty, process the raw buffer first because it is
- // processing an incomplete bracketed paster sequence.
+ // processing an incomplete bracketed paste sequence.
size_t size = rstream_available(&input->read_stream);
if (size) {
size_t consumed = handle_raw_buffer(input, true, input->read_stream.read_pos, size);
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index 314d322a68..587124fab0 100644
--- a/src/nvim/ui.c
+++ b/src/nvim/ui.c
@@ -182,9 +182,10 @@ bool ui_override(void)
return false;
}
-bool ui_active(void)
+/// Gets the number of UIs connected to this server.
+size_t ui_active(void)
{
- return ui_count > 0;
+ return ui_count;
}
void ui_refresh(void)
@@ -197,7 +198,7 @@ void ui_refresh(void)
int height = INT_MAX;
bool ext_widgets[kUIExtCount];
bool inclusive = ui_override();
- memset(ext_widgets, ui_active(), ARRAY_SIZE(ext_widgets));
+ memset(ext_widgets, !!ui_active(), ARRAY_SIZE(ext_widgets));
for (size_t i = 0; i < ui_count; i++) {
RemoteUI *ui = uis[i];
diff --git a/src/nvim/ui_client.c b/src/nvim/ui_client.c
index cfa79b9d8c..43ab238716 100644
--- a/src/nvim/ui_client.c
+++ b/src/nvim/ui_client.c
@@ -24,6 +24,7 @@
#include "nvim/msgpack_rpc/channel_defs.h"
#include "nvim/os/os.h"
#include "nvim/os/os_defs.h"
+#include "nvim/profile.h"
#include "nvim/tui/tui.h"
#include "nvim/tui/tui_defs.h"
#include "nvim/ui.h"
@@ -81,12 +82,15 @@ uint64_t ui_client_start_server(int argc, char **argv)
return channel->id;
}
+/// Attaches this client to the UI channel, and sets its client info.
void ui_client_attach(int width, int height, char *term, bool rgb)
{
+ //
+ // nvim_ui_attach
+ //
MAXSIZE_TEMP_ARRAY(args, 3);
ADD_C(args, INTEGER_OBJ(width));
ADD_C(args, INTEGER_OBJ(height));
-
MAXSIZE_TEMP_DICT(opts, 9);
PUT_C(opts, "rgb", BOOLEAN_OBJ(rgb));
PUT_C(opts, "ext_linegrid", BOOLEAN_OBJ(true));
@@ -94,7 +98,6 @@ void ui_client_attach(int width, int height, char *term, bool rgb)
if (term) {
PUT_C(opts, "term_name", CSTR_AS_OBJ(term));
}
-
PUT_C(opts, "term_colors", INTEGER_OBJ(t_colors));
if (!ui_client_is_remote) {
PUT_C(opts, "stdin_tty", BOOLEAN_OBJ(stdin_isatty));
@@ -108,6 +111,40 @@ void ui_client_attach(int width, int height, char *term, bool rgb)
rpc_send_event(ui_client_channel_id, "nvim_ui_attach", args);
ui_client_attached = true;
+
+ TIME_MSG("nvim_ui_attach");
+
+ //
+ // nvim_set_client_info
+ //
+ MAXSIZE_TEMP_ARRAY(args2, 5);
+ ADD_C(args2, CSTR_AS_OBJ("nvim-tui")); // name
+ Object m = api_metadata();
+ Dictionary version = { 0 };
+ assert(m.data.dictionary.size > 0);
+ for (size_t i = 0; i < m.data.dictionary.size; i++) {
+ if (strequal(m.data.dictionary.items[i].key.data, "version")) {
+ version = m.data.dictionary.items[i].value.data.dictionary;
+ break;
+ } else if (i + 1 == m.data.dictionary.size) {
+ abort();
+ }
+ }
+ ADD_C(args2, DICTIONARY_OBJ(version)); // version
+ ADD_C(args2, CSTR_AS_OBJ("ui")); // type
+ // We don't send api_metadata.functions as the "methods" because:
+ // 1. it consumes memory.
+ // 2. it is unlikely to be useful, since the peer can just call `nvim_get_api`.
+ // 3. nvim_set_client_info expects a dict instead of an array.
+ ADD_C(args2, ARRAY_OBJ((Array)ARRAY_DICT_INIT)); // methods
+ MAXSIZE_TEMP_DICT(info, 9); // attributes
+ PUT_C(info, "website", CSTR_AS_OBJ("https://neovim.io"));
+ PUT_C(info, "license", CSTR_AS_OBJ("Apache 2"));
+ PUT_C(info, "pid", INTEGER_OBJ(os_get_pid()));
+ ADD_C(args2, DICTIONARY_OBJ(info)); // attributes
+ rpc_send_event(ui_client_channel_id, "nvim_set_client_info", args2);
+
+ TIME_MSG("nvim_set_client_info");
}
void ui_client_detach(void)
@@ -132,6 +169,8 @@ void ui_client_run(bool remote_ui)
ELOG("test log message");
}
+ time_finish();
+
// os_exit() will be invoked when the client channel detaches
while (true) {
LOOP_PROCESS_EVENTS(&main_loop, resize_events, -1);