mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 16:26:08 +03:00
config: load themes
This commit is contained in:
@ -7,6 +7,7 @@ const builtin = @import("builtin");
|
||||
const assert = std.debug.assert;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const ArenaAllocator = std.heap.ArenaAllocator;
|
||||
const global_state = &@import("../main.zig").state;
|
||||
const fontpkg = @import("../font/main.zig");
|
||||
const inputpkg = @import("../input.zig");
|
||||
const terminal = @import("../terminal/main.zig");
|
||||
@ -1326,7 +1327,85 @@ fn expandPaths(self: *Config, base: []const u8) !void {
|
||||
}
|
||||
}
|
||||
|
||||
fn loadTheme(self: *Config, theme: []const u8) !void {
|
||||
const alloc = self._arena.?.allocator();
|
||||
const resources_dir = global_state.resources_dir orelse {
|
||||
try self._errors.add(alloc, .{
|
||||
.message = "no resources directory found, themes will not work",
|
||||
});
|
||||
return;
|
||||
};
|
||||
|
||||
const path = try std.fs.path.join(alloc, &.{
|
||||
resources_dir,
|
||||
"themes",
|
||||
theme,
|
||||
});
|
||||
|
||||
const cwd = std.fs.cwd();
|
||||
var file = cwd.openFile(path, .{}) catch |err| {
|
||||
switch (err) {
|
||||
error.FileNotFound => try self._errors.add(alloc, .{
|
||||
.message = try std.fmt.allocPrintZ(
|
||||
alloc,
|
||||
"theme \"{s}\" not found, path={s}",
|
||||
.{ theme, path },
|
||||
),
|
||||
}),
|
||||
|
||||
else => try self._errors.add(alloc, .{
|
||||
.message = try std.fmt.allocPrintZ(
|
||||
alloc,
|
||||
"failed to load theme \"{s}\": {}",
|
||||
.{ theme, err },
|
||||
),
|
||||
}),
|
||||
}
|
||||
return;
|
||||
};
|
||||
defer file.close();
|
||||
|
||||
// From this point onwards, we load the theme and do a bit of a dance
|
||||
// to achive two separate goals:
|
||||
//
|
||||
// (1) We want the theme to be loaded and our existing config to
|
||||
// override the theme. So we need to load the theme and apply
|
||||
// our config on top of it.
|
||||
//
|
||||
// (2) We want to free existing memory that we aren't using anymore
|
||||
// as a result of reloading the configuration.
|
||||
//
|
||||
// Point 2 is strictly a result of aur approach to point 1.
|
||||
|
||||
// Keep track of our input length prior ot loading the theme
|
||||
// so that we can replay the previous config to override values.
|
||||
const input_len = self._inputs.items.len;
|
||||
|
||||
// Load into a new configuration so that we can free the existing memory.
|
||||
const alloc_gpa = self._arena.?.child_allocator;
|
||||
var new_config = try default(alloc_gpa);
|
||||
errdefer new_config.deinit();
|
||||
|
||||
// Load our theme
|
||||
var buf_reader = std.io.bufferedReader(file.reader());
|
||||
var iter = cli.args.lineIterator(buf_reader.reader());
|
||||
try new_config.loadIter(alloc_gpa, &iter);
|
||||
|
||||
// Replay our previous inputs so that we can override values
|
||||
// from the theme.
|
||||
var slice_it = cli.args.sliceIterator(self._inputs.items[0..input_len]);
|
||||
try new_config.loadIter(alloc_gpa, &slice_it);
|
||||
|
||||
// Success, swap our new config in and free the old.
|
||||
self.deinit();
|
||||
self.* = new_config;
|
||||
}
|
||||
|
||||
pub fn finalize(self: *Config) !void {
|
||||
// We always load the theme first because it may set other fields
|
||||
// in our config.
|
||||
if (self.theme) |theme| try self.loadTheme(theme);
|
||||
|
||||
// If we have a font-family set and don't set the others, default
|
||||
// the others to the font family. This way, if someone does
|
||||
// --font-family=foo, then we try to get the stylized versions of
|
||||
|
Reference in New Issue
Block a user