aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/ui.c15
-rw-r--r--src/nvim/channel.c2
-rw-r--r--src/nvim/main.c21
-rw-r--r--src/nvim/msgpack_rpc/channel.c27
-rw-r--r--src/nvim/tui/tui.c27
5 files changed, 49 insertions, 43 deletions
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c
index 509032892b..4971753854 100644
--- a/src/nvim/api/ui.c
+++ b/src/nvim/api/ui.c
@@ -58,6 +58,21 @@ void remote_ui_disconnect(uint64_t channel_id)
xfree(ui);
}
+/// Wait until ui has connected on stdio channel.
+void remote_ui_wait_for_attach(void)
+ FUNC_API_NOEXPORT
+{
+ Channel *channel = find_channel(CHAN_STDIO);
+ if (!channel) {
+ // this function should only be called in --embed mode, stdio channel
+ // can be assumed.
+ abort();
+ }
+
+ LOOP_PROCESS_EVENTS_UNTIL(&main_loop, channel->events, -1,
+ pmap_has(uint64_t)(connected_uis, CHAN_STDIO));
+}
+
void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height,
Dictionary options, Error *err)
FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
diff --git a/src/nvim/channel.c b/src/nvim/channel.c
index 36423d0aa1..259f1cc600 100644
--- a/src/nvim/channel.c
+++ b/src/nvim/channel.c
@@ -432,7 +432,7 @@ uint64_t channel_from_stdio(bool rpc, CallbackReader on_output,
const char **error)
FUNC_ATTR_NONNULL_ALL
{
- if (!headless_mode) {
+ if (!headless_mode && !embedded_mode) {
*error = _("can only be opened in headless mode");
return 0;
}
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 192e7d2907..4b838a837c 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -65,6 +65,7 @@
#include "nvim/msgpack_rpc/helpers.h"
#include "nvim/msgpack_rpc/server.h"
#include "nvim/msgpack_rpc/channel.h"
+#include "nvim/api/ui.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
#include "nvim/api/private/handle.h"
@@ -304,6 +305,7 @@ int main(int argc, char **argv)
// Read ex-commands if invoked with "-es".
//
bool reading_tty = !headless_mode
+ && !embedded_mode
&& !silent_mode
&& (params.input_isatty || params.output_isatty
|| params.err_isatty);
@@ -348,18 +350,16 @@ int main(int argc, char **argv)
// startup. This allows an external UI to show messages and prompts from
// --cmd and buffer loading (e.g. swap files)
bool early_ui = false;
- if (embedded_mode) {
+ if (embedded_mode && !headless_mode) {
TIME_MSG("waiting for embedder to make request");
- rpc_wait_for_request();
+ remote_ui_wait_for_attach();
TIME_MSG("done waiting for embedder");
- if (ui_active()) {
- // prepare screen now, so external UIs can display messages
- starting = NO_BUFFERS;
- screenclear();
- early_ui = true;
- TIME_MSG("initialized screen early for embedder");
- }
+ // prepare screen now, so external UIs can display messages
+ starting = NO_BUFFERS;
+ screenclear();
+ early_ui = true;
+ TIME_MSG("initialized screen early for embedder");
}
// Execute --cmd arguments.
@@ -467,7 +467,7 @@ int main(int argc, char **argv)
wait_return(true);
}
- if (!headless_mode && !silent_mode) {
+ if (!headless_mode && !embedded_mode && !silent_mode) {
input_stop(); // Stop reading input, let the UI take over.
ui_builtin_start();
}
@@ -848,7 +848,6 @@ static void command_line_scan(mparm_T *parmp)
headless_mode = true;
} else if (STRICMP(argv[0] + argv_idx, "embed") == 0) {
embedded_mode = true;
- headless_mode = true;
const char *err;
if (!channel_from_stdio(true, CALLBACK_READER_INIT, &err)) {
abort();
diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c
index c6cfb1a9ce..3356cdc61e 100644
--- a/src/nvim/msgpack_rpc/channel.c
+++ b/src/nvim/msgpack_rpc/channel.c
@@ -40,8 +40,6 @@
static PMap(cstr_t) *event_strings = NULL;
static msgpack_sbuffer out_buffer;
-static bool got_stdio_request = false;
-
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "msgpack_rpc/channel.c.generated.h"
#endif
@@ -331,9 +329,6 @@ static void handle_request(Channel *channel, msgpack_object *request)
send_error(channel, request_id, error.msg);
api_clear_error(&error);
api_free_array(args);
- if (channel->id == CHAN_STDIO) {
- got_stdio_request = true;
- }
return;
}
@@ -349,9 +344,6 @@ static void handle_request(Channel *channel, msgpack_object *request)
if (is_get_mode && !input_blocking()) {
// Defer the event to a special queue used by os/input.c. #6247
multiqueue_put(ch_before_blocking_events, on_request_event, 1, evdata);
- if (channel->id == CHAN_STDIO) {
- got_stdio_request = true;
- }
} else {
// Invoke immediately.
on_request_event((void **)&evdata);
@@ -387,11 +379,6 @@ static void on_request_event(void **argv)
channel_decref(channel);
xfree(e);
api_clear_error(&error);
- bool is_api_info = handler.fn == handle_nvim_get_api_info;
- // api info is used to initiate client library, ignore it
- if (channel->id == CHAN_STDIO && !is_api_info) {
- got_stdio_request = true;
- }
}
static bool channel_write(Channel *channel, WBuffer *buffer)
@@ -757,17 +744,3 @@ static void log_msg_close(FILE *f, msgpack_object msg)
log_unlock();
}
#endif
-
-/// Wait until embedder has done a request
-void rpc_wait_for_request(void)
-{
- Channel *channel = find_rpc_channel(CHAN_STDIO);
- if (!channel) {
- // this function should only be called in --embed mode, stdio channel
- // can be assumed.
- abort();
- }
-
- LOOP_PROCESS_EVENTS_UNTIL(&main_loop, channel->events, -1, got_stdio_request);
-}
-
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 8e7b072b1a..713fe6a2e5 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -100,6 +100,7 @@ typedef struct {
bool mouse_enabled;
bool busy, is_invisible;
bool cork, overflow;
+ bool cursor_color_changed;
cursorentry_T cursor_shapes[SHAPE_IDX_COUNT];
HlAttrs clear_attrs;
kvec_t(HlAttrs) attrs;
@@ -112,6 +113,7 @@ typedef struct {
int enable_lr_margin, disable_lr_margin;
int set_rgb_foreground, set_rgb_background;
int set_cursor_color;
+ int reset_cursor_color;
int enable_focus_reporting, disable_focus_reporting;
int resize_screen;
int reset_scroll_region;
@@ -186,10 +188,12 @@ static void terminfo_start(UI *ui)
data->busy = false;
data->cork = false;
data->overflow = false;
+ data->cursor_color_changed = false;
data->showing_mode = SHAPE_IDX_N;
data->unibi_ext.enable_mouse = -1;
data->unibi_ext.disable_mouse = -1;
data->unibi_ext.set_cursor_color = -1;
+ data->unibi_ext.reset_cursor_color = -1;
data->unibi_ext.enable_bracketed_paste = -1;
data->unibi_ext.disable_bracketed_paste = -1;
data->unibi_ext.enable_lr_margin = -1;
@@ -278,6 +282,9 @@ static void terminfo_stop(UI *ui)
unibi_out(ui, unibi_cursor_normal);
unibi_out(ui, unibi_keypad_local);
unibi_out(ui, unibi_exit_ca_mode);
+ if (data->cursor_color_changed) {
+ unibi_out_ext(ui, data->unibi_ext.reset_cursor_color);
+ }
// Disable bracketed paste
unibi_out_ext(ui, data->unibi_ext.disable_bracketed_paste);
// Disable focus reporting
@@ -965,9 +972,19 @@ static void tui_set_mode(UI *ui, ModeShape mode)
cursorentry_T c = data->cursor_shapes[mode];
if (c.id != 0 && c.id < (int)kv_size(data->attrs) && ui->rgb) {
- int color = kv_A(data->attrs, c.id).rgb_bg_color;
- UNIBI_SET_NUM_VAR(data->params[0], color);
- unibi_out_ext(ui, data->unibi_ext.set_cursor_color);
+ HlAttrs aep = kv_A(data->attrs, c.id);
+ if (aep.rgb_ae_attr & HL_INVERSE) {
+ // We interpret "inverse" as "default" (no termcode for "inverse"...).
+ // Hopefully the user's default cursor color is inverse.
+ unibi_out_ext(ui, data->unibi_ext.reset_cursor_color);
+ } else {
+ UNIBI_SET_NUM_VAR(data->params[0], aep.rgb_bg_color);
+ unibi_out_ext(ui, data->unibi_ext.set_cursor_color);
+ data->cursor_color_changed = true;
+ }
+ } else if (c.id == 0) {
+ // No cursor color for this mode; reset to default.
+ unibi_out_ext(ui, data->unibi_ext.reset_cursor_color);
}
int shape;
@@ -1774,8 +1791,10 @@ static void augment_terminfo(TUIData *data, const char *term,
// This seems to be supported for a long time in VTE
// urxvt also supports this
data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str(
- ut, NULL, "\033]12;#%p1%06x\007");
+ ut, "ext.set_cursor_color", "\033]12;#%p1%06x\007");
}
+ data->unibi_ext.reset_cursor_color = (int)unibi_add_ext_str(
+ ut, "ext.reset_cursor_color", "\x1b]112\x07");
/// Terminals usually ignore unrecognized private modes, and there is no
/// known ambiguity with these. So we just set them unconditionally.