mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-04-22 09:28:37 +03:00
empty cli or config args reset the value to the default
Fixes #1367 We previously special-cased optionals but we should do better and have this reset ANY type to the defined default value on the struct.
This commit is contained in:
@ -71,6 +71,10 @@ foreground= ffffff
|
|||||||
keybind = ctrl+z=close_surface
|
keybind = ctrl+z=close_surface
|
||||||
keybind = ctrl+d=new_split:right
|
keybind = ctrl+d=new_split:right
|
||||||
|
|
||||||
|
# Empty values reset the configuration to the default value
|
||||||
|
|
||||||
|
font-family =
|
||||||
|
|
||||||
# Colors can be changed by setting the 16 colors of `palette`, which each color
|
# Colors can be changed by setting the 16 colors of `palette`, which each color
|
||||||
# being defined as regular and bold.
|
# being defined as regular and bold.
|
||||||
#
|
#
|
||||||
|
@ -170,21 +170,15 @@ fn parseIntoField(
|
|||||||
|
|
||||||
inline for (info.Struct.fields) |field| {
|
inline for (info.Struct.fields) |field| {
|
||||||
if (field.name[0] != '_' and mem.eql(u8, field.name, key)) {
|
if (field.name[0] != '_' and mem.eql(u8, field.name, key)) {
|
||||||
// If the field is optional then consider scenarios we reset
|
// If the value is empty string (set but empty string),
|
||||||
// the value to being unset. We allow unsetting optionals
|
// then we reset the value to the default.
|
||||||
// whenever the value is "".
|
if (value) |v| default: {
|
||||||
//
|
if (v.len != 0) break :default;
|
||||||
// At the time of writing this, empty string isn't a desirable
|
const raw = field.default_value orelse break :default;
|
||||||
// value for any optional field under any realistic scenario.
|
const ptr: *const field.type = @alignCast(@ptrCast(raw));
|
||||||
//
|
@field(dst, field.name) = ptr.*;
|
||||||
// We don't allow unset values to set optional fields to
|
|
||||||
// null because unset value for booleans always means true.
|
|
||||||
if (@typeInfo(field.type) == .Optional) optional: {
|
|
||||||
if (std.mem.eql(u8, "", value orelse break :optional)) {
|
|
||||||
@field(dst, field.name) = null;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// For optional fields, we just treat it as the child type.
|
// For optional fields, we just treat it as the child type.
|
||||||
// This lets optional fields default to null but get set by
|
// This lets optional fields default to null but get set by
|
||||||
@ -396,6 +390,26 @@ test "parse: quoted value" {
|
|||||||
try testing.expectEqualStrings("hello!", data.b);
|
try testing.expectEqualStrings("hello!", data.b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "parse: empty value resets to default" {
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
var data: struct {
|
||||||
|
a: u8 = 42,
|
||||||
|
b: bool = false,
|
||||||
|
_arena: ?ArenaAllocator = null,
|
||||||
|
} = .{};
|
||||||
|
defer if (data._arena) |arena| arena.deinit();
|
||||||
|
|
||||||
|
var iter = try std.process.ArgIteratorGeneral(.{}).init(
|
||||||
|
testing.allocator,
|
||||||
|
"--a= --b=",
|
||||||
|
);
|
||||||
|
defer iter.deinit();
|
||||||
|
try parse(@TypeOf(data), testing.allocator, &data, &iter);
|
||||||
|
try testing.expectEqual(@as(u8, 42), data.a);
|
||||||
|
try testing.expect(!data.b);
|
||||||
|
}
|
||||||
|
|
||||||
test "parse: error tracking" {
|
test "parse: error tracking" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
|
|
||||||
@ -865,6 +879,15 @@ test "LineIterator spaces around '='" {
|
|||||||
try testing.expectEqual(@as(?[]const u8, null), iter.next());
|
try testing.expectEqual(@as(?[]const u8, null), iter.next());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "LineIterator no value" {
|
||||||
|
const testing = std.testing;
|
||||||
|
var fbs = std.io.fixedBufferStream("A = \n\n");
|
||||||
|
|
||||||
|
var iter = lineIterator(fbs.reader());
|
||||||
|
try testing.expectEqualStrings("--A=", iter.next().?);
|
||||||
|
try testing.expectEqual(@as(?[]const u8, null), iter.next());
|
||||||
|
}
|
||||||
|
|
||||||
test "LineIterator with CRLF line endings" {
|
test "LineIterator with CRLF line endings" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
var fbs = std.io.fixedBufferStream("A\r\nB = C\r\n");
|
var fbs = std.io.fixedBufferStream("A\r\nB = C\r\n");
|
||||||
|
Reference in New Issue
Block a user