diff options
Diffstat (limited to 'src/nvim/ui.c')
-rw-r--r-- | src/nvim/ui.c | 188 |
1 files changed, 87 insertions, 101 deletions
diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 3b8b3ac9a7..42366fdb76 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -49,13 +49,13 @@ #define MAX_UI_COUNT 16 static UI *uis[MAX_UI_COUNT]; -static bool ui_ext[UI_WIDGETS] = { 0 }; +static bool ui_ext[kUIExtCount] = { 0 }; static size_t ui_count = 0; static int row = 0, col = 0; static struct { int top, bot, left, right; } sr; -static int current_attr_code = 0; +static int current_attr_code = -1; static bool pending_cursor_update = false; static int busy = 0; static int height, width; @@ -107,8 +107,9 @@ static char uilog_last_event[1024] = { 0 }; } \ } while (0) #endif -#define CNT(...) SELECT_NTH(__VA_ARGS__, MORE, MORE, MORE, MORE, ZERO, ignore) -#define SELECT_NTH(a1, a2, a3, a4, a5, a6, ...) a6 +#define CNT(...) SELECT_NTH(__VA_ARGS__, MORE, MORE, MORE, \ + MORE, MORE, ZERO, ignore) +#define SELECT_NTH(a1, a2, a3, a4, a5, a6, a7, ...) a7 #define UI_CALL_HELPER(c, ...) UI_CALL_HELPER2(c, __VA_ARGS__) // Resolves to UI_CALL_MORE or UI_CALL_ZERO. #define UI_CALL_HELPER2(c, ...) UI_CALL_##c(__VA_ARGS__) @@ -145,6 +146,9 @@ void ui_builtin_stop(void) bool ui_rgb_attached(void) { + if (!headless_mode && p_tgc) { + return true; + } for (size_t i = 0; i < ui_count; i++) { if (uis[i]->rgb) { return true; @@ -168,84 +172,61 @@ void ui_event(char *name, Array args) } -/// Converts an attrentry_T into an HlAttrs +/// Converts an HlAttrs into Dictionary /// /// @param[in] aep data to convert /// @param use_rgb use 'gui*' settings if true, else resorts to 'cterm*' -HlAttrs attrentry2hlattrs(const attrentry_T *aep, bool use_rgb) +Dictionary hlattrs2dict(const HlAttrs *aep, bool use_rgb) { assert(aep); - - HlAttrs attrs = HLATTRS_INIT; - int mask = 0; - - mask = use_rgb ? aep->rgb_ae_attr : aep->cterm_ae_attr; - - attrs.bold = mask & HL_BOLD; - attrs.underline = mask & HL_UNDERLINE; - attrs.undercurl = mask & HL_UNDERCURL; - attrs.italic = mask & HL_ITALIC; - attrs.reverse = mask & (HL_INVERSE | HL_STANDOUT); - - if (use_rgb) { - if (aep->rgb_fg_color != -1) { - attrs.foreground = aep->rgb_fg_color; - } - - if (aep->rgb_bg_color != -1) { - attrs.background = aep->rgb_bg_color; - } - - if (aep->rgb_sp_color != -1) { - attrs.special = aep->rgb_sp_color; - } - } else { - if (cterm_normal_fg_color != aep->cterm_fg_color) { - attrs.foreground = aep->cterm_fg_color - 1; - } - - if (cterm_normal_bg_color != aep->cterm_bg_color) { - attrs.background = aep->cterm_bg_color - 1; - } - } - - return attrs; -} - -Dictionary hlattrs2dict(HlAttrs attrs) -{ Dictionary hl = ARRAY_DICT_INIT; + int mask = use_rgb ? aep->rgb_ae_attr : aep->cterm_ae_attr; - if (attrs.bold) { + if (mask & HL_BOLD) { PUT(hl, "bold", BOOLEAN_OBJ(true)); } - if (attrs.underline) { + if (mask & HL_STANDOUT) { + PUT(hl, "standout", BOOLEAN_OBJ(true)); + } + + if (mask & HL_UNDERLINE) { PUT(hl, "underline", BOOLEAN_OBJ(true)); } - if (attrs.undercurl) { + if (mask & HL_UNDERCURL) { PUT(hl, "undercurl", BOOLEAN_OBJ(true)); } - if (attrs.italic) { + if (mask & HL_ITALIC) { PUT(hl, "italic", BOOLEAN_OBJ(true)); } - if (attrs.reverse) { + if (mask & HL_INVERSE) { PUT(hl, "reverse", BOOLEAN_OBJ(true)); } - if (attrs.foreground != -1) { - PUT(hl, "foreground", INTEGER_OBJ(attrs.foreground)); - } - if (attrs.background != -1) { - PUT(hl, "background", INTEGER_OBJ(attrs.background)); - } + if (use_rgb) { + if (aep->rgb_fg_color != -1) { + PUT(hl, "foreground", INTEGER_OBJ(aep->rgb_fg_color)); + } + + if (aep->rgb_bg_color != -1) { + PUT(hl, "background", INTEGER_OBJ(aep->rgb_bg_color)); + } - if (attrs.special != -1) { - PUT(hl, "special", INTEGER_OBJ(attrs.special)); + if (aep->rgb_sp_color != -1) { + PUT(hl, "special", INTEGER_OBJ(aep->rgb_sp_color)); + } + } else { + if (cterm_normal_fg_color != aep->cterm_fg_color) { + PUT(hl, "foreground", INTEGER_OBJ(aep->cterm_fg_color - 1)); + } + + if (cterm_normal_bg_color != aep->cterm_bg_color) { + PUT(hl, "background", INTEGER_OBJ(aep->cterm_bg_color - 1)); + } } return hl; @@ -263,8 +244,8 @@ void ui_refresh(void) } int width = INT_MAX, height = INT_MAX; - bool ext_widgets[UI_WIDGETS]; - for (UIWidget i = 0; (int)i < UI_WIDGETS; i++) { + bool ext_widgets[kUIExtCount]; + for (UIExtension i = 0; (int)i < kUIExtCount; i++) { ext_widgets[i] = true; } @@ -272,7 +253,7 @@ void ui_refresh(void) UI *ui = uis[i]; width = MIN(ui->width, width); height = MIN(ui->height, height); - for (UIWidget i = 0; (int)i < UI_WIDGETS; i++) { + for (UIExtension i = 0; (int)i < kUIExtCount; i++) { ext_widgets[i] &= ui->ui_ext[i]; } } @@ -284,12 +265,15 @@ void ui_refresh(void) screen_resize(width, height); p_lz = save_p_lz; - for (UIWidget i = 0; (int)i < UI_WIDGETS; i++) { - ui_set_external(i, ext_widgets[i]); + for (UIExtension i = 0; (int)i < kUIExtCount; i++) { + ui_ext[i] = ext_widgets[i]; + ui_call_option_set(cstr_as_string((char *)ui_ext_names[i]), + BOOLEAN_OBJ(ext_widgets[i])); } ui_mode_info_set(); old_mode_idx = -1; ui_cursor_shape(); + current_attr_code = -1; } static void ui_refresh_event(void **argv) @@ -307,6 +291,11 @@ void ui_resize(int new_width, int new_height) width = new_width; height = new_height; + // TODO(bfredl): update default colors when they changed, NOT on resize. + ui_call_default_colors_set(normal_fg, normal_bg, normal_sp, + cterm_normal_fg_color, cterm_normal_bg_color); + + // Deprecated: UI_CALL(update_fg, (ui->rgb ? normal_fg : cterm_normal_fg_color - 1)); UI_CALL(update_bg, (ui->rgb ? normal_bg : cterm_normal_bg_color - 1)); UI_CALL(update_sp, (ui->rgb ? normal_sp : -1)); @@ -339,6 +328,7 @@ void ui_attach_impl(UI *ui) } uis[ui_count++] = ui; + ui_refresh_options(); ui_refresh(); } @@ -399,26 +389,28 @@ void ui_reset_scroll_region(void) ui_call_set_scroll_region(sr.top, sr.bot, sr.left, sr.right); } -void ui_start_highlight(int attr_code) +void ui_set_highlight(int attr_code) { + if (current_attr_code == attr_code) { + return; + } current_attr_code = attr_code; - if (!ui_count) { - return; + HlAttrs attrs = HLATTRS_INIT; + + if (attr_code != 0) { + HlAttrs *aep = syn_cterm_attr2entry(attr_code); + if (aep) { + attrs = *aep; + } } - set_highlight_args(current_attr_code); + UI_CALL(highlight_set, attrs); } -void ui_stop_highlight(void) +void ui_clear_highlight(void) { - current_attr_code = HL_NORMAL; - - if (!ui_count) { - return; - } - - set_highlight_args(current_attr_code); + ui_set_highlight(0); } void ui_puts(uint8_t *str) @@ -446,6 +438,12 @@ void ui_puts(uint8_t *str) ui_linefeed(); } p += clen; + + if (p_wd) { // 'writedelay': flush & delay each time. + ui_flush(); + uint64_t wd = (uint64_t)labs(p_wd); + os_delay(wd, false); + } } } @@ -489,26 +487,6 @@ void ui_flush(void) ui_call_flush(); } -static void set_highlight_args(int attr_code) -{ - HlAttrs rgb_attrs = HLATTRS_INIT; - HlAttrs cterm_attrs = rgb_attrs; - - if (attr_code == HL_NORMAL) { - goto end; - } - attrentry_T *aep = syn_cterm_attr2entry(attr_code); - - if (!aep) { - goto end; - } - - rgb_attrs = attrentry2hlattrs(aep, true); - cterm_attrs = attrentry2hlattrs(aep, false); - -end: - UI_CALL(highlight_set, (ui->rgb ? rgb_attrs : cterm_attrs)); -} void ui_linefeed(void) { @@ -548,15 +526,23 @@ void ui_cursor_shape(void) } /// Returns true if `widget` is externalized. -bool ui_is_external(UIWidget widget) +bool ui_is_external(UIExtension widget) { return ui_ext[widget]; } -/// Sets `widget` as "external". -/// Such widgets are not drawn by Nvim; external UIs are expected to handle -/// higher-level UI events and present the data. -void ui_set_external(UIWidget widget, bool external) +Array ui_array(void) { - ui_ext[widget] = external; + Array all_uis = ARRAY_DICT_INIT; + for (size_t i = 0; i < ui_count; i++) { + Dictionary dic = ARRAY_DICT_INIT; + PUT(dic, "width", INTEGER_OBJ(uis[i]->width)); + PUT(dic, "height", INTEGER_OBJ(uis[i]->height)); + PUT(dic, "rgb", BOOLEAN_OBJ(uis[i]->rgb)); + for (UIExtension j = 0; j < kUIExtCount; j++) { + PUT(dic, ui_ext_names[j], BOOLEAN_OBJ(uis[i]->ui_ext[j])); + } + ADD(all_uis, DICTIONARY_OBJ(dic)); + } + return all_uis; } |