diff --git a/src/cli/args.zig b/src/cli/args.zig index 7385e6a3e..a27b98980 100644 --- a/src/cli/args.zig +++ b/src/cli/args.zig @@ -247,16 +247,6 @@ pub fn parseIntoField( inline for (info.Struct.fields) |field| { if (field.name[0] != '_' and mem.eql(u8, field.name, key)) { - // If the value is empty string (set but empty string), - // then we reset the value to the default. - if (value) |v| default: { - if (v.len != 0) break :default; - const raw = field.default_value orelse break :default; - const ptr: *const field.type = @alignCast(@ptrCast(raw)); - @field(dst, field.name) = ptr.*; - return; - } - // For optional fields, we just treat it as the child type. // This lets optional fields default to null but get set by // the CLI. @@ -264,11 +254,27 @@ pub fn parseIntoField( .Optional => |opt| opt.child, else => field.type, }; + const fieldInfo = @typeInfo(Field); + const canHaveDecls = fieldInfo == .Struct or fieldInfo == .Union or fieldInfo == .Enum; + + // If the value is empty string (set but empty string), + // then we reset the value to the default. + if (value) |v| default: { + if (v.len != 0) break :default; + // Set default value if possible. + if (canHaveDecls and @hasDecl(Field, "setToDefault")) { + try @field(dst, field.name).setToDefault(alloc); + return; + } + const raw = field.default_value orelse break :default; + const ptr: *const field.type = @alignCast(@ptrCast(raw)); + @field(dst, field.name) = ptr.*; + return; + } // If we are a type that can have decls and have a parseCLI decl, // we call that and use that to set the value. - const fieldInfo = @typeInfo(Field); - if (fieldInfo == .Struct or fieldInfo == .Union or fieldInfo == .Enum) { + if (canHaveDecls) { if (@hasDecl(Field, "parseCLI")) { const fnInfo = @typeInfo(@TypeOf(Field.parseCLI)).Fn; switch (fnInfo.params.len) { diff --git a/src/config/Config.zig b/src/config/Config.zig index 62da3888d..6d2a0f424 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -5129,6 +5129,12 @@ pub const Keybinds = struct { errdefer if (copy) |v| alloc.free(v); // Check for special values + if (value.len == 0) { + log.info("config has 'keybind =', using default keybinds", .{}); + try self.setToDefault(alloc); + return; + } + if (std.mem.eql(u8, value, "clear")) { // We don't clear the memory because its in the arena and unlikely // to be free-able anyways (since arenas can only clear the last