diff --git a/build.zig.zon b/build.zig.zon index 88dd1fd1..a1cbb89b 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -22,8 +22,8 @@ .hash = "thespian-0.0.1-owFOjlgiBgC8w4XqkCOegxz5vMy6kNErcssWQWf2QHeE", }, .themes = .{ - .url = "https://github.com/neurocyte/flow-themes/releases/download/master-750400d02ea8cacaabc869cd4d34dcebf04a53c8/flow-themes.tar.gz", - .hash = "N-V-__8AAEWxJQAyUV_rvRIWHB8EhIBxpQXqCB68SpilIjEt", + .url = "https://github.com/neurocyte/flow-themes/releases/download/master-32b5be45c4c001902fc8ff226d2e790e462148ed/flow-themes.tar.gz", + .hash = "N-V-__8AAP_iKgB6QFdA6p7L0Yvz2GpIbDtM80oD5lebig9_", }, .fuzzig = .{ .url = "https://github.com/fjebaker/fuzzig/archive/4251fe4230d38e721514394a485db62ee1667ff3.tar.gz", diff --git a/src/color.zig b/src/color.zig index 47be2ecc..c97c300e 100644 --- a/src/color.zig +++ b/src/color.zig @@ -106,6 +106,10 @@ pub const RGBf = struct { const GAMMA = 2.4; }; +pub fn u24_to_u8s(v: u24) [3]u8 { + return .{ @truncate(v >> 16), @truncate(v >> 8), @truncate(v) }; +} + pub fn max_contrast(v: u24, a: u24, b: u24) u24 { return RGB.max_contrast(RGB.from_u24(v), RGB.from_u24(a), RGB.from_u24(b)).to_u24(); } diff --git a/src/tui/terminal_view.zig b/src/tui/terminal_view.zig index fe9da1eb..9204b655 100644 --- a/src/tui/terminal_view.zig +++ b/src/tui/terminal_view.zig @@ -18,7 +18,8 @@ const tui = @import("tui.zig"); const input = @import("input"); const keybind = @import("keybind"); pub const Mode = keybind.Mode; -const RGB = @import("color").RGB; +const color = @import("color"); +const RGB = color.RGB; pub const name = @typeName(Self); @@ -371,14 +372,8 @@ pub fn render(self: *Self, theme: *const Widget.Theme) bool { // Update the terminal's fg/bg color cache from the current theme so that // OSC 10/11 colour queries return accurate values. - if (theme.editor.fg) |fg| { - const c = fg.color; - self.vt.vt.fg_color = .{ @truncate(c >> 16), @truncate(c >> 8), @truncate(c) }; - } - if (theme.editor.bg) |bg| { - const c = bg.color; - self.vt.vt.bg_color = .{ @truncate(c >> 16), @truncate(c >> 8), @truncate(c) }; - } + if (theme.editor.fg) |fg| self.vt.vt.fg_color = color.u24_to_u8s(fg.color); + if (theme.editor.bg) |bg| self.vt.vt.bg_color = color.u24_to_u8s(bg.color); // Blit the terminal's front screen into our vaxis.Window. const software_cursor = !tui.has_native_cursor(); @@ -388,6 +383,24 @@ pub fn render(self: *Self, theme: *const Widget.Theme) bool { std.log.err("terminal_view: draw failed: {}", .{e}); }; + // Resolve ANSI colour indices 0–15 to theme RGB values + { + const palette = theme.ansi_palette; + const win = self.plane.window; + const scr = win.screen; + const y_off: usize = @intCast(win.y_off); + const x_off: usize = @intCast(win.x_off); + for (0..win.height) |row| { + const row_base = (y_off + row) * scr.width + x_off; + if (row_base >= scr.buf.len) break; + const row_end = @min(row_base + win.width, scr.buf.len); + for (scr.buf[row_base..row_end]) |*cell| { + resolve_color(&cell.style.fg, palette); + resolve_color(&cell.style.bg, palette); + } + } + } + if (!software_cursor and self.focused and tui.terminal_has_focus()) { const scr = &tui.rdr().vx.screen; if (scr.cursor_vis) @@ -397,6 +410,15 @@ pub fn render(self: *Self, theme: *const Widget.Theme) bool { return false; } +fn resolve_color(c: *vaxis.Cell.Color, palette: [16][3]u8) void { + switch (c.*) { + .index => |idx| if (idx < 16) { + c.* = .{ .rgb = palette[idx] }; + }, + else => {}, + } +} + fn handle_child_exit(self: *Self, code: u8) void { switch (self.vt.on_exit) { .hold => self.show_exit_message(code),