mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
config: add basic conditional system core logic (no syntax yet)
Note: this doesn't have any syntax the user can use in a configuration yet. This just implements a core, tested system.
This commit is contained in:
@ -2,6 +2,7 @@ const builtin = @import("builtin");
|
|||||||
|
|
||||||
const formatter = @import("config/formatter.zig");
|
const formatter = @import("config/formatter.zig");
|
||||||
pub const Config = @import("config/Config.zig");
|
pub const Config = @import("config/Config.zig");
|
||||||
|
pub const conditional = @import("config/conditional.zig");
|
||||||
pub const string = @import("config/string.zig");
|
pub const string = @import("config/string.zig");
|
||||||
pub const edit = @import("config/edit.zig");
|
pub const edit = @import("config/edit.zig");
|
||||||
pub const url = @import("config/url.zig");
|
pub const url = @import("config/url.zig");
|
||||||
|
84
src/config/conditional.zig
Normal file
84
src/config/conditional.zig
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
const assert = std.debug.assert;
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
|
/// Conditionals in Ghostty configuration are based on a static, typed
|
||||||
|
/// state of the world instead of a dynamic key-value set. This simplifies
|
||||||
|
/// the implementation, allows for better type checking, and enables a
|
||||||
|
/// typed C API.
|
||||||
|
pub const State = struct {
|
||||||
|
/// The theme of the underlying OS desktop environment.
|
||||||
|
theme: Theme = .light,
|
||||||
|
|
||||||
|
/// The target OS of the current build.
|
||||||
|
os: std.Target.Os.Tag = builtin.target.os.tag,
|
||||||
|
|
||||||
|
pub const Theme = enum { light, dark };
|
||||||
|
|
||||||
|
/// Tests the conditional against the state and returns true if it matches.
|
||||||
|
pub fn match(self: State, cond: Conditional) bool {
|
||||||
|
switch (cond.key) {
|
||||||
|
inline else => |tag| {
|
||||||
|
// The raw value of the state field.
|
||||||
|
const raw = @field(self, @tagName(tag));
|
||||||
|
|
||||||
|
// Since all values are enums currently then we can just
|
||||||
|
// do this. If we introduce non-enum state values then this
|
||||||
|
// will be a compile error and we should fix here.
|
||||||
|
const value: []const u8 = @tagName(raw);
|
||||||
|
|
||||||
|
return switch (cond.op) {
|
||||||
|
.eq => std.mem.eql(u8, value, cond.value),
|
||||||
|
.ne => !std.mem.eql(u8, value, cond.value),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// An enum of the available conditional configuration keys.
|
||||||
|
pub const Key = key: {
|
||||||
|
const stateInfo = @typeInfo(State).Struct;
|
||||||
|
var fields: [stateInfo.fields.len]std.builtin.Type.EnumField = undefined;
|
||||||
|
for (stateInfo.fields, 0..) |field, i| fields[i] = .{
|
||||||
|
.name = field.name,
|
||||||
|
.value = i,
|
||||||
|
};
|
||||||
|
|
||||||
|
break :key @Type(.{ .Enum = .{
|
||||||
|
.tag_type = std.math.IntFittingRange(0, fields.len - 1),
|
||||||
|
.fields = &fields,
|
||||||
|
.decls = &.{},
|
||||||
|
.is_exhaustive = true,
|
||||||
|
} });
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A single conditional that can be true or false.
|
||||||
|
pub const Conditional = struct {
|
||||||
|
key: Key,
|
||||||
|
op: Op,
|
||||||
|
value: []const u8,
|
||||||
|
|
||||||
|
pub const Op = enum { eq, ne };
|
||||||
|
};
|
||||||
|
|
||||||
|
test "conditional enum match" {
|
||||||
|
const testing = std.testing;
|
||||||
|
const state: State = .{ .theme = .dark };
|
||||||
|
try testing.expect(state.match(.{
|
||||||
|
.key = .theme,
|
||||||
|
.op = .eq,
|
||||||
|
.value = "dark",
|
||||||
|
}));
|
||||||
|
try testing.expect(!state.match(.{
|
||||||
|
.key = .theme,
|
||||||
|
.op = .ne,
|
||||||
|
.value = "dark",
|
||||||
|
}));
|
||||||
|
try testing.expect(state.match(.{
|
||||||
|
.key = .theme,
|
||||||
|
.op = .ne,
|
||||||
|
.value = "light",
|
||||||
|
}));
|
||||||
|
}
|
Reference in New Issue
Block a user