mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
config: add cursor-invert-fg-bg option
When set, the cursor-invert-fg-bg option uses the inverted foreground and background colors of the cursor's current cell to color the cursor, rather than using a fixed color. This option has higher precedence than the cursor-color and cursor-text options, but has lower precedence than an OSC 12 command to change the cursor color.
This commit is contained in:
@ -289,6 +289,12 @@ palette: Palette = .{},
|
||||
/// The color of the cursor. If this is not set, a default will be chosen.
|
||||
@"cursor-color": ?Color = null,
|
||||
|
||||
/// Swap the foreground and background colors of the cell under the cursor. This
|
||||
/// option overrides the `cursor-color` and `cursor-text` options.
|
||||
///
|
||||
/// This is currently only supported on macOS.
|
||||
@"cursor-invert-fg-bg": bool = false,
|
||||
|
||||
/// The opacity level (opposite of transparency) of the cursor. A value of 1
|
||||
/// is fully opaque and a value of 0 is fully transparent. A value less than 0
|
||||
/// or greater than 1 will be clamped to the nearest valid value. Note that a
|
||||
|
@ -91,6 +91,11 @@ background_color: terminal.color.RGB,
|
||||
/// by a terminal application
|
||||
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,
|
||||
|
||||
/// The current frame background color. This is only updated during
|
||||
/// the updateFrame method.
|
||||
current_background_color: terminal.color.RGB,
|
||||
@ -317,6 +322,7 @@ pub const DerivedConfig = struct {
|
||||
font_features: std.ArrayListUnmanaged([:0]const u8),
|
||||
font_styles: font.CodepointResolver.StyleStatus,
|
||||
cursor_color: ?terminal.color.RGB,
|
||||
cursor_invert: bool,
|
||||
cursor_opacity: f64,
|
||||
cursor_text: ?terminal.color.RGB,
|
||||
background: terminal.color.RGB,
|
||||
@ -357,17 +363,21 @@ 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_features = font_features,
|
||||
.font_styles = font_styles,
|
||||
|
||||
.cursor_color = if (config.@"cursor-color") |col|
|
||||
col.toTerminalRGB()
|
||||
.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
|
||||
@ -590,6 +600,7 @@ pub fn init(alloc: Allocator, options: renderer.Options) !Metal {
|
||||
.foreground_color = options.config.foreground,
|
||||
.background_color = options.config.background,
|
||||
.cursor_color = options.config.cursor_color,
|
||||
.cursor_invert = options.config.cursor_invert,
|
||||
.current_background_color = options.config.background,
|
||||
|
||||
// Render state
|
||||
@ -1753,7 +1764,8 @@ pub fn changeConfig(self: *Metal, config: *DerivedConfig) !void {
|
||||
// Set our new colors
|
||||
self.background_color = config.background;
|
||||
self.foreground_color = config.foreground;
|
||||
self.cursor_color = config.cursor_color;
|
||||
self.cursor_invert = config.cursor_invert;
|
||||
self.cursor_color = if (!config.cursor_invert) config.cursor_color else null;
|
||||
|
||||
self.config.deinit();
|
||||
self.config = config.*;
|
||||
@ -2040,7 +2052,16 @@ fn rebuildCells(
|
||||
|
||||
// Prepare the cursor cell contents.
|
||||
const style = cursor_style_ orelse break :cursor;
|
||||
self.addCursor(screen, style);
|
||||
const cursor_color = self.cursor_color orelse color: {
|
||||
if (self.cursor_invert) {
|
||||
const sty = screen.cursor.page_pin.style(screen.cursor.page_cell);
|
||||
break :color sty.fg(color_palette, self.config.bold_is_bright) orelse self.foreground_color;
|
||||
} else {
|
||||
break :color self.foreground_color;
|
||||
}
|
||||
};
|
||||
|
||||
self.addCursor(screen, style, cursor_color);
|
||||
|
||||
// If the cursor is visible then we set our uniforms.
|
||||
if (style == .block and screen.viewportIsBottom()) {
|
||||
@ -2048,15 +2069,19 @@ fn rebuildCells(
|
||||
screen.cursor.x,
|
||||
screen.cursor.y,
|
||||
};
|
||||
self.uniforms.cursor_color = if (self.config.cursor_text) |txt| .{
|
||||
txt.r,
|
||||
txt.g,
|
||||
txt.b,
|
||||
255,
|
||||
} else .{
|
||||
self.background_color.r,
|
||||
self.background_color.g,
|
||||
self.background_color.b,
|
||||
|
||||
const uniform_color = if (self.cursor_invert) blk: {
|
||||
const sty = screen.cursor.page_pin.style(screen.cursor.page_cell);
|
||||
break :blk sty.bg(screen.cursor.page_cell, color_palette) orelse self.background_color;
|
||||
} else if (self.config.cursor_text) |txt|
|
||||
txt
|
||||
else
|
||||
self.background_color;
|
||||
|
||||
self.uniforms.cursor_color = .{
|
||||
uniform_color.r,
|
||||
uniform_color.g,
|
||||
uniform_color.b,
|
||||
255,
|
||||
};
|
||||
}
|
||||
@ -2317,6 +2342,7 @@ fn addCursor(
|
||||
self: *Metal,
|
||||
screen: *terminal.Screen,
|
||||
cursor_style: renderer.CursorStyle,
|
||||
cursor_color: terminal.color.RGB,
|
||||
) void {
|
||||
// Add the cursor. We render the cursor over the wide character if
|
||||
// we're on the wide characer tail.
|
||||
@ -2332,7 +2358,6 @@ fn addCursor(
|
||||
break :cell .{ prev_cell.wide == .wide, screen.cursor.x - 1 };
|
||||
};
|
||||
|
||||
const color = self.cursor_color orelse self.foreground_color;
|
||||
const alpha: u8 = if (!self.focused) 255 else alpha: {
|
||||
const alpha = 255 * self.config.cursor_opacity;
|
||||
break :alpha @intFromFloat(@ceil(alpha));
|
||||
@ -2362,7 +2387,7 @@ fn addCursor(
|
||||
.mode = .cursor,
|
||||
.grid_pos = .{ x, screen.cursor.y },
|
||||
.cell_width = if (wide) 2 else 1,
|
||||
.color = .{ color.r, color.g, color.b, alpha },
|
||||
.color = .{ cursor_color.r, cursor_color.g, cursor_color.b, alpha },
|
||||
.bg_color = .{ 0, 0, 0, 0 },
|
||||
.glyph_pos = .{ render.glyph.atlas_x, render.glyph.atlas_y },
|
||||
.glyph_size = .{ render.glyph.width, render.glyph.height },
|
||||
|
@ -82,6 +82,7 @@ pub const DerivedConfig = struct {
|
||||
cursor_style: terminal.CursorStyle,
|
||||
cursor_blink: ?bool,
|
||||
cursor_color: ?configpkg.Config.Color,
|
||||
cursor_invert: bool,
|
||||
foreground: configpkg.Config.Color,
|
||||
background: configpkg.Config.Color,
|
||||
osc_color_report_format: configpkg.Config.OSCColorReportFormat,
|
||||
@ -103,6 +104,7 @@ 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",
|
||||
@ -176,8 +178,8 @@ 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_color) |col|
|
||||
col.toTerminalRGB()
|
||||
const default_cursor_color = if (!opts.config.cursor_invert and opts.config.cursor_color != null)
|
||||
opts.config.cursor_color.?.toTerminalRGB()
|
||||
else
|
||||
null;
|
||||
|
||||
|
@ -115,8 +115,8 @@ 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_color) |col|
|
||||
col.toTerminalRGB()
|
||||
self.default_cursor_color = if (!config.cursor_invert and config.cursor_color != null)
|
||||
config.cursor_color.?.toTerminalRGB()
|
||||
else
|
||||
null;
|
||||
|
||||
|
Reference in New Issue
Block a user