diff --git a/src/cli/list_fonts.zig b/src/cli/list_fonts.zig index 1b7c9bcb5..f34df3cf1 100644 --- a/src/cli/list_fonts.zig +++ b/src/cli/list_fonts.zig @@ -10,12 +10,39 @@ pub const Config = struct { /// This is set by the CLI parser for deinit. _arena: ?ArenaAllocator = null, + /// The font family to search for. If this is set, then only fonts + /// matching this family will be listed. + family: ?[:0]const u8 = null, + + /// Font styles to search for. If this is set, then only fonts that + /// match the given styles will be listed. + bold: bool = false, + italic: bool = false, + pub fn deinit(self: *Config) void { if (self._arena) |arena| arena.deinit(); self.* = undefined; } }; +/// The list-fonts command is used to list all the available fonts for Ghostty. +/// This uses the exact same font discovery mechanism Ghostty uses to find +/// fonts to use. +/// +/// When executed with no arguments, this will list all available fonts, +/// sorted by family name, then font name. If a family name is given +/// with "--family", the sorting will be disabled and the results instead +/// will be shown in the same priority order Ghostty would use to pick a +/// font. +/// +/// The "--family" argument can be used to filter results to a specific family. +/// The family handling is identical to the "font-familiy" set of Ghostty +/// configuration values, so this can be used to debug why your desired font +/// may not be loading. +/// +/// The "--bold" and "--italic" arguments can be used to filter results to +/// specific styles. It is not guaranteed that only those styles are returned, +/// it will just prioriiize fonts that match those styles. pub fn run(alloc: Allocator) !u8 { var iter = try std.process.argsWithAllocator(alloc); defer iter.deinit(); @@ -55,7 +82,11 @@ fn runArgs(alloc_gpa: Allocator, argsIter: anytype) !u8 { // Look up all available fonts var disco = font.Discover.init(); defer disco.deinit(); - var disco_it = try disco.discover(.{}); + var disco_it = try disco.discover(.{ + .family = config.family, + .bold = config.bold, + .italic = config.italic, + }); defer disco_it.deinit(); while (try disco_it.next()) |face| { var buf: [1024]u8 = undefined; @@ -81,21 +112,25 @@ fn runArgs(alloc_gpa: Allocator, argsIter: anytype) !u8 { } // Sort our keys. - std.mem.sortUnstable([]const u8, families.items, {}, struct { - fn lessThan(_: void, lhs: []const u8, rhs: []const u8) bool { - return std.mem.order(u8, lhs, rhs) == .lt; - } - }.lessThan); + if (config.family == null) { + std.mem.sortUnstable([]const u8, families.items, {}, struct { + fn lessThan(_: void, lhs: []const u8, rhs: []const u8) bool { + return std.mem.order(u8, lhs, rhs) == .lt; + } + }.lessThan); + } // Output each for (families.items) |family| { const list = map.get(family) orelse continue; if (list.items.len == 0) continue; - std.mem.sortUnstable([]const u8, list.items, {}, struct { - fn lessThan(_: void, lhs: []const u8, rhs: []const u8) bool { - return std.mem.order(u8, lhs, rhs) == .lt; - } - }.lessThan); + if (config.family == null) { + std.mem.sortUnstable([]const u8, list.items, {}, struct { + fn lessThan(_: void, lhs: []const u8, rhs: []const u8) bool { + return std.mem.order(u8, lhs, rhs) == .lt; + } + }.lessThan); + } try stdout.print("{s}\n", .{family}); for (list.items) |item| try stdout.print(" {s}\n", .{item});