aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ui.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/ui.c')
-rw-r--r--src/nvim/ui.c124
1 files changed, 79 insertions, 45 deletions
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index 36f34bc75a..bddcf98b53 100644
--- a/src/nvim/ui.c
+++ b/src/nvim/ui.c
@@ -1,10 +1,10 @@
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
-#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <uv.h>
#include "klib/kvec.h"
#include "nvim/api/private/helpers.h"
@@ -13,10 +13,12 @@
#include "nvim/ascii_defs.h"
#include "nvim/autocmd.h"
#include "nvim/buffer.h"
+#include "nvim/buffer_defs.h"
#include "nvim/cursor_shape.h"
#include "nvim/drawscreen.h"
+#include "nvim/event/multiqueue.h"
#include "nvim/ex_getln.h"
-#include "nvim/gettext.h"
+#include "nvim/gettext_defs.h"
#include "nvim/globals.h"
#include "nvim/grid.h"
#include "nvim/highlight.h"
@@ -25,9 +27,12 @@
#include "nvim/lua/executor.h"
#include "nvim/map_defs.h"
#include "nvim/memory.h"
+#include "nvim/memory_defs.h"
#include "nvim/message.h"
#include "nvim/option.h"
+#include "nvim/option_defs.h"
#include "nvim/option_vars.h"
+#include "nvim/os/os_defs.h"
#include "nvim/os/time.h"
#include "nvim/state_defs.h"
#include "nvim/strings.h"
@@ -37,13 +42,18 @@
#include "nvim/window.h"
#include "nvim/winfloat.h"
+typedef struct {
+ LuaRef cb;
+ bool ext_widgets[kUIGlobalCount];
+} UIEventCallback;
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ui.c.generated.h"
#endif
#define MAX_UI_COUNT 16
-static UI *uis[MAX_UI_COUNT];
+static RemoteUI *uis[MAX_UI_COUNT];
static bool ui_ext[kUIExtCount] = { 0 };
static size_t ui_count = 0;
static int ui_mode_idx = SHAPE_IDX_N;
@@ -59,6 +69,7 @@ bool ui_cb_ext[kUIExtCount]; ///< Internalized UI capabilities.
static bool has_mouse = false;
static int pending_has_mouse = -1;
+static bool pending_default_colors = false;
static Array call_buf = ARRAY_DICT_INIT;
@@ -97,7 +108,7 @@ static void ui_log(const char *funname)
do { \
bool any_call = false; \
for (size_t i = 0; i < ui_count; i++) { \
- UI *ui = uis[i]; \
+ RemoteUI *ui = uis[i]; \
if ((cond)) { \
remote_ui_##funname(__VA_ARGS__); \
any_call = true; \
@@ -130,6 +141,8 @@ void ui_free_all_mem(void)
free_ui_event_callback(event_cb);
})
map_destroy(uint32_t, &ui_event_cbs);
+
+ multiqueue_free(resize_events);
}
#endif
@@ -190,7 +203,8 @@ void ui_refresh(void)
return;
}
- int width = INT_MAX, height = INT_MAX;
+ int width = INT_MAX;
+ int height = INT_MAX;
bool ext_widgets[kUIExtCount];
for (UIExtension i = 0; (int)i < kUIExtCount; i++) {
ext_widgets[i] = true;
@@ -198,7 +212,7 @@ void ui_refresh(void)
bool inclusive = ui_override();
for (size_t i = 0; i < ui_count; i++) {
- UI *ui = uis[i];
+ RemoteUI *ui = uis[i];
width = MIN(ui->width, width);
height = MIN(ui->height, height);
for (UIExtension j = 0; (int)j < kUIExtCount; j++) {
@@ -215,7 +229,7 @@ void ui_refresh(void)
}
ui_ext[i] = ext_widgets[i];
if (i < kUIGlobalCount) {
- ui_call_option_set(cstr_as_string((char *)ui_ext_names[i]),
+ ui_call_option_set(cstr_as_string(ui_ext_names[i]),
BOOLEAN_OBJ(ext_widgets[i]));
}
}
@@ -228,7 +242,7 @@ void ui_refresh(void)
p_lz = save_p_lz;
if (ext_widgets[kUIMessages]) {
- set_option_value("cmdheight", NUMBER_OPTVAL(0), 0);
+ set_option_value(kOptCmdheight, NUMBER_OPTVAL(0), 0);
command_height();
}
ui_mode_info_set();
@@ -272,13 +286,26 @@ static void ui_refresh_event(void **argv)
void ui_schedule_refresh(void)
{
- multiqueue_put(resize_events, ui_refresh_event, 0);
+ multiqueue_put(resize_events, ui_refresh_event, NULL);
}
void ui_default_colors_set(void)
{
- ui_call_default_colors_set(normal_fg, normal_bg, normal_sp,
- cterm_normal_fg_color, cterm_normal_bg_color);
+ // Throttle setting of default colors at startup, so it only happens once
+ // if the user sets the colorscheme in startup.
+ pending_default_colors = true;
+ if (starting == 0) {
+ ui_may_set_default_colors();
+ }
+}
+
+static void ui_may_set_default_colors(void)
+{
+ if (pending_default_colors) {
+ pending_default_colors = false;
+ ui_call_default_colors_set(normal_fg, normal_bg, normal_sp,
+ cterm_normal_fg_color, cterm_normal_bg_color);
+ }
}
void ui_busy_start(void)
@@ -340,12 +367,11 @@ void vim_beep(unsigned val)
void do_autocmd_uienter_all(void)
{
for (size_t i = 0; i < ui_count; i++) {
- UIData *data = uis[i]->data;
- do_autocmd_uienter(data->channel_id, true);
+ do_autocmd_uienter(uis[i]->channel_id, true);
}
}
-void ui_attach_impl(UI *ui, uint64_t chanid)
+void ui_attach_impl(RemoteUI *ui, uint64_t chanid)
{
if (ui_count == MAX_UI_COUNT) {
abort();
@@ -359,6 +385,12 @@ void ui_attach_impl(UI *ui, uint64_t chanid)
ui_refresh_options();
resettitle();
+ char cwd[MAXPATHL];
+ size_t cwdlen = sizeof(cwd);
+ if (uv_cwd(cwd, &cwdlen) == 0) {
+ ui_call_chdir((String){ .data = cwd, .size = cwdlen });
+ }
+
for (UIExtension i = kUIGlobalCount; (int)i < kUIExtCount; i++) {
ui_set_ext_option(ui, i, ui->ui_ext[i]);
}
@@ -375,7 +407,7 @@ void ui_attach_impl(UI *ui, uint64_t chanid)
do_autocmd_uienter(chanid, true);
}
-void ui_detach_impl(UI *ui, uint64_t chanid)
+void ui_detach_impl(RemoteUI *ui, uint64_t chanid)
{
size_t shift_index = MAX_UI_COUNT;
@@ -411,31 +443,32 @@ void ui_detach_impl(UI *ui, uint64_t chanid)
do_autocmd_uienter(chanid, false);
}
-void ui_set_ext_option(UI *ui, UIExtension ext, bool active)
+void ui_set_ext_option(RemoteUI *ui, UIExtension ext, bool active)
{
if (ext < kUIGlobalCount) {
ui_refresh();
return;
}
if (ui_ext_names[ext][0] != '_' || active) {
- remote_ui_option_set(ui, cstr_as_string((char *)ui_ext_names[ext]),
- BOOLEAN_OBJ(active));
+ remote_ui_option_set(ui, cstr_as_string(ui_ext_names[ext]), BOOLEAN_OBJ(active));
}
if (ext == kUITermColors) {
ui_default_colors_set();
}
}
-void ui_line(ScreenGrid *grid, int row, int startcol, int endcol, int clearcol, int clearattr,
- bool wrap)
+void ui_line(ScreenGrid *grid, int row, bool invalid_row, int startcol, int endcol, int clearcol,
+ int clearattr, bool wrap)
{
assert(0 <= row && row < grid->rows);
LineFlags flags = wrap ? kLineFlagWrap : 0;
- if (startcol == -1) {
- startcol = 0;
+ if (startcol == 0 && invalid_row) {
flags |= kLineFlagInvalid;
}
+ // set default colors now so that that text won't have to be repainted later
+ ui_may_set_default_colors();
+
size_t off = grid->line_offset[row] + (size_t)startcol;
ui_call_raw_line(grid->handle, row, startcol, endcol, clearcol, clearattr,
@@ -611,34 +644,35 @@ bool ui_has(UIExtension ext)
return ui_ext[ext];
}
-Array ui_array(void)
+Array ui_array(Arena *arena)
{
- Array all_uis = ARRAY_DICT_INIT;
+ Array all_uis = arena_array(arena, ui_count);
for (size_t i = 0; i < ui_count; i++) {
- UI *ui = uis[i];
- Dictionary info = ARRAY_DICT_INIT;
- PUT(info, "width", INTEGER_OBJ(ui->width));
- PUT(info, "height", INTEGER_OBJ(ui->height));
- PUT(info, "rgb", BOOLEAN_OBJ(ui->rgb));
- PUT(info, "override", BOOLEAN_OBJ(ui->override));
+ RemoteUI *ui = uis[i];
+ Dictionary info = arena_dict(arena, 10 + kUIExtCount);
+ PUT_C(info, "width", INTEGER_OBJ(ui->width));
+ PUT_C(info, "height", INTEGER_OBJ(ui->height));
+ PUT_C(info, "rgb", BOOLEAN_OBJ(ui->rgb));
+ PUT_C(info, "override", BOOLEAN_OBJ(ui->override));
// TUI fields. (`stdin_fd` is intentionally omitted.)
- PUT(info, "term_name", CSTR_TO_OBJ(ui->term_name));
+ PUT_C(info, "term_name", CSTR_AS_OBJ(ui->term_name));
// term_background is deprecated. Populate with an empty string
- PUT(info, "term_background", CSTR_TO_OBJ(""));
+ PUT_C(info, "term_background", STATIC_CSTR_AS_OBJ(""));
- PUT(info, "term_colors", INTEGER_OBJ(ui->term_colors));
- PUT(info, "stdin_tty", BOOLEAN_OBJ(ui->stdin_tty));
- PUT(info, "stdout_tty", BOOLEAN_OBJ(ui->stdout_tty));
+ PUT_C(info, "term_colors", INTEGER_OBJ(ui->term_colors));
+ PUT_C(info, "stdin_tty", BOOLEAN_OBJ(ui->stdin_tty));
+ PUT_C(info, "stdout_tty", BOOLEAN_OBJ(ui->stdout_tty));
for (UIExtension j = 0; j < kUIExtCount; j++) {
if (ui_ext_names[j][0] != '_' || ui->ui_ext[j]) {
- PUT(info, ui_ext_names[j], BOOLEAN_OBJ(ui->ui_ext[j]));
+ PUT_C(info, (char *)ui_ext_names[j], BOOLEAN_OBJ(ui->ui_ext[j]));
}
}
- remote_ui_inspect(ui, &info);
- ADD(all_uis, DICTIONARY_OBJ(info));
+ PUT_C(info, "chan", INTEGER_OBJ((Integer)ui->channel_id));
+
+ ADD_C(all_uis, DICTIONARY_OBJ(info));
}
return all_uis;
}
@@ -657,9 +691,9 @@ void ui_grid_resize(handle_T grid_handle, int width, int height, Error *err)
if (wp->w_floating) {
if (width != wp->w_width || height != wp->w_height) {
- wp->w_float_config.width = width;
- wp->w_float_config.height = height;
- win_config_float(wp, wp->w_float_config);
+ wp->w_config.width = width;
+ wp->w_config.height = height;
+ win_config_float(wp, wp->w_config);
}
} else {
// non-positive indicates no request
@@ -675,8 +709,8 @@ void ui_call_event(char *name, Array args)
bool handled = false;
map_foreach_value(&ui_event_cbs, event_cb, {
Error err = ERROR_INIT;
- Object res = nlua_call_ref(event_cb->cb, name, args, false, &err);
- if (res.type == kObjectTypeBoolean && res.data.boolean == true) {
+ Object res = nlua_call_ref(event_cb->cb, name, args, kRetNilBool, NULL, &err);
+ if (LUARET_TRUTHY(res)) {
handled = true;
}
if (ERROR_SET(&err)) {
@@ -692,7 +726,7 @@ void ui_call_event(char *name, Array args)
ui_log(name);
}
-void ui_cb_update_ext(void)
+static void ui_cb_update_ext(void)
{
memset(ui_cb_ext, 0, ARRAY_SIZE(ui_cb_ext));
@@ -708,7 +742,7 @@ void ui_cb_update_ext(void)
}
}
-void free_ui_event_callback(UIEventCallback *event_cb)
+static void free_ui_event_callback(UIEventCallback *event_cb)
{
api_free_luaref(event_cb->cb);
xfree(event_cb);