diff options
Diffstat (limited to 'src/config.zig')
| -rw-r--r-- | src/config.zig | 73 |
1 files changed, 54 insertions, 19 deletions
diff --git a/src/config.zig b/src/config.zig index 592281d3..6bb4d6e4 100644 --- a/src/config.zig +++ b/src/config.zig @@ -1242,6 +1242,22 @@ pub const Runtime = struct { }; } + /// What a setting takes, for a refusal of a bad value to name: its + /// words (`choices`), else its range or the kind of thing it takes. + pub fn takes(action: Action) ?[]const u8 { + return choices(action) orelse switch (action) { + .inactive_dim, .window_opacity, .window_blur => "0-100 (a percentage)", + .grip_width => "50-300 (a percentage)", + .tagline_size => std.fmt.comptimePrint("{d}-{d} (a percentage)", .{ tagline_percent_min, tagline_percent_max }), + .message_ms => std.fmt.comptimePrint("0-{d} (milliseconds)", .{message_ms_max}), + .shell => "a path of at most 255 bytes; bare, the login shell", + .dump_dir => std.fmt.comptimePrint("a path of at most {d} bytes; bare, the default", .{limits.host_path_cap}), + .shader => "a Shadertoy file's path, or off", + .font => "a name or path, :8 to :72 after it (Mono:14)", + else => null, + }; + } + /// The value a choice word names, or bare, the one after `now`; null for /// a word it does not take. fn stepped(comptime T: type, now: T, argument: ?[]const u8) ?T { @@ -1267,6 +1283,9 @@ pub const Runtime = struct { startup_config_path: ?[]const u8, platform: []const u8, theme_name: []const u8, + /// The ThemeFile in effect, said as `ThemeFile <path>` in place + /// of the theme's name. + theme_file: ?[]const u8 = null, compiled_default_shell: []const u8, hover_delay_frames: ?u16, /// Where dumps go when `DumpDir` is unset; empty without a host @@ -1288,8 +1307,8 @@ pub const Runtime = struct { } /// Each setting line reads as the command that would set it: the word, - /// then the value you would type after it (`unsupported` where this - /// shell has no such setting). No colons, no units: `WindowOpacity 70` + /// then the value you would type after it (a `# Word unsupported` + /// comment where this shell has no such setting). No colons, no units: `WindowOpacity 70` /// is both what DumpConfig prints and what you write back. What is in /// effect but set by no word follows, after a blank line. pub fn writeReport(out: *std.Io.Writer, context: ReportContext) !void { @@ -1297,7 +1316,7 @@ pub const Runtime = struct { for (settings) |setting| switch (setting.action) { .toggle => |field| { if (!setting.enabled(context.capabilities)) { - try out.print("{s} unsupported\n", .{setting.word}); + try out.print("# {s} unsupported\n", .{setting.word}); continue; } const value = switch (field) { @@ -1305,22 +1324,25 @@ pub const Runtime = struct { }; try out.print("{s} {s}\n", .{ setting.word, onOff(value) }); }, - .theme => try out.print("{s} {s}\n", .{ setting.word, context.theme_name }), + .theme => if (context.theme_file) |path| + try out.print("ThemeFile {s}\n", .{path}) + else + try out.print("{s} {s}\n", .{ setting.word, context.theme_name }), .window_opacity => { if (setting.enabled(context.capabilities)) try out.print("{s} {d}\n", .{ setting.word, state.window_opacity }) else - try out.print("{s} unsupported\n", .{setting.word}); + try out.print("# {s} unsupported\n", .{setting.word}); }, .window_blur => { if (setting.enabled(context.capabilities)) try out.print("{s} {d}\n", .{ setting.word, state.window_blur }) else - try out.print("{s} unsupported\n", .{setting.word}); + try out.print("# {s} unsupported\n", .{setting.word}); }, .dump_dir => { const dir = if (state.dump_dir.len > 0) state.dump_dir.get() else context.default_dump_dir; - try out.print("{s} {s}\n", .{ setting.word, if (dir.len > 0) dir else "(none)" }); + if (dir.len > 0) try out.print("{s} {s}\n", .{ setting.word, dir }) else try out.print("# {s} (none)\n", .{setting.word}); }, .message_ms => |which| try out.print("{s} {d}\n", .{ setting.word, switch (which) { inline else => |w| @field(state, "message_" ++ @tagName(w) ++ "_ms"), @@ -1330,28 +1352,34 @@ pub const Runtime = struct { try out.print("{s} {s}\n", .{ setting.word, if (chosen.len == 0) context.compiled_default_shell else chosen }); }, .font => if (!setting.enabled(context.capabilities)) - try out.print("{s} unsupported\n", .{setting.word}) + try out.print("# {s} unsupported\n", .{setting.word}) else { // As `Font` takes it, `name:size`: the one asked for, else // the one in use. const f = &state.font; const name = if (f.requested_path.get().len > 0) f.requested_path.get() else if (f.requested_name.get().len > 0) f.requested_name.get() else f.effective_name.get(); + // None known yet (no font loaded): a comment, as `Font` + // alone is no line a ctl takes. + if (name.len == 0) { + try out.print("# {s} (none yet)\n", .{setting.word}); + continue; + } try out.print("{s} {s}", .{ setting.word, name }); if (f.requested_size_hundredths != 0) try out.print(":{d}.{d:0>2}", .{ f.requested_size_hundredths / 100, f.requested_size_hundredths % 100 }); try out.writeByte('\n'); }, .tagline_size => if (!context.capabilities.tagline_font_size) - try out.print("{s} unsupported\n", .{setting.word}) + try out.print("# {s} unsupported\n", .{setting.word}) else try out.print("{s} {d}\n", .{ setting.word, state.font.tagline_percent }), // Each a switch of its own, the one in use on. .transition => |transition| if (!setting.enabled(context.capabilities)) - try out.print("{s} unsupported\n", .{setting.word}) + try out.print("# {s} unsupported\n", .{setting.word}) else try out.print("{s} {s}\n", .{ setting.word, onOff(state.panel_transition == transition) }), .scene => |effect| { if (!setting.enabled(context.capabilities)) { - try out.print("{s} unsupported\n", .{setting.word}); + try out.print("# {s} unsupported\n", .{setting.word}); continue; } const level = state.post.level(effect); @@ -1359,7 +1387,7 @@ pub const Runtime = struct { }, .shader => { if (!setting.enabled(context.capabilities)) { - try out.print("{s} unsupported\n", .{setting.word}); + try out.print("# {s} unsupported\n", .{setting.word}); continue; } var files: usize = 0; @@ -1372,17 +1400,20 @@ pub const Runtime = struct { .shader_animation => if (setting.enabled(context.capabilities)) try out.print("{s} {s}\n", .{ setting.word, @tagName(state.shader_animation) }) else - try out.print("{s} unsupported\n", .{setting.word}), + try out.print("# {s} unsupported\n", .{setting.word}), .choice => |which| switch (which) { inline else => |field| try out.print("{s} {s}\n", .{ setting.word, @tagName(@field(state, @tagName(field))) }), }, .lift => if (setting.enabled(context.capabilities)) try out.print("{s} {s}\n", .{ setting.word, @tagName(state.lift) }) else - try out.print("{s} unsupported\n", .{setting.word}), + try out.print("# {s} unsupported\n", .{setting.word}), .motion => try out.print("{s} {s}\n", .{ setting.word, @tagName(state.motion) }), .inactive_dim => try out.print("{s} {d}\n", .{ setting.word, state.inactive_dim }), - .grip_width => try out.print("{s} {d}\n", .{ setting.word, state.grip_width }), + .grip_width => if (setting.enabled(context.capabilities)) + try out.print("{s} {d}\n", .{ setting.word, state.grip_width }) + else + try out.print("# {s} unsupported\n", .{setting.word}), }; if (context.locations.len > 0) try out.print("LocationsConfig {s}\n", .{context.locations}); @@ -1805,12 +1836,16 @@ pub const Runtime = struct { try std.testing.expect(std.mem.indexOf(u8, defaults_report, "TaglineSize unsupported\n") != null); try std.testing.expect(std.mem.indexOf(u8, defaults_report, "# Look hover delay: off\n") != null); try std.testing.expect(std.mem.indexOf(u8, defaults_report, "# Native images: off\n") != null); - // A setting this shell does not have reads so, as a line to write. - try std.testing.expect(std.mem.indexOf(u8, defaults_report, "Ligatures unsupported\n") != null); - // Every line before the blank one is a ctl word and its value. + // A setting this shell does not have reads so, as a comment. + try std.testing.expect(std.mem.indexOf(u8, defaults_report, "# Ligatures unsupported\n") != null); + // Every line before the blank one is a ctl word and its value, or a + // comment naming one. const words = defaults_report[0..std.mem.indexOf(u8, defaults_report, "\n\n").?]; var lines = std.mem.splitScalar(u8, words, '\n'); - while (lines.next()) |line| try std.testing.expect(find(line[0..std.mem.indexOfScalar(u8, line, ' ').?]) != null); + while (lines.next()) |line| { + const word = if (std.mem.startsWith(u8, line, "# ")) line[2..] else line; + try std.testing.expect(find(word[0..std.mem.indexOfScalar(u8, word, ' ').?]) != null); + } // ...and every one after it a `#` line, which runs as nothing. var info = std.mem.splitScalar(u8, std.mem.trimEnd(u8, defaults_report[words.len + 2 ..], "\n"), '\n'); while (info.next()) |line| try std.testing.expect(std.mem.startsWith(u8, line, "# ")); |
