-
Notifications
You must be signed in to change notification settings - Fork 654
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: support selection foreground being cell foreground #5219
base: main
Are you sure you want to change the base?
Changes from all commits
671a12a
8fe5904
ccb5f00
861a6c2
686e08d
4d75871
3b500f1
0e1f21d
0c05ff5
6444db4
168d013
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -99,12 +99,7 @@ cursor_color: ?terminal.color.RGB, | |
/// This is cursor color as set in the user's config, if any. If no cursor color | ||
/// is set in the user's config, then the cursor color is determined by the | ||
/// current foreground color. | ||
default_cursor_color: ?terminal.color.RGB, | ||
|
||
/// When `cursor_color` is null, swap the foreground and background colors of | ||
/// the cell under the cursor for the cursor color. Otherwise, use the default | ||
/// foreground color as the cursor color. | ||
cursor_invert: bool, | ||
default_cursor_color: ?configpkg.Config.DynamicColor, | ||
|
||
/// The current set of cells to render. This is rebuilt on every frame | ||
/// but we keep this around so that we don't reallocate. Each set of | ||
|
@@ -374,16 +369,14 @@ pub const DerivedConfig = struct { | |
font_thicken_strength: u8, | ||
font_features: std.ArrayListUnmanaged([:0]const u8), | ||
font_styles: font.CodepointResolver.StyleStatus, | ||
cursor_color: ?terminal.color.RGB, | ||
cursor_invert: bool, | ||
cursor_color: ?configpkg.Config.DynamicColor, | ||
cursor_opacity: f64, | ||
cursor_text: ?terminal.color.RGB, | ||
cursor_text: ?configpkg.Config.DynamicColor, | ||
background: terminal.color.RGB, | ||
background_opacity: f64, | ||
foreground: terminal.color.RGB, | ||
selection_background: ?terminal.color.RGB, | ||
selection_foreground: ?terminal.color.RGB, | ||
invert_selection_fg_bg: bool, | ||
selection_background: ?configpkg.Config.DynamicColor, | ||
selection_foreground: ?configpkg.Config.DynamicColor, | ||
bold_is_bright: bool, | ||
min_contrast: f32, | ||
padding_color: configpkg.WindowPaddingColor, | ||
|
@@ -419,45 +412,25 @@ pub const DerivedConfig = struct { | |
config.link.links.items, | ||
); | ||
|
||
const cursor_invert = config.@"cursor-invert-fg-bg"; | ||
|
||
return .{ | ||
.background_opacity = @max(0, @min(1, config.@"background-opacity")), | ||
.font_thicken = config.@"font-thicken", | ||
.font_thicken_strength = config.@"font-thicken-strength", | ||
.font_features = font_features.list, | ||
.font_styles = font_styles, | ||
|
||
.cursor_color = if (!cursor_invert and config.@"cursor-color" != null) | ||
config.@"cursor-color".?.toTerminalRGB() | ||
else | ||
null, | ||
|
||
.cursor_invert = cursor_invert, | ||
|
||
.cursor_text = if (config.@"cursor-text") |txt| | ||
txt.toTerminalRGB() | ||
else | ||
null, | ||
|
||
.cursor_color = config.@"cursor-color", | ||
.cursor_text = config.@"cursor-text", | ||
.cursor_opacity = @max(0, @min(1, config.@"cursor-opacity")), | ||
|
||
.background = config.background.toTerminalRGB(), | ||
.foreground = config.foreground.toTerminalRGB(), | ||
.invert_selection_fg_bg = config.@"selection-invert-fg-bg", | ||
.bold_is_bright = config.@"bold-is-bright", | ||
.min_contrast = @floatCast(config.@"minimum-contrast"), | ||
.padding_color = config.@"window-padding-color", | ||
|
||
.selection_background = if (config.@"selection-background") |bg| | ||
bg.toTerminalRGB() | ||
else | ||
null, | ||
|
||
.selection_foreground = if (config.@"selection-foreground") |bg| | ||
bg.toTerminalRGB() | ||
else | ||
null, | ||
.selection_background = config.@"selection-background", | ||
.selection_foreground = config.@"selection-foreground", | ||
|
||
.custom_shaders = custom_shaders, | ||
.links = links, | ||
|
@@ -645,7 +618,6 @@ pub fn init(alloc: Allocator, options: renderer.Options) !Metal { | |
.default_background_color = options.config.background, | ||
.cursor_color = null, | ||
.default_cursor_color = options.config.cursor_color, | ||
.cursor_invert = options.config.cursor_invert, | ||
|
||
// Render state | ||
.cells = .{}, | ||
|
@@ -2117,8 +2089,7 @@ pub fn changeConfig(self: *Metal, config: *DerivedConfig) !void { | |
// Set our new colors | ||
self.default_background_color = config.background; | ||
self.default_foreground_color = config.foreground; | ||
self.default_cursor_color = if (!config.cursor_invert) config.cursor_color else null; | ||
self.cursor_invert = config.cursor_invert; | ||
self.default_cursor_color = config.cursor_color; | ||
|
||
// Update our layer's opaqueness and display sync in case they changed. | ||
{ | ||
|
@@ -2598,22 +2569,15 @@ fn rebuildCells( | |
// The final background color for the cell. | ||
const bg = bg: { | ||
if (selected) { | ||
break :bg if (self.config.invert_selection_fg_bg) | ||
if (style.flags.inverse) | ||
// Cell is selected with invert selection fg/bg | ||
// enabled, and the cell has the inverse style | ||
// flag, so they cancel out and we get the normal | ||
// bg color. | ||
bg_style | ||
else | ||
// If it doesn't have the inverse style | ||
// flag then we use the fg color instead. | ||
fg_style | ||
break :bg if (self.config.selection_background) |selection_color| | ||
// Use the selection background if set, otherwise the default fg color. | ||
switch (selection_color) { | ||
.color => selection_color.color.toTerminalRGB(), | ||
.@"cell-foreground" => if (style.flags.inverse) bg_style else fg_style, | ||
.@"cell-background" => if (style.flags.inverse) fg_style else bg_style, | ||
} | ||
else | ||
// If we don't have invert selection fg/bg set then we | ||
// just use the selection background if set, otherwise | ||
// the default fg color. | ||
break :bg self.config.selection_background orelse self.foreground_color orelse self.default_foreground_color; | ||
self.foreground_color orelse self.default_foreground_color; | ||
} | ||
|
||
// Not selected | ||
|
@@ -2631,20 +2595,26 @@ fn rebuildCells( | |
}; | ||
|
||
const fg = fg: { | ||
if (selected and !self.config.invert_selection_fg_bg) { | ||
// If we don't have invert selection fg/bg set | ||
// then we just use the selection foreground if | ||
// set, otherwise the default bg color. | ||
break :fg self.config.selection_foreground orelse self.background_color orelse self.default_background_color; | ||
} | ||
const final_bg = bg_style orelse self.background_color orelse self.default_background_color; | ||
|
||
// Whether we need to use the bg color as our fg color: | ||
// - Cell is selected, inverted, and set to cell-foreground | ||
// - Cell is selected, not inverted, and set to cell-background | ||
// - Cell is inverted and not selected | ||
// - Cell is selected and not inverted | ||
// Note: if selected then invert sel fg / bg must be | ||
// false since we separately handle it if true above. | ||
break :fg if (style.flags.inverse != selected) | ||
bg_style orelse self.background_color orelse self.default_background_color | ||
if (selected) { | ||
// Use the selection foreground if set, otherwise the default bg color. | ||
break :fg if (self.config.selection_foreground) |selection_color| | ||
switch (selection_color) { | ||
.color => selection_color.color.toTerminalRGB(), | ||
.@"cell-foreground" => if (style.flags.inverse) final_bg else fg_style, | ||
.@"cell-background" => if (style.flags.inverse) fg_style else final_bg, | ||
} | ||
else | ||
self.background_color orelse self.default_background_color; | ||
} | ||
|
||
break :fg if (style.flags.inverse) | ||
final_bg | ||
else | ||
fg_style; | ||
}; | ||
|
@@ -2833,19 +2803,25 @@ fn rebuildCells( | |
|
||
// Prepare the cursor cell contents. | ||
const style = cursor_style_ orelse break :cursor; | ||
const cursor_color = self.cursor_color orelse self.default_cursor_color orelse color: { | ||
if (self.cursor_invert) { | ||
// Use the foreground color from the cell under the cursor, if any. | ||
const sty = screen.cursor.page_pin.style(screen.cursor.page_cell); | ||
break :color if (sty.flags.inverse) | ||
// If the cell is reversed, use background color instead. | ||
(sty.bg(screen.cursor.page_cell, color_palette) orelse self.background_color orelse self.default_background_color) | ||
else | ||
(sty.fg(color_palette, self.config.bold_is_bright) orelse self.foreground_color orelse self.default_foreground_color); | ||
} else { | ||
break :color self.foreground_color orelse self.default_foreground_color; | ||
const cursor_color = self.cursor_color orelse if (self.default_cursor_color) |color| color: { | ||
// If cursor-color is set, then compute the correct color. | ||
// Otherwise, use the foreground color | ||
if (color == .color) { | ||
// Use the color set by cursor-color, if any. | ||
break :color color.color.toTerminalRGB(); | ||
} | ||
}; | ||
|
||
const sty = screen.cursor.page_pin.style(screen.cursor.page_cell); | ||
const fg_style = sty.fg(color_palette, self.config.bold_is_bright) orelse self.foreground_color orelse self.default_foreground_color; | ||
const bg_style = sty.bg(screen.cursor.page_cell, color_palette) orelse self.background_color orelse self.default_background_color; | ||
Comment on lines
+2814
to
+2816
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's probably not a big deal, but we are computing these styles even if they're not needed when the cursor color is set to an explicit style. I don't think there is a significant runtime cost though. If we wanted to avoid that we could first check to see if the enum has the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added a check before these calls which should skip them if the union has the |
||
|
||
break :color switch (color) { | ||
// If the cell is reversed, use the opposite cell color instead. | ||
.@"cell-foreground" => if (sty.flags.inverse) bg_style else fg_style, | ||
.@"cell-background" => if (sty.flags.inverse) fg_style else bg_style, | ||
else => unreachable, | ||
}; | ||
} else self.foreground_color orelse self.default_foreground_color; | ||
|
||
self.addCursor(screen, style, cursor_color); | ||
|
||
|
@@ -2869,18 +2845,25 @@ fn rebuildCells( | |
.wide, .spacer_tail => true, | ||
}; | ||
|
||
const uniform_color = if (self.cursor_invert) blk: { | ||
// Use the background color from the cell under the cursor, if any. | ||
const uniform_color = if (self.config.cursor_text) |txt| blk: { | ||
// If cursor-text is set, then compute the correct color. | ||
// Otherwise, use the background color. | ||
if (txt == .color) { | ||
// Use the color set by cursor-text, if any. | ||
break :blk txt.color.toTerminalRGB(); | ||
} | ||
|
||
const sty = screen.cursor.page_pin.style(screen.cursor.page_cell); | ||
break :blk if (sty.flags.inverse) | ||
// If the cell is reversed, use foreground color instead. | ||
(sty.fg(color_palette, self.config.bold_is_bright) orelse self.foreground_color orelse self.default_foreground_color) | ||
else | ||
(sty.bg(screen.cursor.page_cell, color_palette) orelse self.background_color orelse self.default_background_color); | ||
} else if (self.config.cursor_text) |txt| | ||
txt | ||
else | ||
self.background_color orelse self.default_background_color; | ||
const fg_style = sty.fg(color_palette, self.config.bold_is_bright) orelse self.foreground_color orelse self.default_foreground_color; | ||
const bg_style = sty.bg(screen.cursor.page_cell, color_palette) orelse self.background_color orelse self.default_background_color; | ||
|
||
break :blk switch (txt) { | ||
// If the cell is reversed, use the opposite cell color instead. | ||
.@"cell-foreground" => if (sty.flags.inverse) bg_style else fg_style, | ||
.@"cell-background" => if (sty.flags.inverse) fg_style else bg_style, | ||
else => unreachable, | ||
}; | ||
} else self.background_color orelse self.default_background_color; | ||
|
||
self.uniforms.cursor_color = .{ | ||
uniform_color.r, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably not for this PR (and maybe never), but I wonder if we should unify the terminology for cursor and selection, so that instead of
cursor-text
andcursor-color
we usecursor-foreground
andcursor-background
.