From f748b17e27f5ee089494044179dea1c493ce63cc Mon Sep 17 00:00:00 2001 From: phl Date: Sat, 15 Aug 2026 15:54:19 +0200 Subject: [PATCH] feat: expand tildes in config theme path to HOME When loading a theme from a path that includes a tilde: ``` theme="~/.cache/wal/colors-ghostty" ``` currently fails with the following error: ``` cannot include path separators unless it is an absolute path ``` This PR tries to expand the ~ of the path. If there is no ~ or expansion fails, it falls back to the unexpanded value. --- src/config/theme.zig | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/config/theme.zig b/src/config/theme.zig index a8c39cad9..0a3a8ecee 100644 --- a/src/config/theme.zig +++ b/src/config/theme.zig @@ -5,6 +5,8 @@ const internal_os = @import("../os/main.zig"); const cli = @import("../cli.zig"); const global = @import("../global.zig"); +const log = std.log.scoped(.config); + /// Location of possible themes. The order of this enum matters because it /// defines the priority of theme search (from top to bottom). pub const Location = enum { @@ -113,12 +115,40 @@ pub const LocationIterator = struct { /// will be added to the list and null will be returned. pub fn open( arena_alloc: Allocator, - theme: []const u8, + theme_: []const u8, diags: *cli.DiagnosticList, ) error{ OutOfMemory, Unexpected }!?struct { path: []const u8, file: std.Io.File, } { + var buf: [std.fs.max_path_bytes]u8 = undefined; + const theme = expanded: { + if (!std.mem.startsWith(u8, theme_, "~/")) + break :expanded theme_; + + var environ_map = global.environMap() catch |err| { + log.warn( + "error getting environment map when expanding theme path={s}: {}", + .{ theme_, err }, + ); + break :expanded theme_; + }; + defer environ_map.deinit(); + + break :expanded internal_os.expandHome( + global.io(), + &environ_map, + theme_, + &buf, + ) catch |err| { + log.warn( + "error expanding home directory for theme path={s}: {}", + .{ theme_, err }, + ); + break :expanded theme_; + }; + }; + // Absolute themes are loaded a different path. if (std.fs.path.isAbsolute(theme)) { const file: std.Io.File = try openAbsolute(