aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/src/config/conditional.zig
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-04-04 19:22:04 +0300
committerCan Celik <ogulcancelik@gmail.com>2026-04-05 01:23:06 +0300
commit41dd733ca7123c9ac4bfc6c781697a660e95b052 (patch)
tree3fc91815ca139ef2e0b281bba0abda4ef15175f4 /vendor/libghostty-vt/src/config/conditional.zig
parent55c138263e190a1e79d4b997bfb9397306c0ec1f (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.zig94
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",
+ }));
+}