cli/list-fonts

This commit is contained in:
Mitchell Hashimoto
2023-09-24 08:23:12 -07:00
parent 2fb14eee09
commit 11440a3a4c

View File

@ -22,10 +22,15 @@ pub fn run(alloc: Allocator) !u8 {
return try runArgs(alloc, &iter);
}
fn runArgs(alloc: Allocator, argsIter: anytype) !u8 {
fn runArgs(alloc_gpa: Allocator, argsIter: anytype) !u8 {
var config: Config = .{};
defer config.deinit();
try args.parse(Config, alloc, &config, argsIter);
try args.parse(Config, alloc_gpa, &config, argsIter);
// Use an arena for all our memory allocs
var arena = ArenaAllocator.init(alloc_gpa);
defer arena.deinit();
const alloc = arena.allocator();
// Its possible to build Ghostty without font discovery!
if (comptime font.Discover == void) {
@ -42,19 +47,57 @@ fn runArgs(alloc: Allocator, argsIter: anytype) !u8 {
const stdout = std.io.getStdOut().writer();
var disco = font.Discover.init();
defer disco.deinit();
// We'll be putting our fonts into a list categorized by family
// so it is easier to read the output.
var map = std.StringArrayHashMap(std.ArrayListUnmanaged([]const u8)).init(alloc);
// Look up all available fonts
var disco = font.Discover.init();
defer disco.deinit();
var disco_it = try disco.discover(.{});
defer disco_it.deinit();
while (try disco_it.next()) |face| {
var buf: [1024]u8 = undefined;
const name = face.name(&buf) catch |err| {
const family = face.familyName(&buf) catch |err| {
log.err("failed to get font family name: {}", .{err});
continue;
};
const gop = try map.getOrPut(try alloc.dupe(u8, family));
if (!gop.found_existing) {
gop.value_ptr.* = .{};
}
const full_name = face.name(&buf) catch |err| {
log.err("failed to get font name: {}", .{err});
continue;
};
try stdout.print("{s}\n", .{name});
try gop.value_ptr.append(alloc, try alloc.dupe(u8, full_name));
}
// Sort our keys.
std.mem.sortUnstable([]const u8, map.keys(), {}, struct {
fn lessThan(_: void, lhs: []const u8, rhs: []const u8) bool {
return std.mem.order(u8, lhs, rhs) == .lt;
}
}.lessThan);
try map.reIndex(); // Have to reindex since keys changed
// Output each
var it = map.iterator();
while (it.next()) |entry| {
var items = entry.value_ptr.items;
if (items.len == 0) continue;
std.mem.sortUnstable([]const u8, 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", .{entry.key_ptr.*});
for (items) |item| try stdout.print(" {s}\n", .{item});
try stdout.print("\n", .{});
}
return 0;