diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-30 20:05:16 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:17 -0300 |
| commit | 506ca99f13aec67d593e4a30bbe416dea176d0ba (patch) | |
| tree | df61a0d3846b45b3ef70d189c676dfa98975541c | |
| parent | 30378c63d752bf27d44f6a64738bab5a2cddc863 (diff) | |
| download | pardes-506ca99f13aec67d593e4a30bbe416dea176d0ba.tar.gz pardes-506ca99f13aec67d593e4a30bbe416dea176d0ba.zip | |
A ThemeFile that fails names its file: "theme file /x/mine.zon: file not found", not "theme file: file not found"
The read and parse failures come back after the write, often from a
relative name resolved against the config directory, so which file was
missing or bad was left to guess. They now carry the resolved path,
its middle cut when long.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
| -rw-r--r-- | src/colors.zig | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/src/colors.zig b/src/colors.zig index 8d541c13..b75cdc3d 100644 --- a/src/colors.zig +++ b/src/colors.zig @@ -759,7 +759,16 @@ pub fn themeFileRequest(p: *const Pardes, generation: u32) ?ThemeFileRequest { pub fn failThemeFile(p: *Pardes, generation: u32, err: anyerror) void { const request = themeFileRequest(p, generation) orelse return; - p.reportError(request.pane, "theme file", err); + themeFileError(p, request, err); +} + +/// A theme file's failure, said with its path: `theme file x.zon: file +/// not found`, not which file left to guess. +fn themeFileError(p: *Pardes, request: ThemeFileRequest, err: anyerror) void { + var said: [300]u8 = undefined; + var cut: [200]u8 = undefined; + const path = @import("ninep/tree.zig").fitErr(request.path, &cut); + p.reportError(request.pane, std.fmt.bufPrint(&said, "theme file {s}", .{path}) catch "theme file", err); } pub fn loadThemeFile(p: *Pardes, generation: u32, bytes: []const u8, animate: bool) bool { @@ -767,23 +776,23 @@ pub fn loadThemeFile(p: *Pardes, generation: u32, bytes: []const u8, animate: bo @setEvalBranchQuota(10000); const request = themeFileRequest(p, generation) orelse return false; if (bytes.len > 1024 * 1024) { - p.reportError(request.pane, "theme file", error.ThemeFileTooLarge); + themeFileError(p, request, error.ThemeFileTooLarge); return false; } const source = p.gpa.dupeZ(u8, bytes) catch |err| { - p.reportError(request.pane, "theme file", err); + themeFileError(p, request, err); return false; }; defer p.gpa.free(source); var diagnostics: std.zon.parse.Diagnostics = .{}; defer diagnostics.deinit(p.gpa); const parsed = std.zon.parse.fromSliceAlloc(Theme, p.gpa, source, &diagnostics, .{}) catch |err| { - p.reportError(request.pane, "theme file", err); + themeFileError(p, request, err); return false; }; if (parsed.name.len == 0 or parsed.name.len > 255) { std.zon.parse.free(p.gpa, parsed); - p.reportError(request.pane, "theme file", error.InvalidThemeName); + themeFileError(p, request, error.InvalidThemeName); return false; } @@ -912,6 +921,16 @@ pub fn setThemeIndex(p: *Pardes, index: usize) void { invalidateThemeDependentRasters(p); } +test "a theme file that cannot be read is named in the failure" { + if (platform == .web) return; + const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true }); + defer p.deinit(); + requestThemeFile(p, 0, "/nowhere/mine.zon"); + failThemeFile(p, p.theme_file_generation, error.FileNotFound); + const pane = p.panes[0].?; + try std.testing.expect(std.mem.indexOf(u8, pane.msg[0..pane.msg_len], "theme file /nowhere/mine.zon: ") != null); +} + test "ThemeFile parses ZON atomically and Theme returns to the compiled ring" { if (platform == .web) return; const p = try Pardes.init(std.testing.allocator, .{ |
