diff options
Diffstat (limited to 'src/config.zig')
| -rw-r--r-- | src/config.zig | 83 |
1 files changed, 53 insertions, 30 deletions
diff --git a/src/config.zig b/src/config.zig index 8c37a7ce..f898df11 100644 --- a/src/config.zig +++ b/src/config.zig @@ -705,15 +705,6 @@ pub const Runtime = struct { action: Action, availability: ?Capability = null, - pub fn takesArg(setting: Setting) bool { - return switch (setting.action) { - // A toggle flips when it is a bare tagline word and SETS when - // it is given `on` or `off`, so the report is configuration. - .shell, .theme, .font, .tagline_size, .window_opacity, .window_blur, .message_ms, .dump_dir, .toggle => true, - else => false, - }; - } - pub fn enabled(setting: Setting, capabilities: Capabilities) bool { const capability = setting.availability orelse return true; return switch (capability) { @@ -831,15 +822,7 @@ pub const Runtime = struct { // it SETS, so the report `writeReport` prints (`Verbose on`) can // be fed straight back as configuration and mean what it says. .toggle => |field| { - const text = std.mem.trim(u8, argument orelse "", " \t\r\n"); - const want: ?bool = if (text.len == 0) - null - else if (std.mem.eql(u8, text, "on")) - true - else if (std.mem.eql(u8, text, "off")) - false - else - return false; + const want = switchedTo(argument) catch return false; switch (field) { inline else => |f| @field(state, @tagName(f)) = want orelse !@field(state, @tagName(f)), } @@ -881,18 +864,42 @@ pub const Runtime = struct { inline else => |w| @field(state, "message_" ++ @tagName(w) ++ "_ms") = ms, } }, - .transition => |effect| state.toggleTransition(effect), - .scene => |effect| switch (effect) { - inline else => |field| { - const value = &@field(state.scene_effects, @tagName(field)); - value.* = !value.*; - }, + // Panel effects are one choice, so `on` picks this one and `off` + // turns it off only if it is the one on. + .transition => |effect| { + const want = switchedTo(argument) catch return false; + if (want == null) { + state.toggleTransition(effect); + } else if (want.?) { + state.panel_transition = effect; + } else if (state.panel_transition == effect) { + state.panel_transition = .off; + } + }, + .scene => |effect| { + const want = switchedTo(argument) catch return false; + switch (effect) { + inline else => |field| { + const value = &@field(state.scene_effects, @tagName(field)); + value.* = want orelse !value.*; + }, + } }, .theme, .font => return false, } return true; } + /// What `on`, `off` or nothing after a switch word asks for: null flips + /// it, as a bare tagline word does. + fn switchedTo(argument: ?[]const u8) error{NotOnOrOff}!?bool { + const text = std.mem.trim(u8, argument orelse "", " \t\r\n"); + if (text.len == 0) return null; + if (std.mem.eql(u8, text, "on")) return true; + if (std.mem.eql(u8, text, "off")) return false; + return error.NotOnOrOff; + } + // Slices are borrowed for one writeReport call. pub const ReportContext = struct { startup_config_path: ?[]const u8, @@ -1055,15 +1062,32 @@ pub const Runtime = struct { try out.print("Pet: {s}\n", .{@tagName(state.pet)}); } - test "setting names are unique and argument metadata follows actions" { + test "setting names are unique" { for (settings, 0..) |setting, i| { try std.testing.expect(setting.word.len > 0); for (settings[i + 1 ..]) |later| try std.testing.expect(!std.mem.eql(u8, setting.word, later.word)); - try std.testing.expectEqual(switch (setting.action) { - .shell, .theme, .font, .tagline_size, .window_opacity, .window_blur, .message_ms, .dump_dir, .toggle => true, - else => false, - }, setting.takesArg()); + } + } + + test "panel and scene effects flip bare and are set by on and off" { + var state: Runtime = .{}; + const slide = findAction(.{ .transition = .slide }).?; + const zoom = findAction(.{ .transition = .zoom }).?; + try std.testing.expect(apply(&state, slide, "on")); + try std.testing.expectEqual(layout.Transition.slide, state.panel_transition); + try std.testing.expect(apply(&state, zoom, "off")); + try std.testing.expectEqual(layout.Transition.slide, state.panel_transition); + try std.testing.expect(apply(&state, slide, "on")); + try std.testing.expectEqual(layout.Transition.slide, state.panel_transition); + try std.testing.expect(apply(&state, slide, null)); + try std.testing.expectEqual(layout.Transition.off, state.panel_transition); + try std.testing.expect(!apply(&state, slide, "yes")); + const scene = findAction(.{ .scene = std.enums.values(Scene)[0] }).?; + try std.testing.expect(apply(&state, scene, "on")); + try std.testing.expect(apply(&state, scene, "on")); + switch (std.enums.values(Scene)[0]) { + inline else => |f| try std.testing.expect(@field(state.scene_effects, @tagName(f))), } } @@ -1125,7 +1149,6 @@ pub const Runtime = struct { var state: Runtime = .{}; try std.testing.expectEqual(@as(u8, 100), state.window_opacity); try std.testing.expect(state.window_opacity_pending); - try std.testing.expect(setting.takesArg()); try std.testing.expectEqual(Capability.window_opacity, setting.availability.?); for ([_][]const u8{ "0", " 85\n", "100" }, [_]u8{ 0, 85, 100 }) |argument, expected| { |
