summaryrefslogtreecommitdiff
path: root/src/config.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-28 23:11:08 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:15 -0300
commit8b2a55f31169ede82e11a573ab655e72e7831fe7 (patch)
treed0e14b6abc79e7a6fd0d60af587fc47f331e8f64 /src/config.zig
parent7e6e5e803c6ec2e203b094b2a64291840c5e6aed (diff)
downloadpardes-8b2a55f31169ede82e11a573ab655e72e7831fe7.tar.gz
pardes-8b2a55f31169ede82e11a573ab655e72e7831fe7.zip
A choice setting's refusal names what it takes, and /commands lists them
Bare Placement and BootShell flip, which is pardes's convention for a word that chooses (Crt does too), but nothing said so, and "bad value in control message" never said what would do. A refused value now says `takes acme, pardes` (every switch and choice setting), /commands lists each such setting's values in a fourth field, and config.md and fs.md say that bare steps to the next. Motion and ShaderAnimation stepped nowhere bare and now step like the rest. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/config.zig')
-rw-r--r--src/config.zig51
1 files changed, 37 insertions, 14 deletions
diff --git a/src/config.zig b/src/config.zig
index 24c48770..234d8cae 100644
--- a/src/config.zig
+++ b/src/config.zig
@@ -1104,20 +1104,12 @@ pub const Runtime = struct {
}
return state.post.set(null, path, null);
},
- .shader_animation => {
- const text = std.mem.trim(u8, argument orelse return false, " \t\r\n");
- state.shader_animation = std.meta.stringToEnum(ShaderAnimation, text) orelse return false;
- },
+ .shader_animation => state.shader_animation = stepped(ShaderAnimation, state.shader_animation, argument) orelse return false,
// Bare, it steps to the next word, as a tag word should.
.choice => |which| switch (which) {
inline else => |field| {
const now = &@field(state, @tagName(field));
- const T = @TypeOf(now.*);
- const text = std.mem.trim(u8, argument orelse "", " \t\r\n");
- now.* = if (text.len == 0)
- @enumFromInt((@as(usize, @intFromEnum(now.*)) + 1) % std.enums.values(T).len)
- else
- std.meta.stringToEnum(T, text) orelse return false;
+ now.* = stepped(@TypeOf(now.*), now.*, argument) orelse return false;
},
},
.lift => {
@@ -1129,10 +1121,7 @@ pub const Runtime = struct {
else
std.meta.stringToEnum(LiftStyle, text) orelse return false;
},
- .motion => {
- const text = std.mem.trim(u8, argument orelse return false, " \t\r\n");
- state.motion = std.meta.stringToEnum(animation.Motion.Flavour, text) orelse return false;
- },
+ .motion => state.motion = stepped(animation.Motion.Flavour, state.motion, argument) orelse return false,
.inactive_dim => {
const text = std.mem.trim(u8, argument orelse return false, " \t\r\n%");
const percent = std.fmt.parseInt(u8, text, 10) catch return false;
@@ -1150,6 +1139,40 @@ pub const Runtime = struct {
return true;
}
+ /// The values a setting that chooses among words takes, for a refusal to
+ /// name; null for one that takes a number, a path or a name. Bare, each
+ /// of these flips (a two-valued one) or steps to its next value.
+ pub fn choices(action: Action) ?[]const u8 {
+ const words = struct {
+ fn of(comptime T: type) []const u8 {
+ comptime var out: []const u8 = "";
+ inline for (std.meta.fieldNames(T), 0..) |name, i| out = out ++ (if (i > 0) ", " else "") ++ name;
+ return out;
+ }
+ };
+ return switch (action) {
+ .toggle, .transition => "on, off",
+ .choice => |which| switch (which) {
+ inline else => |field| comptime words.of(@FieldType(Runtime, @tagName(field))),
+ },
+ .lift => "on, " ++ comptime words.of(LiftStyle),
+ .motion => comptime words.of(animation.Motion.Flavour),
+ .scene => std.fmt.comptimePrint("on, off, 0-{d}", .{Post.max_level}),
+ .shader_animation => comptime words.of(ShaderAnimation),
+ 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 {
+ const text = std.mem.trim(u8, argument orelse "", " \t\r\n");
+ if (text.len > 0) return std.meta.stringToEnum(T, text);
+ const all = std.enums.values(T);
+ const at = std.mem.indexOfScalar(T, all, now) orelse 0;
+ return all[(at + 1) % all.len];
+ }
+
/// 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 {