diff options
Diffstat (limited to 'src/nvim/ui.c')
-rw-r--r-- | src/nvim/ui.c | 124 |
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); |