diff --git a/lua/themes/dark-16.lua b/lua/themes/base-16.lua similarity index 79% rename from lua/themes/dark-16.lua rename to lua/themes/base-16.lua index fd7e1dbf9..f334e1163 100644 --- a/lua/themes/dark-16.lua +++ b/lua/themes/base-16.lua @@ -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' @@ -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,fore:black' 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 = '' diff --git a/lua/themes/default-16.lua b/lua/themes/default-16.lua deleted file mode 120000 index 51192b440..000000000 --- a/lua/themes/default-16.lua +++ /dev/null @@ -1 +0,0 @@ -dark-16.lua \ No newline at end of file diff --git a/lua/themes/default-256.lua b/lua/themes/default-256.lua deleted file mode 120000 index e12776c02..000000000 --- a/lua/themes/default-256.lua +++ /dev/null @@ -1 +0,0 @@ -zenburn.lua \ No newline at end of file diff --git a/lua/themes/default.lua b/lua/themes/default.lua new file mode 120000 index 000000000..2813d855c --- /dev/null +++ b/lua/themes/default.lua @@ -0,0 +1 @@ +base-16.lua \ No newline at end of file diff --git a/lua/themes/light-16.lua b/lua/themes/light-16.lua deleted file mode 100644 index 53d0e45e1..000000000 --- a/lua/themes/light-16.lua +++ /dev/null @@ -1,37 +0,0 @@ --- Eight-color scheme -local lexers = vis.lexers --- light -lexers.STYLE_DEFAULT = 'back:white,fore:black' -lexers.STYLE_NOTHING = 'back:white' -lexers.STYLE_CLASS = 'fore:yellow,bold' -lexers.STYLE_COMMENT = 'fore:blue,bold' -lexers.STYLE_CONSTANT = 'fore:cyan,bold' -lexers.STYLE_DEFINITION = 'fore:blue,bold' -lexers.STYLE_ERROR = 'fore:red,italics' -lexers.STYLE_FUNCTION = 'fore:blue,bold' -lexers.STYLE_KEYWORD = 'fore:yellow,bold' -lexers.STYLE_LABEL = 'fore:green,bold' -lexers.STYLE_NUMBER = 'fore:red,bold' -lexers.STYLE_OPERATOR = 'fore:cyan,bold' -lexers.STYLE_REGEX = 'fore:green,bold' -lexers.STYLE_STRING = 'fore:red,bold' -lexers.STYLE_PREPROCESSOR = 'fore:magenta,bold' -lexers.STYLE_TAG = 'fore:red,bold' -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:black' - -lexers.STYLE_LINENUMBER = 'fore:black' -lexers.STYLE_LINENUMBER_CURSOR = lexers.STYLE_LINENUMBER -lexers.STYLE_CURSOR = 'reverse' -lexers.STYLE_CURSOR_PRIMARY = lexers.STYLE_CURSOR..',fore:yellow' -lexers.STYLE_CURSOR_LINE = 'underlined' -lexers.STYLE_COLOR_COLUMN = 'back:red' -lexers.STYLE_SELECTION = 'back:black' -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_EOF = '' diff --git a/lua/vis-std.lua b/lua/vis-std.lua index 971d24715..8b5715b38 100644 --- a/lua/vis-std.lua +++ b/lua/vis-std.lua @@ -2,9 +2,9 @@ vis.events.subscribe(vis.events.INIT, function() if os.getenv("TERM_PROGRAM") == "Apple_Terminal" then - vis:command("set change256colors false"); + vis:command("set change256colors 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) diff --git a/ui-terminal-curses.c b/ui-terminal-curses.c index 0e7a4f189..b89d9b58f 100644 --- a/ui-terminal-curses.c +++ b/ui-terminal-curses.c @@ -51,9 +51,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) @@ -83,10 +87,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; @@ -170,7 +177,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) { @@ -300,3 +307,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); +} diff --git a/ui-terminal-vt100.c b/ui-terminal-vt100.c index 3c785b802..565313f9e 100644 --- a/ui-terminal-vt100.c +++ b/ui-terminal-vt100.c @@ -75,7 +75,13 @@ typedef struct { UiTerm uiterm; 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 }; } @@ -219,6 +225,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); +} diff --git a/ui-terminal.c b/ui-terminal.c index 264c6d3c0..cf343783a 100644 --- a/ui-terminal.c +++ b/ui-terminal.c @@ -286,10 +286,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) { @@ -520,7 +531,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, diff --git a/ui.h b/ui.h index ce98af1c1..76bdcce33 100644 --- a/ui.h +++ b/ui.h @@ -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 { @@ -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*); @@ -116,7 +105,6 @@ struct UiWin { int (*window_height)(UiWin*); }; -bool is_default_color(CellColor c); enum UiLayout ui_layout_get(Ui *ui); #endif diff --git a/view.c b/view.c index 4ae4b8753..df7906b54 100644 --- a/view.c +++ b/view.c @@ -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) { @@ -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; @@ -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)); diff --git a/view.h b/view.h index 95df58b6c..68eeb4b9f 100644 --- a/view.h +++ b/view.h @@ -6,6 +6,7 @@ typedef struct View View; typedef struct Selection Selection; +typedef struct Cell Cell; #include "text.h" #include "ui.h" @@ -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 */ @@ -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 */ diff --git a/vis.c b/vis.c index 8d68907d2..e28740539 100644 --- a/vis.c +++ b/vis.c @@ -297,7 +297,6 @@ static void window_draw_colorcolumn(Win *win) { int cc = view_colorcolumn_get(view); if (cc <= 0) return; - CellStyle style = win->ui->style_get(win->ui, UI_STYLE_COLOR_COLUMN); size_t lineno = 0; int line_cols = 0; /* Track the number of columns we've passed on each line */ bool line_cc_set = false; /* Has the colorcolumn attribute been set for this line yet */ @@ -315,10 +314,7 @@ static void window_draw_colorcolumn(Win *win) { /* This screen line contains the cell we want to highlight */ if (cc <= line_cols + width) { - CellStyle *orig = &l->cells[cc - 1 - line_cols].style; - orig->attr = style.attr; - orig->fg = is_default_color(style.fg) ? orig->fg : style.fg; - orig->bg = is_default_color(style.bg) ? orig->bg : style.bg; + win->ui->style_set(win->ui, &l->cells[cc - 1 - line_cols], UI_STYLE_COLOR_COLUMN); line_cc_set = true; } else { line_cols += width; @@ -338,22 +334,20 @@ static void window_draw_cursorline(Win *win) { return; int width = view_width_get(view); - CellStyle style = win->ui->style_get(win->ui, UI_STYLE_CURSOR_LINE); Selection *sel = view_selections_primary_get(view); size_t lineno = view_cursors_line_get(sel)->lineno; for (Line *l = view_lines_first(view); l; l = l->next) { if (l->lineno == lineno) { - for (int x = 0; x < width; x++) { - l->cells[x].style.attr |= style.attr; - l->cells[x].style.bg = style.bg; - } + for (int x = 0; x < width; x++) + win->ui->style_set(win->ui, &l->cells[x], UI_STYLE_CURSOR_LINE); } else if (l->lineno > lineno) { break; } } } -static void window_draw_selection(View *view, Selection *cur, CellStyle *style) { +static void window_draw_selection(Win *win, Selection *cur) { + View *view = win->view; Filerange sel = view_selections_get(cur); if (!text_range_valid(&sel)) return; @@ -374,25 +368,12 @@ static void window_draw_selection(View *view, Selection *cur, CellStyle *style) for (Line *l = start_line; l != end_line->next; l = l->next) { int col = (l == start_line) ? start_col : 0; int end = (l == end_line) ? end_col : l->width; - while (col < end) { - if (cell_color_equal(l->cells[col].style.fg, style->bg)) { - CellStyle old = l->cells[col].style; - if (!cell_color_equal(old.fg, old.bg)) { - l->cells[col].style.fg = old.bg; - l->cells[col].style.bg = old.fg; - } else { - l->cells[col].style.attr = style->attr; - } - } else { - l->cells[col].style.bg = style->bg; - l->cells[col].style.fg = style->fg; - } - col++; - } + while (col < end) + win->ui->style_set(win->ui, &l->cells[col++], UI_STYLE_SELECTION); } } -static void window_draw_cursor_matching(Win *win, Selection *cur, CellStyle *style) { +static void window_draw_cursor_matching(Win *win, Selection *cur) { if (win->vis->mode->visual) return; Line *line_match; int col_match; @@ -403,25 +384,18 @@ static void window_draw_cursor_matching(Win *win, Selection *cur, CellStyle *sty return; if (!view_coord_get(win->view, pos_match, &line_match, NULL, &col_match)) return; - if (cell_color_equal(line_match->cells[col_match].style.fg, style->fg)) { - CellStyle old = line_match->cells[col_match].style; - line_match->cells[col_match].style.fg = old.bg; - line_match->cells[col_match].style.bg = old.fg; - } else { - line_match->cells[col_match].style.bg = style->bg; - line_match->cells[col_match].style.fg = style->fg; - } + win->ui->style_set(win->ui, &line_match->cells[col_match], UI_STYLE_SELECTION); } -static void window_draw_cursor(Win *win, Selection *cur, CellStyle *style, CellStyle *sel_style) { +static void window_draw_cursor(Win *win, Selection *cur) { if (win->vis->win != win) return; Line *line = view_cursors_line_get(cur); int col = view_cursors_cell_get(cur); if (!line || col == -1) return; - line->cells[col].style = *style; - window_draw_cursor_matching(win, cur, sel_style); + win->ui->style_set(win->ui, &line->cells[col], UI_STYLE_CURSOR); + window_draw_cursor_matching(win, cur); return; } @@ -429,24 +403,21 @@ static void window_draw_selections(Win *win) { View *view = win->view; Filerange viewport = view_viewport_get(view); Selection *sel = view_selections_primary_get(view); - CellStyle style_cursor = win->ui->style_get(win->ui, UI_STYLE_CURSOR); - CellStyle style_cursor_primary = win->ui->style_get(win->ui, UI_STYLE_CURSOR_PRIMARY); - CellStyle style_selection = win->ui->style_get(win->ui, UI_STYLE_SELECTION); for (Selection *s = view_selections_prev(sel); s; s = view_selections_prev(s)) { - window_draw_selection(win->view, s, &style_selection); + window_draw_selection(win, s); size_t pos = view_cursors_pos(s); if (pos < viewport.start) break; - window_draw_cursor(win, s, &style_cursor, &style_selection); + window_draw_cursor(win, s); } - window_draw_selection(win->view, sel, &style_selection); - window_draw_cursor(win, sel, &style_cursor_primary, &style_selection); + window_draw_selection(win, sel); + window_draw_cursor(win, sel); for (Selection *s = view_selections_next(sel); s; s = view_selections_next(s)) { - window_draw_selection(win->view, s, &style_selection); + window_draw_selection(win, s); size_t pos = view_cursors_pos(s); if (pos > viewport.end) break; - window_draw_cursor(win, s, &style_cursor, &style_selection); + window_draw_cursor(win, s); } } @@ -454,10 +425,9 @@ static void window_draw_eof(Win *win) { View *view = win->view; if (view_width_get(view) == 0) return; - CellStyle style = win->ui->style_get(win->ui, UI_STYLE_EOF); for (Line *l = view_lines_last(view)->next; l; l = l->next) { strncpy(l->cells[0].data, view_symbol_eof_get(view), sizeof(l->cells[0].data)-1); - l->cells[0].style = style; + win->ui->style_set(win->ui, &l->cells[0], UI_STYLE_EOF); } }