mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
Added bold-color option
This commit is contained in:

committed by
Mitchell Hashimoto

parent
04c5bb2984
commit
52790fb92c
@ -14,6 +14,7 @@ pub const entryFormatter = formatter.entryFormatter;
|
|||||||
pub const formatEntry = formatter.formatEntry;
|
pub const formatEntry = formatter.formatEntry;
|
||||||
|
|
||||||
// Field types
|
// Field types
|
||||||
|
pub const BoldColor = Config.BoldColor;
|
||||||
pub const ClipboardAccess = Config.ClipboardAccess;
|
pub const ClipboardAccess = Config.ClipboardAccess;
|
||||||
pub const Command = Config.Command;
|
pub const Command = Config.Command;
|
||||||
pub const ConfirmCloseSurface = Config.ConfirmCloseSurface;
|
pub const ConfirmCloseSurface = Config.ConfirmCloseSurface;
|
||||||
|
@ -69,6 +69,10 @@ pub const compatibility = std.StaticStringMap(
|
|||||||
// this behavior. This applies to selection too.
|
// this behavior. This applies to selection too.
|
||||||
.{ "cursor-invert-fg-bg", compatCursorInvertFgBg },
|
.{ "cursor-invert-fg-bg", compatCursorInvertFgBg },
|
||||||
.{ "selection-invert-fg-bg", compatSelectionInvertFgBg },
|
.{ "selection-invert-fg-bg", compatSelectionInvertFgBg },
|
||||||
|
|
||||||
|
// Ghostty 1.2 merged `bold-is-bright` into the new `bold-color`
|
||||||
|
// by setting the value to "bright".
|
||||||
|
.{ "bold-is-bright", compatBoldIsBright },
|
||||||
});
|
});
|
||||||
|
|
||||||
/// The font families to use.
|
/// The font families to use.
|
||||||
@ -2804,8 +2808,24 @@ else
|
|||||||
/// notifications using certain escape sequences such as OSC 9 or OSC 777.
|
/// notifications using certain escape sequences such as OSC 9 or OSC 777.
|
||||||
@"desktop-notifications": bool = true,
|
@"desktop-notifications": bool = true,
|
||||||
|
|
||||||
/// If `true`, the bold text will use the bright color palette.
|
/// Modifies the color used for bold text in the terminal.
|
||||||
@"bold-is-bright": bool = false,
|
///
|
||||||
|
/// This can be set to a specific color, using the same format as
|
||||||
|
/// `background` or `foreground` (e.g. `#RRGGBB` but other formats
|
||||||
|
/// are also supported; see the aforementioned documentation). If a
|
||||||
|
/// specific color is set, this color will always be used for all
|
||||||
|
/// bold text regardless of the terminal's color scheme.
|
||||||
|
///
|
||||||
|
/// This can also be set to `bright`, which uses the bright color palette
|
||||||
|
/// for bold text. For example, if the text is red, then the bold will
|
||||||
|
/// use the bright red color. The terminal palette is set with `palette`
|
||||||
|
/// but can also be overridden by the terminal application itself using
|
||||||
|
/// escape sequences such as OSC 4. (Since Ghostty 1.2.0, the previous
|
||||||
|
/// configuration `bold-is-bright` is deprecated and replaced by this
|
||||||
|
/// usage).
|
||||||
|
///
|
||||||
|
/// Available since Ghostty 1.2.0.
|
||||||
|
@"bold-color": ?BoldColor = null,
|
||||||
|
|
||||||
/// This will be used to set the `TERM` environment variable.
|
/// This will be used to set the `TERM` environment variable.
|
||||||
/// HACK: We set this with an `xterm` prefix because vim uses that to enable key
|
/// HACK: We set this with an `xterm` prefix because vim uses that to enable key
|
||||||
@ -3910,6 +3930,23 @@ fn compatSelectionInvertFgBg(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compatBoldIsBright(
|
||||||
|
self: *Config,
|
||||||
|
alloc: Allocator,
|
||||||
|
key: []const u8,
|
||||||
|
value_: ?[]const u8,
|
||||||
|
) bool {
|
||||||
|
_ = alloc;
|
||||||
|
assert(std.mem.eql(u8, key, "bold-is-bright"));
|
||||||
|
|
||||||
|
const set = cli.args.parseBool(value_ orelse "t") catch return false;
|
||||||
|
if (set) {
|
||||||
|
self.@"bold-color" = .bright;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a shallow copy of this config. This will share all the memory
|
/// Create a shallow copy of this config. This will share all the memory
|
||||||
/// allocated with the previous config but will have a new arena for
|
/// allocated with the previous config but will have a new arena for
|
||||||
/// any changes or new allocations. The config should have `deinit`
|
/// any changes or new allocations. The config should have `deinit`
|
||||||
@ -4537,6 +4574,58 @@ pub const TerminalColor = union(enum) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Represents color values that can be used for bold. See `bold-color`.
|
||||||
|
pub const BoldColor = union(enum) {
|
||||||
|
color: Color,
|
||||||
|
bright,
|
||||||
|
|
||||||
|
pub fn parseCLI(input_: ?[]const u8) !BoldColor {
|
||||||
|
const input = input_ orelse return error.ValueRequired;
|
||||||
|
if (std.mem.eql(u8, input, "bright")) return .bright;
|
||||||
|
return .{ .color = try Color.parseCLI(input) };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Used by Formatter
|
||||||
|
pub fn formatEntry(self: BoldColor, formatter: anytype) !void {
|
||||||
|
switch (self) {
|
||||||
|
.color => try self.color.formatEntry(formatter),
|
||||||
|
.bright => try formatter.formatEntry(
|
||||||
|
[:0]const u8,
|
||||||
|
@tagName(self),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "parseCLI" {
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
try testing.expectEqual(
|
||||||
|
BoldColor{ .color = Color{ .r = 78, .g = 42, .b = 132 } },
|
||||||
|
try BoldColor.parseCLI("#4e2a84"),
|
||||||
|
);
|
||||||
|
try testing.expectEqual(
|
||||||
|
BoldColor{ .color = Color{ .r = 0, .g = 0, .b = 0 } },
|
||||||
|
try BoldColor.parseCLI("black"),
|
||||||
|
);
|
||||||
|
try testing.expectEqual(
|
||||||
|
BoldColor.bright,
|
||||||
|
try BoldColor.parseCLI("bright"),
|
||||||
|
);
|
||||||
|
|
||||||
|
try testing.expectError(error.InvalidValue, BoldColor.parseCLI("a"));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "formatConfig" {
|
||||||
|
const testing = std.testing;
|
||||||
|
var buf = std.ArrayList(u8).init(testing.allocator);
|
||||||
|
defer buf.deinit();
|
||||||
|
|
||||||
|
var sc: BoldColor = .bright;
|
||||||
|
try sc.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
|
||||||
|
try testing.expectEqualSlices(u8, "a = bright\n", buf.items);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
pub const ColorList = struct {
|
pub const ColorList = struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
@ -8236,3 +8325,23 @@ test "compatibility: removed selection-invert-fg-bg" {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "compatibility: removed bold-is-bright" {
|
||||||
|
const testing = std.testing;
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
|
{
|
||||||
|
var cfg = try Config.default(alloc);
|
||||||
|
defer cfg.deinit();
|
||||||
|
var it: TestIterator = .{ .data = &.{
|
||||||
|
"--bold-is-bright",
|
||||||
|
} };
|
||||||
|
try cfg.loadIter(alloc, &it);
|
||||||
|
try cfg.finalize();
|
||||||
|
|
||||||
|
try testing.expectEqual(
|
||||||
|
BoldColor.bright,
|
||||||
|
cfg.@"bold-color",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -519,7 +519,7 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
|
|||||||
foreground: terminal.color.RGB,
|
foreground: terminal.color.RGB,
|
||||||
selection_background: ?configpkg.Config.TerminalColor,
|
selection_background: ?configpkg.Config.TerminalColor,
|
||||||
selection_foreground: ?configpkg.Config.TerminalColor,
|
selection_foreground: ?configpkg.Config.TerminalColor,
|
||||||
bold_is_bright: bool,
|
bold_color: ?configpkg.BoldColor,
|
||||||
min_contrast: f32,
|
min_contrast: f32,
|
||||||
padding_color: configpkg.WindowPaddingColor,
|
padding_color: configpkg.WindowPaddingColor,
|
||||||
custom_shaders: configpkg.RepeatablePath,
|
custom_shaders: configpkg.RepeatablePath,
|
||||||
@ -580,7 +580,8 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
|
|||||||
|
|
||||||
.background = config.background.toTerminalRGB(),
|
.background = config.background.toTerminalRGB(),
|
||||||
.foreground = config.foreground.toTerminalRGB(),
|
.foreground = config.foreground.toTerminalRGB(),
|
||||||
.bold_is_bright = config.@"bold-is-bright",
|
.bold_color = config.@"bold-color",
|
||||||
|
|
||||||
.min_contrast = @floatCast(config.@"minimum-contrast"),
|
.min_contrast = @floatCast(config.@"minimum-contrast"),
|
||||||
.padding_color = config.@"window-padding-color",
|
.padding_color = config.@"window-padding-color",
|
||||||
|
|
||||||
@ -2540,10 +2541,11 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
|
|||||||
// the cell style (SGR), before applying any additional
|
// the cell style (SGR), before applying any additional
|
||||||
// configuration, inversions, selections, etc.
|
// configuration, inversions, selections, etc.
|
||||||
const bg_style = style.bg(cell, color_palette);
|
const bg_style = style.bg(cell, color_palette);
|
||||||
const fg_style = style.fg(
|
const fg_style = style.fg(.{
|
||||||
color_palette,
|
.default = self.foreground_color orelse self.default_foreground_color,
|
||||||
self.config.bold_is_bright,
|
.palette = color_palette,
|
||||||
) orelse self.foreground_color orelse self.default_foreground_color;
|
.bold = self.config.bold_color,
|
||||||
|
});
|
||||||
|
|
||||||
// The final background color for the cell.
|
// The final background color for the cell.
|
||||||
const bg = bg: {
|
const bg = bg: {
|
||||||
@ -2801,10 +2803,11 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
|
|||||||
.@"cell-background",
|
.@"cell-background",
|
||||||
=> |_, tag| {
|
=> |_, tag| {
|
||||||
const sty = screen.cursor.page_pin.style(screen.cursor.page_cell);
|
const sty = screen.cursor.page_pin.style(screen.cursor.page_cell);
|
||||||
const fg_style = sty.fg(
|
const fg_style = sty.fg(.{
|
||||||
color_palette,
|
.default = self.foreground_color orelse self.default_foreground_color,
|
||||||
self.config.bold_is_bright,
|
.palette = color_palette,
|
||||||
) orelse self.foreground_color orelse self.default_foreground_color;
|
.bold = self.config.bold_color,
|
||||||
|
});
|
||||||
const bg_style = sty.bg(
|
const bg_style = sty.bg(
|
||||||
screen.cursor.page_cell,
|
screen.cursor.page_cell,
|
||||||
color_palette,
|
color_palette,
|
||||||
@ -2852,7 +2855,11 @@ pub fn Renderer(comptime GraphicsAPI: type) type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const sty = screen.cursor.page_pin.style(screen.cursor.page_cell);
|
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 fg_style = sty.fg(.{
|
||||||
|
.default = self.foreground_color orelse self.default_foreground_color,
|
||||||
|
.palette = color_palette,
|
||||||
|
.bold = self.config.bold_color,
|
||||||
|
});
|
||||||
const bg_style = sty.bg(screen.cursor.page_cell, color_palette) orelse self.background_color orelse self.default_background_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) {
|
break :blk switch (txt) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
|
const configpkg = @import("../config.zig");
|
||||||
const color = @import("color.zig");
|
const color = @import("color.zig");
|
||||||
const sgr = @import("sgr.zig");
|
const sgr = @import("sgr.zig");
|
||||||
const page = @import("page.zig");
|
const page = @import("page.zig");
|
||||||
@ -115,24 +116,68 @@ pub const Style = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the fg color for a cell with this style given the palette.
|
pub const Fg = struct {
|
||||||
|
/// The default color to use if the style doesn't specify a
|
||||||
|
/// foreground color and no configuration options override
|
||||||
|
/// it.
|
||||||
|
default: color.RGB,
|
||||||
|
|
||||||
|
/// The current color palette. Required to map palette indices to
|
||||||
|
/// real color values.
|
||||||
|
palette: *const color.Palette,
|
||||||
|
|
||||||
|
/// If specified, the color to use for bold text.
|
||||||
|
bold: ?configpkg.BoldColor = null,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Returns the fg color for a cell with this style given the palette
|
||||||
|
/// and various configuration options.
|
||||||
pub fn fg(
|
pub fn fg(
|
||||||
self: Style,
|
self: Style,
|
||||||
palette: *const color.Palette,
|
opts: Fg,
|
||||||
bold_is_bright: bool,
|
) color.RGB {
|
||||||
) ?color.RGB {
|
// Note we don't pull the bold check to the top-level here because
|
||||||
|
// we don't want to duplicate the conditional multiple times since
|
||||||
|
// certain colors require more checks (e.g. `bold_is_bright`).
|
||||||
|
|
||||||
return switch (self.fg_color) {
|
return switch (self.fg_color) {
|
||||||
.none => null,
|
.none => default: {
|
||||||
.palette => |idx| palette: {
|
if (self.flags.bold) {
|
||||||
if (bold_is_bright and self.flags.bold) {
|
if (opts.bold) |bold| switch (bold) {
|
||||||
const bright_offset = @intFromEnum(color.Name.bright_black);
|
.bright => {},
|
||||||
if (idx < bright_offset)
|
.color => |v| break :default v.toTerminalRGB(),
|
||||||
break :palette palette[idx + bright_offset];
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
break :palette palette[idx];
|
break :default opts.default;
|
||||||
|
},
|
||||||
|
|
||||||
|
.palette => |idx| palette: {
|
||||||
|
if (self.flags.bold) {
|
||||||
|
if (opts.bold) |bold| switch (bold) {
|
||||||
|
.color => |v| break :palette v.toTerminalRGB(),
|
||||||
|
.bright => {
|
||||||
|
const bright_offset = @intFromEnum(color.Name.bright_black);
|
||||||
|
if (idx < bright_offset) {
|
||||||
|
break :palette opts.palette[idx + bright_offset];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
break :palette opts.palette[idx];
|
||||||
|
},
|
||||||
|
|
||||||
|
.rgb => |rgb| rgb: {
|
||||||
|
if (self.flags.bold and rgb.eql(opts.default)) {
|
||||||
|
if (opts.bold) |bold| switch (bold) {
|
||||||
|
.color => |v| break :rgb v.toTerminalRGB(),
|
||||||
|
.bright => {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
break :rgb rgb;
|
||||||
},
|
},
|
||||||
.rgb => |rgb| rgb,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user