Skip to content

Commit

Permalink
ui: refactor style handling
Browse files Browse the repository at this point in the history
The old style handling had a lot edge cases where one of the
colours or the attribute wouldn't get applied correctly. This
commit adds a new style_set() method to the Ui which should be
called instead of manually touching a cell's style. This also
means that the Cell struct can be made opaque since all the
handling is now done inside the ui-terminal files.

With this it is now viable to combine the light and dark 16 colour
themes into a single base-16 theme. This theme works very well
with the Linux virtual console and will now be the default theme
regardless of if the terminal supports 256 colours or not.  This
should address the common complaints about vis not respecting the
users default terminal colours.

fixes #1151: Theming is sometimes partially applied or ignored
see #1103: terminal no longer has transparency/opacity
see #1040: Transparent background and setting options by default
  • Loading branch information
rnpnr committed Nov 10, 2023
1 parent 1e64b1c commit 8acdb79
Show file tree
Hide file tree
Showing 13 changed files with 88 additions and 125 deletions.
15 changes: 7 additions & 8 deletions lua/themes/dark-16.lua → lua/themes/base-16.lua
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
-- Eight-color scheme
local lexers = vis.lexers
-- dark
lexers.STYLE_DEFAULT ='back:black,fore:white'
lexers.STYLE_NOTHING = 'back:black'
lexers.STYLE_DEFAULT =''
lexers.STYLE_NOTHING = ''
lexers.STYLE_CLASS = 'fore:yellow,bold'
lexers.STYLE_COMMENT = 'fore:blue,bold'
lexers.STYLE_CONSTANT = 'fore:cyan,bold'
Expand All @@ -21,17 +20,17 @@ lexers.STYLE_TYPE = 'fore:green,bold'
lexers.STYLE_VARIABLE = 'fore:blue,bold'
lexers.STYLE_WHITESPACE = ''
lexers.STYLE_EMBEDDED = 'back:blue,bold'
lexers.STYLE_IDENTIFIER = 'fore:white'
lexers.STYLE_IDENTIFIER = ''

lexers.STYLE_LINENUMBER = 'fore:white'
lexers.STYLE_LINENUMBER = ''
lexers.STYLE_LINENUMBER_CURSOR = lexers.STYLE_LINENUMBER
lexers.STYLE_CURSOR = 'reverse'
lexers.STYLE_CURSOR = 'back:white'
lexers.STYLE_CURSOR_PRIMARY = lexers.STYLE_CURSOR..',fore:yellow'
lexers.STYLE_CURSOR_LINE = 'underlined'
lexers.STYLE_COLOR_COLUMN = 'back:red'
lexers.STYLE_SELECTION = 'back:white'
lexers.STYLE_SELECTION = 'back:white,bold'
lexers.STYLE_STATUS = 'reverse'
lexers.STYLE_STATUS_FOCUSED = 'reverse,bold'
lexers.STYLE_SEPARATOR = lexers.STYLE_DEFAULT
lexers.STYLE_INFO = 'fore:default,back:default,bold'
lexers.STYLE_INFO = 'bold'
lexers.STYLE_EOF = ''
1 change: 0 additions & 1 deletion lua/themes/default-16.lua

This file was deleted.

1 change: 0 additions & 1 deletion lua/themes/default-256.lua

This file was deleted.

1 change: 1 addition & 0 deletions lua/themes/default.lua
37 changes: 0 additions & 37 deletions lua/themes/light-16.lua

This file was deleted.

4 changes: 2 additions & 2 deletions lua/vis-std.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

vis.events.subscribe(vis.events.INIT, function()
if os.getenv("TERM_PROGRAM") == "Apple_Terminal" then
vis:command("set change-256colors false");
vis:command("set change-256colors false")
end
vis:command("set theme ".. (vis.ui.colors <= 16 and "default-16" or "default-256"))
vis:command("set theme default")
end)

vis:option_register("theme", "string", function(name)
Expand Down
27 changes: 23 additions & 4 deletions ui-terminal-curses.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,13 @@

#define MAX_COLOR_CLOBBER 240

static short color_clobber_idx = 0;
static uint32_t clobbering_colors[MAX_COLOR_CLOBBER];
static int change_colors = -1;
static short default_fg = -1;
static short default_bg = -1;

static inline bool cell_color_equal(CellColor c1, CellColor c2) {
return c1 == c2;
}

/* Calculate r,g,b components of one of the standard upper 240 colors */
static void get_6cube_rgb(unsigned int n, int *r, int *g, int *b)
Expand Down Expand Up @@ -82,10 +86,13 @@ static void undo_palette(void)
/* Work out the nearest color from the 256 color set, or perhaps exactly. */
static CellColor color_rgb(UiTerm *ui, uint8_t r, uint8_t g, uint8_t b)
{
static short color_clobber_idx = 0;
static uint32_t clobbering_colors[MAX_COLOR_CLOBBER];

if (change_colors == -1)
change_colors = ui->vis->change_colors && can_change_color() && COLORS >= 256;
if (change_colors) {
uint32_t hexrep = ((r << 16) | (g << 8) | b) + 1;
uint32_t hexrep = (r << 16) | (g << 8) | b;
for (short i = 0; i < MAX_COLOR_CLOBBER; ++i) {
if (clobbering_colors[i] == hexrep)
return i + 16;
Expand Down Expand Up @@ -169,7 +176,7 @@ static inline unsigned int color_pair_hash(short fg, short bg) {

static short color_pair_get(short fg, short bg) {
static bool has_default_colors;
static short *color2palette, default_fg, default_bg;
static short *color2palette;
static short color_pairs_max, color_pair_current;

if (!color2palette) {
Expand Down Expand Up @@ -299,3 +306,15 @@ static void ui_curses_free(UiTerm *term) {
bool is_default_color(CellColor c) {
return c == CELL_COLOR_DEFAULT;
}

static bool is_default_bg(CellColor c) {
if (change_colors == 1)
return c == default_bg;
return is_default_color(c);
}

static bool is_default_fg(CellColor c) {
if (change_colors == 1)
return c == default_fg;
return is_default_color(c);
}
16 changes: 15 additions & 1 deletion ui-terminal-vt100.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ typedef struct {
Buffer buf;
} UiVt100;

static inline bool cell_color_equal(CellColor c1, CellColor c2) {
if (c1.index != (uint8_t)-1 || c2.index != (uint8_t)-1)
return c1.index == c2.index;
return c1.r == c2.r && c1.g == c2.g && c1.b == c2.b;
}

static CellColor color_rgb(UiTerm *ui, uint8_t r, uint8_t g, uint8_t b) {
return (CellColor){ .r = r, .g = g, .b = b, .index = (uint8_t)-1 };
}
Expand Down Expand Up @@ -217,6 +223,14 @@ static void ui_vt100_free(UiTerm *tui) {
buffer_release(&vtui->buf);
}

bool is_default_color(CellColor c) {
static bool is_default_color(CellColor c) {
return c.index == ((CellColor) CELL_COLOR_DEFAULT).index;
}

static bool is_default_fg(CellColor c) {
return is_default_color(c);
}

static bool is_default_bg(CellColor c) {
return is_default_color(c);
}
17 changes: 14 additions & 3 deletions ui-terminal.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,10 +282,21 @@ static void ui_window_draw(UiWin *w) {
}
}

static CellStyle ui_window_style_get(UiWin *w, enum UiStyle style) {
static void ui_window_style_set(UiWin *w, Cell *cell, enum UiStyle id) {
UiTermWin *win = (UiTermWin*)w;
UiTerm *tui = win->ui;
return tui->styles[win->id * UI_STYLE_MAX + style];
CellStyle set, style = tui->styles[win->id * UI_STYLE_MAX + id];

if (id == UI_STYLE_DEFAULT) {
memcpy(&cell->style, &style, sizeof(CellStyle));
return;
}

set.fg = is_default_fg(style.fg)? cell->style.fg : style.fg;
set.bg = is_default_bg(style.bg)? cell->style.bg : style.bg;
set.attr = cell->style.attr | style.attr;

memcpy(&cell->style, &set, sizeof(CellStyle));
}

static void ui_window_status(UiWin *w, const char *status) {
Expand Down Expand Up @@ -516,7 +527,7 @@ static UiWin *ui_window_new(Ui *ui, Win *w, enum UiOption options) {
return NULL;

win->uiwin = (UiWin) {
.style_get = ui_window_style_get,
.style_set = ui_window_style_set,
.status = ui_window_status,
.options_set = ui_window_options_set,
.options_get = ui_window_options_get,
Expand Down
14 changes: 1 addition & 13 deletions ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,23 +54,12 @@ enum UiStyle {
#if CONFIG_CURSES
typedef uint64_t CellAttr;
typedef short CellColor;

static inline bool cell_color_equal(CellColor c1, CellColor c2) {
return c1 == c2;
}
#else
typedef uint8_t CellAttr;
typedef struct {
uint8_t r, g, b;
uint8_t index;
} CellColor;

static inline bool cell_color_equal(CellColor c1, CellColor c2) {
if (c1.index != (uint8_t)-1 || c2.index != (uint8_t)-1)
return c1.index == c2.index;
return c1.r == c2.r && c1.g == c2.g && c1.b == c2.b;
}

#endif

typedef struct {
Expand Down Expand Up @@ -107,7 +96,7 @@ struct Ui {
};

struct UiWin {
CellStyle (*style_get)(UiWin*, enum UiStyle);
void (*style_set)(UiWin*, Cell*, enum UiStyle);
void (*status)(UiWin*, const char *txt);
void (*options_set)(UiWin*, enum UiOption);
enum UiOption (*options_get)(UiWin*);
Expand All @@ -116,7 +105,6 @@ struct UiWin {
int (*window_height)(UiWin*);
};

bool is_default_color(CellColor c);
enum UiLayout ui_layout_get(Ui *ui);

#endif
7 changes: 3 additions & 4 deletions view.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ static void view_clear(View *view) {
view->wrapcol = 0;
view->prevch_breakat = false;
if (view->ui)
view->cell_blank.style = view->ui->style_get(view->ui, UI_STYLE_DEFAULT);
view->ui->style_set(view->ui, &view->cell_blank, UI_STYLE_DEFAULT);
}

Filerange view_viewport_get(View *view) {
Expand Down Expand Up @@ -1405,11 +1405,10 @@ bool view_style_define(View *view, enum UiStyle id, const char *style) {
return view->ui->style_define(view->ui, id, style);
}

void view_style(View *view, enum UiStyle style_id, size_t start, size_t end) {
void view_style(View *view, enum UiStyle style, size_t start, size_t end) {
if (end < view->start || start > view->end)
return;

CellStyle style = view->ui->style_get(view->ui, style_id);
size_t pos = view->start;
Line *line = view->topline;

Expand All @@ -1435,7 +1434,7 @@ void view_style(View *view, enum UiStyle style_id, size_t start, size_t end) {
do {
while (pos <= end && col < width) {
pos += line->cells[col].len;
line->cells[col++].style = style;
view->ui->style_set(view->ui, &line->cells[col++], style);
}
col = 0;
} while (pos <= end && (line = line->next));
Expand Down
5 changes: 3 additions & 2 deletions view.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

typedef struct View View;
typedef struct Selection Selection;
typedef struct Cell Cell;

#include "text.h"
#include "ui.h"
Expand All @@ -16,7 +17,7 @@ typedef struct {
Mark cursor;
} SelectionRegion;

typedef struct {
struct Cell {
char data[16]; /* utf8 encoded character displayed in this cell (might be more than
one Unicode codepoint. might also not be the same as in the
underlying text, for example tabs get expanded */
Expand All @@ -26,7 +27,7 @@ typedef struct {
occupied by the same character have a length of 0. */
int width; /* display width i.e. number of columns occupied by this character */
CellStyle style; /* colors and attributes used to display this cell */
} Cell;
};

typedef struct Line Line;
struct Line { /* a line on the screen, *not* in the file */
Expand Down
Loading

0 comments on commit 8acdb79

Please sign in to comment.