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/synthetic/cli.zig | |
| parent | 55c138263e190a1e79d4b997bfb9397306c0ec1f (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.zig | 115 |
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; + } +} |
