mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 00:36:07 +03:00
config: load themes
This commit is contained in:
@ -7,6 +7,7 @@ const builtin = @import("builtin");
|
|||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const ArenaAllocator = std.heap.ArenaAllocator;
|
const ArenaAllocator = std.heap.ArenaAllocator;
|
||||||
|
const global_state = &@import("../main.zig").state;
|
||||||
const fontpkg = @import("../font/main.zig");
|
const fontpkg = @import("../font/main.zig");
|
||||||
const inputpkg = @import("../input.zig");
|
const inputpkg = @import("../input.zig");
|
||||||
const terminal = @import("../terminal/main.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 {
|
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
|
// 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
|
// the others to the font family. This way, if someone does
|
||||||
// --font-family=foo, then we try to get the stylized versions of
|
// --font-family=foo, then we try to get the stylized versions of
|
||||||
|
Reference in New Issue
Block a user