diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-04-04 19:22:04 +0300 |
|---|---|---|
| committer | Can Celik <ogulcancelik@gmail.com> | 2026-04-05 01:23:06 +0300 |
| commit | 41dd733ca7123c9ac4bfc6c781697a660e95b052 (patch) | |
| tree | 3fc91815ca139ef2e0b281bba0abda4ef15175f4 /vendor/libghostty-vt/src/config/conditional.zig | |
| parent | 55c138263e190a1e79d4b997bfb9397306c0ec1f (diff) | |
feat: finish ghostty pane backend integration
Diffstat (limited to 'vendor/libghostty-vt/src/config/conditional.zig')
| -rw-r--r-- | vendor/libghostty-vt/src/config/conditional.zig | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/src/config/conditional.zig b/vendor/libghostty-vt/src/config/conditional.zig new file mode 100644 index 00000000..fdc285a2 --- /dev/null +++ b/vendor/libghostty-vt/src/config/conditional.zig @@ -0,0 +1,94 @@ +const std = @import("std"); +const builtin = @import("builtin"); +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 }; + + pub fn clone( + self: Conditional, + alloc: Allocator, + ) Allocator.Error!Conditional { + return .{ + .key = self.key, + .op = self.op, + .value = try alloc.dupe(u8, self.value), + }; + } +}; + +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", + })); +} |
