aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/src/synthetic/cli.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/synthetic/cli.zig
parent55c138263e190a1e79d4b997bfb9397306c0ec1f (diff)
feat: finish ghostty pane backend integration
Diffstat (limited to 'vendor/libghostty-vt/src/synthetic/cli.zig')
-rw-r--r--vendor/libghostty-vt/src/synthetic/cli.zig115
1 files changed, 115 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/src/synthetic/cli.zig b/vendor/libghostty-vt/src/synthetic/cli.zig
new file mode 100644
index 00000000..d9b6a659
--- /dev/null
+++ b/vendor/libghostty-vt/src/synthetic/cli.zig
@@ -0,0 +1,115 @@
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+const cli = @import("../cli.zig");
+
+/// The available actions for the CLI. This is the list of available
+/// synthetic generators. View docs for each individual one in the
+/// predictably named files under `cli/`.
+pub const Action = enum {
+ ascii,
+ osc,
+ utf8,
+
+ /// Returns the struct associated with the action. The struct
+ /// should have a few decls:
+ ///
+ /// - `const Options`: The CLI options for the action.
+ /// - `fn create`: Create a new instance of the action from options.
+ /// - `fn destroy`: Destroy the instance of the action.
+ ///
+ /// See TerminalStream for an example.
+ pub fn Struct(comptime action: Action) type {
+ return switch (action) {
+ .ascii => @import("cli/Ascii.zig"),
+ .osc => @import("cli/Osc.zig"),
+ .utf8 => @import("cli/Utf8.zig"),
+ };
+ }
+};
+
+/// An entrypoint for the synthetic generator CLI.
+pub fn main() !void {
+ const alloc = std.heap.c_allocator;
+ const action_ = try cli.action.detectArgs(Action, alloc);
+ const action = action_ orelse return error.NoAction;
+ try mainAction(alloc, action, .cli);
+}
+
+pub const Args = union(enum) {
+ /// The arguments passed to the CLI via argc/argv.
+ cli,
+
+ /// Simple string arguments, parsed via std.process.ArgIteratorGeneral.
+ string: []const u8,
+};
+
+pub fn mainAction(
+ alloc: Allocator,
+ action: Action,
+ args: Args,
+) !void {
+ switch (action) {
+ inline else => |comptime_action| {
+ const Impl = Action.Struct(comptime_action);
+ try mainActionImpl(Impl, alloc, args);
+ },
+ }
+}
+
+fn mainActionImpl(
+ comptime Impl: type,
+ alloc: Allocator,
+ args: Args,
+) !void {
+ // First, parse our CLI options.
+ const Options = Impl.Options;
+ var opts: Options = .{};
+ defer if (@hasDecl(Options, "deinit")) opts.deinit();
+ switch (args) {
+ .cli => {
+ var iter = try cli.args.argsIterator(alloc);
+ defer iter.deinit();
+ try cli.args.parse(Options, alloc, &opts, &iter);
+ },
+ .string => |str| {
+ var iter = try std.process.ArgIteratorGeneral(.{}).init(
+ alloc,
+ str,
+ );
+ defer iter.deinit();
+ try cli.args.parse(Options, alloc, &opts, &iter);
+ },
+ }
+
+ // TODO: Make this a command line option.
+ const seed: u64 = @truncate(@as(
+ u128,
+ @bitCast(std.time.nanoTimestamp()),
+ ));
+ var prng = std.Random.DefaultPrng.init(seed);
+ const rand = prng.random();
+
+ // Our output always goes to stdout.
+ var buffer: [2048]u8 = undefined;
+ var stdout_writer = std.fs.File.stdout().writer(&buffer);
+ const writer = &stdout_writer.interface;
+
+ // Create our implementation
+ const impl = try Impl.create(alloc, opts);
+ defer impl.destroy(alloc);
+ try impl.run(writer, rand);
+
+ // Always flush
+ writer.flush() catch |err| switch (err) {
+ error.WriteFailed => return,
+ };
+}
+
+test {
+ // Make sure we ref all our actions
+ inline for (@typeInfo(Action).@"enum".fields) |field| {
+ const action = @field(Action, field.name);
+ const Impl = Action.Struct(action);
+ _ = Impl;
+ }
+}