Created tagged union for selection colors, enabled parsing

Implemented cell color for Metal

Removed use of selection-invert-fg-bg

Mirrored feature to OpenGL

Added tests for SelectionColor

Fixed selection on inverted cell behavior

Implemented cell colors for cursor-text

Implemented cell colors for cursor-color, removed uses of cursor-invert-fg-bg during rendering

Updated docs for dynamically colored options

Updated docstrings, cleaned up awkward formatting, and moved style computation to avoid unnecssary invocations

Bump version in docstrings
This commit is contained in:
Daniel
2025-01-18 20:47:23 -06:00
committed by Mitchell Hashimoto
parent 7bb6d3b728
commit 9e341a3d60
3 changed files with 80 additions and 11 deletions

View File

@ -591,8 +591,11 @@ foreground: Color = .{ .r = 0xFF, .g = 0xFF, .b = 0xFF },
/// the selection color is just the inverted window background and foreground
/// (note: not to be confused with the cell bg/fg).
/// Specified as either hex (`#RRGGBB` or `RRGGBB`) or a named X11 color.
@"selection-foreground": ?Color = null,
@"selection-background": ?Color = null,
/// Since version 1.1.1, this can also be set to `cell-foreground` to match
/// the cell foreground color, or `cell-background` to match the cell
/// background color.
@"selection-foreground": ?DynamicColor = null,
@"selection-background": ?DynamicColor = null,
/// Swap the foreground and background colors of cells for selection. This
/// option overrides the `selection-foreground` and `selection-background`
@ -600,6 +603,10 @@ foreground: Color = .{ .r = 0xFF, .g = 0xFF, .b = 0xFF },
///
/// If you select across cells with differing foregrounds and backgrounds, the
/// selection color will vary across the selection.
///
/// Warning: This option has been deprecated as of version 1.1.1. Instead,
/// users should set `selection-foreground` and `selection-background` to
/// `cell-background` and `cell-foreground`, respectively.
@"selection-invert-fg-bg": bool = false,
/// Whether to clear selected text when typing. This defaults to `true`.
@ -645,10 +652,17 @@ palette: Palette = .{},
/// The color of the cursor. If this is not set, a default will be chosen.
/// Specified as either hex (`#RRGGBB` or `RRGGBB`) or a named X11 color.
@"cursor-color": ?Color = null,
/// Since version 1.1.1, this can also be set to `cell-foreground` to match
/// the cell foreground color, or `cell-background` to match the cell
/// background color.
@"cursor-color": ?DynamicColor = null,
/// Swap the foreground and background colors of the cell under the cursor. This
/// option overrides the `cursor-color` and `cursor-text` options.
///
/// Warning: This option has been deprecated as of version 1.1.1. Instead,
/// users should set `cursor-color` and `cursor-text` to `cell-foreground` and
/// `cell-background`, respectively.
@"cursor-invert-fg-bg": bool = false,
/// The opacity level (opposite of transparency) of the cursor. A value of 1
@ -699,7 +713,10 @@ palette: Palette = .{},
/// The color of the text under the cursor. If this is not set, a default will
/// be chosen.
/// Specified as either hex (`#RRGGBB` or `RRGGBB`) or a named X11 color.
@"cursor-text": ?Color = null,
/// Since version 1.1.1, this can also be set to `cell-foreground` to match
/// the cell foreground color, or `cell-background` to match the cell
/// background color.
@"cursor-text": ?DynamicColor = null,
/// Enables the ability to move the cursor at prompts by using `alt+click` on
/// Linux and `option+click` on macOS.
@ -4409,6 +4426,54 @@ pub const Color = struct {
}
};
/// Represents the color values that can be set to a non-static value.
///
/// Can either be a Color or one of the special values
/// "cell-foreground" or "cell-background".
pub const DynamicColor = union(enum) {
color: Color,
@"cell-foreground",
@"cell-background",
pub fn parseCLI(input_: ?[]const u8) !DynamicColor {
const input = input_ orelse return error.ValueRequired;
if (std.mem.eql(u8, input, "cell-foreground")) return .@"cell-foreground";
if (std.mem.eql(u8, input, "cell-background")) return .@"cell-background";
return DynamicColor{ .color = try Color.parseCLI(input) };
}
/// Used by Formatter
pub fn formatEntry(self: DynamicColor, formatter: anytype) !void {
switch (self) {
.color => try self.color.formatEntry(formatter),
.@"cell-foreground", .@"cell-background" => try formatter.formatEntry([:0]const u8, @tagName(self)),
}
}
test "parseCLI" {
const testing = std.testing;
try testing.expectEqual(DynamicColor{ .color = Color{ .r = 78, .g = 42, .b = 132 } }, try DynamicColor.parseCLI("#4e2a84"));
try testing.expectEqual(DynamicColor{ .color = Color{ .r = 0, .g = 0, .b = 0 } }, try DynamicColor.parseCLI("black"));
try testing.expectEqual(DynamicColor{.@"cell-foreground"}, try DynamicColor.parseCLI("cell-foreground"));
try testing.expectEqual(DynamicColor{.@"cell-background"}, try DynamicColor.parseCLI("cell-background"));
try testing.expectError(error.InvalidValue, DynamicColor.parseCLI("a"));
}
test "formatConfig" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
defer buf.deinit();
var sc: DynamicColor = .{.@"cell-foreground"};
try sc.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try testing.expectEqualSlices(u8, "a = cell-foreground\n", buf.items);
}
};
pub const ColorList = struct {
const Self = @This();

View File

@ -163,8 +163,7 @@ pub const DerivedConfig = struct {
image_storage_limit: usize,
cursor_style: terminalpkg.CursorStyle,
cursor_blink: ?bool,
cursor_color: ?configpkg.Config.Color,
cursor_invert: bool,
cursor_color: ?configpkg.Config.DynamicColor,
foreground: configpkg.Config.Color,
background: configpkg.Config.Color,
osc_color_report_format: configpkg.Config.OSCColorReportFormat,
@ -185,7 +184,6 @@ pub const DerivedConfig = struct {
.cursor_style = config.@"cursor-style",
.cursor_blink = config.@"cursor-style-blink",
.cursor_color = config.@"cursor-color",
.cursor_invert = config.@"cursor-invert-fg-bg",
.foreground = config.foreground,
.background = config.background,
.osc_color_report_format = config.@"osc-color-report-format",
@ -265,8 +263,11 @@ pub fn init(self: *Termio, alloc: Allocator, opts: termio.Options) !void {
// Create our stream handler. This points to memory in self so it
// isn't safe to use until self.* is set.
const handler: StreamHandler = handler: {
const default_cursor_color = if (!opts.config.cursor_invert and opts.config.cursor_color != null)
opts.config.cursor_color.?.toTerminalRGB()
const default_cursor_color = if (opts.config.cursor_color) |color|
switch (color) {
.color => color.color.toTerminalRGB(),
else => null,
}
else
null;

View File

@ -121,8 +121,11 @@ pub const StreamHandler = struct {
self.default_background_color = config.background.toTerminalRGB();
self.default_cursor_style = config.cursor_style;
self.default_cursor_blink = config.cursor_blink;
self.default_cursor_color = if (!config.cursor_invert and config.cursor_color != null)
config.cursor_color.?.toTerminalRGB()
self.default_cursor_color = if (config.cursor_color) |color|
switch (color) {
.color => color.color.toTerminalRGB(),
else => null,
}
else
null;