mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-10-09 19:36:45 +00:00
cli: dedicated directory
This commit is contained in:
141
src/cli/action.zig
Normal file
141
src/cli/action.zig
Normal file
@@ -0,0 +1,141 @@
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const list_fonts = @import("list_fonts.zig");
|
||||
const version = @import("version.zig");
|
||||
|
||||
/// Special commands that can be invoked via CLI flags. These are all
|
||||
/// invoked by using `+<action>` as a CLI flag. The only exception is
|
||||
/// "version" which can be invoked additionally with `--version`.
|
||||
pub const Action = enum {
|
||||
/// Output the version and exit
|
||||
version,
|
||||
|
||||
/// List available fonts
|
||||
@"list-fonts",
|
||||
|
||||
pub const Error = error{
|
||||
/// Multiple actions were detected. You can specify at most one
|
||||
/// action on the CLI otherwise the behavior desired is ambiguous.
|
||||
MultipleActions,
|
||||
|
||||
/// An unknown action was specified.
|
||||
InvalidAction,
|
||||
};
|
||||
|
||||
/// Detect the action from CLI args.
|
||||
pub fn detectCLI(alloc: Allocator) !?Action {
|
||||
var iter = try std.process.argsWithAllocator(alloc);
|
||||
defer iter.deinit();
|
||||
return try detectIter(&iter);
|
||||
}
|
||||
|
||||
/// Detect the action from any iterator, used primarily for tests.
|
||||
pub fn detectIter(iter: anytype) Error!?Action {
|
||||
var pending: ?Action = null;
|
||||
while (iter.next()) |arg| {
|
||||
// Special case, --version always outputs the version no
|
||||
// matter what, no matter what other args exist.
|
||||
if (std.mem.eql(u8, arg, "--version")) return .version;
|
||||
|
||||
// Commands must start with "+"
|
||||
if (arg.len == 0 or arg[0] != '+') continue;
|
||||
if (pending != null) return Error.MultipleActions;
|
||||
pending = std.meta.stringToEnum(Action, arg[1..]) orelse return Error.InvalidAction;
|
||||
}
|
||||
|
||||
return pending;
|
||||
}
|
||||
|
||||
/// Run the action. This returns the exit code to exit with.
|
||||
pub fn run(self: Action, alloc: Allocator) !u8 {
|
||||
_ = alloc;
|
||||
return switch (self) {
|
||||
.version => try version.run(),
|
||||
.@"list-fonts" => try list_fonts.run(),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
test "parse action none" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var iter = try std.process.ArgIteratorGeneral(.{}).init(
|
||||
alloc,
|
||||
"--a=42 --b --b-f=false",
|
||||
);
|
||||
defer iter.deinit();
|
||||
const action = try Action.detectIter(&iter);
|
||||
try testing.expect(action == null);
|
||||
}
|
||||
|
||||
test "parse action version" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
{
|
||||
var iter = try std.process.ArgIteratorGeneral(.{}).init(
|
||||
alloc,
|
||||
"--a=42 --b --b-f=false --version",
|
||||
);
|
||||
defer iter.deinit();
|
||||
const action = try Action.detectIter(&iter);
|
||||
try testing.expect(action.? == .version);
|
||||
}
|
||||
|
||||
{
|
||||
var iter = try std.process.ArgIteratorGeneral(.{}).init(
|
||||
alloc,
|
||||
"--version --a=42 --b --b-f=false",
|
||||
);
|
||||
defer iter.deinit();
|
||||
const action = try Action.detectIter(&iter);
|
||||
try testing.expect(action.? == .version);
|
||||
}
|
||||
|
||||
{
|
||||
var iter = try std.process.ArgIteratorGeneral(.{}).init(
|
||||
alloc,
|
||||
"--c=84 --d --version --a=42 --b --b-f=false",
|
||||
);
|
||||
defer iter.deinit();
|
||||
const action = try Action.detectIter(&iter);
|
||||
try testing.expect(action.? == .version);
|
||||
}
|
||||
}
|
||||
|
||||
test "parse action plus" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
{
|
||||
var iter = try std.process.ArgIteratorGeneral(.{}).init(
|
||||
alloc,
|
||||
"--a=42 --b --b-f=false +version",
|
||||
);
|
||||
defer iter.deinit();
|
||||
const action = try Action.detectIter(&iter);
|
||||
try testing.expect(action.? == .version);
|
||||
}
|
||||
|
||||
{
|
||||
var iter = try std.process.ArgIteratorGeneral(.{}).init(
|
||||
alloc,
|
||||
"+version --a=42 --b --b-f=false",
|
||||
);
|
||||
defer iter.deinit();
|
||||
const action = try Action.detectIter(&iter);
|
||||
try testing.expect(action.? == .version);
|
||||
}
|
||||
|
||||
{
|
||||
var iter = try std.process.ArgIteratorGeneral(.{}).init(
|
||||
alloc,
|
||||
"--c=84 --d +version --a=42 --b --b-f=false",
|
||||
);
|
||||
defer iter.deinit();
|
||||
const action = try Action.detectIter(&iter);
|
||||
try testing.expect(action.? == .version);
|
||||
}
|
||||
}
|
3
src/cli/list_fonts.zig
Normal file
3
src/cli/list_fonts.zig
Normal file
@@ -0,0 +1,3 @@
|
||||
pub fn run() !u8 {
|
||||
return 0;
|
||||
}
|
17
src/cli/version.zig
Normal file
17
src/cli/version.zig
Normal file
@@ -0,0 +1,17 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const build_config = @import("../build_config.zig");
|
||||
const xev = @import("xev");
|
||||
const renderer = @import("../renderer.zig");
|
||||
|
||||
pub fn run() !u8 {
|
||||
const stdout = std.io.getStdOut().writer();
|
||||
try stdout.print("Ghostty {s}\n\n", .{build_config.version_string});
|
||||
try stdout.print("Build Config\n", .{});
|
||||
try stdout.print(" - build mode : {}\n", .{builtin.mode});
|
||||
try stdout.print(" - app runtime: {}\n", .{build_config.app_runtime});
|
||||
try stdout.print(" - font engine: {}\n", .{build_config.font_backend});
|
||||
try stdout.print(" - renderer : {}\n", .{renderer.Renderer});
|
||||
try stdout.print(" - libxev : {}\n", .{xev.backend});
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user