summaryrefslogtreecommitdiff
path: root/src/cli
diff options
context:
space:
mode:
authorMitchell Hashimoto <mitchell.hashimoto@gmail.com>2024-01-20 09:29:26 -0800
committerMitchell Hashimoto <mitchell.hashimoto@gmail.com>2024-01-20 09:29:26 -0800
commitb438998fb82d07e7f29a71cec30e1f46a7a7a0fc (patch)
treeee31f31c74b0edad5daf1b7f60dfe737b8005261 /src/cli
parent203b38fdac0b18d0e26418390dcaca914357c28c (diff)
cli: support --help and -h for actions
Diffstat (limited to 'src/cli')
-rw-r--r--src/cli/action.zig34
-rw-r--r--src/cli/args.zig11
-rw-r--r--src/cli/list_colors.zig7
-rw-r--r--src/cli/list_fonts.zig7
-rw-r--r--src/cli/list_keybinds.zig7
-rw-r--r--src/cli/list_themes.zig7
-rw-r--r--src/cli/version.zig26
7 files changed, 97 insertions, 2 deletions
diff --git a/src/cli/action.zig b/src/cli/action.zig
index 2a7e0c6a9..a0fa216eb 100644
--- a/src/cli/action.zig
+++ b/src/cli/action.zig
@@ -1,5 +1,6 @@
const std = @import("std");
const Allocator = std.mem.Allocator;
+const help_strings = @import("help_strings");
const list_fonts = @import("list_fonts.zig");
const version = @import("version.zig");
@@ -35,6 +36,9 @@ pub const Action = enum {
InvalidAction,
};
+ /// This should be returned by actions that want to print the help text.
+ pub const help_error = error.ActionHelpRequested;
+
/// Detect the action from CLI args.
pub fn detectCLI(alloc: Allocator) !?Action {
var iter = try std.process.argsWithAllocator(alloc);
@@ -61,8 +65,36 @@ pub const Action = enum {
/// Run the action. This returns the exit code to exit with.
pub fn run(self: Action, alloc: Allocator) !u8 {
+ return self.runMain(alloc) catch |err| switch (err) {
+ // If help is requested, then we use some comptime trickery
+ // to find this action in the help strings and output that.
+ help_error => err: {
+ inline for (@typeInfo(Action).Enum.fields) |field| {
+ // Future note: for now we just output the help text directly
+ // to stdout. In the future we can style this much prettier
+ // for all commands by just changing this one place.
+
+ if (std.mem.eql(u8, field.name, @tagName(self))) {
+ const stdout = std.io.getStdOut().writer();
+ const text = @field(help_strings.Action, field.name) ++ "\n";
+ stdout.writeAll(text) catch |write_err| {
+ std.log.warn("failed to write help text: {}\n", .{write_err});
+ break :err 1;
+ };
+
+ break :err 0;
+ }
+ }
+
+ break :err err;
+ },
+ else => err,
+ };
+ }
+
+ fn runMain(self: Action, alloc: Allocator) !u8 {
return switch (self) {
- .version => try version.run(),
+ .version => try version.run(alloc),
.@"list-fonts" => try list_fonts.run(alloc),
.@"list-keybinds" => try list_keybinds.run(alloc),
.@"list-themes" => try list_themes.run(alloc),
diff --git a/src/cli/args.zig b/src/cli/args.zig
index c226493f9..773457cf8 100644
--- a/src/cli/args.zig
+++ b/src/cli/args.zig
@@ -77,6 +77,17 @@ pub fn parse(comptime T: type, alloc: Allocator, dst: *T, iter: anytype) !void {
if (!try dst.parseManuallyHook(arena_alloc, arg, iter)) return;
}
+ // If the destination supports help then we check for it, call
+ // the help function and return.
+ if (@hasDecl(T, "help")) {
+ if (mem.eql(u8, arg, "--help") or
+ mem.eql(u8, arg, "-h"))
+ {
+ try dst.help();
+ return;
+ }
+ }
+
if (mem.startsWith(u8, arg, "--")) {
var key: []const u8 = arg[2..];
const value: ?[]const u8 = value: {
diff --git a/src/cli/list_colors.zig b/src/cli/list_colors.zig
index 2b6dd1d0e..447f70552 100644
--- a/src/cli/list_colors.zig
+++ b/src/cli/list_colors.zig
@@ -1,4 +1,5 @@
const std = @import("std");
+const Action = @import("action.zig").Action;
const args = @import("args.zig");
const x11_color = @import("../terminal/main.zig").x11_color;
@@ -6,6 +7,12 @@ pub const Options = struct {
pub fn deinit(self: Options) void {
_ = self;
}
+
+ /// Enables "-h" and "--help" to work.
+ pub fn help(self: Options) !void {
+ _ = self;
+ return Action.help_error;
+ }
};
/// The "list-colors" command is used to list all the named RGB colors in
diff --git a/src/cli/list_fonts.zig b/src/cli/list_fonts.zig
index 0e48bf0f9..b49e43a30 100644
--- a/src/cli/list_fonts.zig
+++ b/src/cli/list_fonts.zig
@@ -1,6 +1,7 @@
const std = @import("std");
const Allocator = std.mem.Allocator;
const ArenaAllocator = std.heap.ArenaAllocator;
+const Action = @import("action.zig").Action;
const args = @import("args.zig");
const font = @import("../font/main.zig");
@@ -26,6 +27,12 @@ pub const Config = struct {
if (self._arena) |arena| arena.deinit();
self.* = undefined;
}
+
+ /// Enables "-h" and "--help" to work.
+ pub fn help(self: Config) !void {
+ _ = self;
+ return Action.help_error;
+ }
};
/// The list-fonts command is used to list all the available fonts for Ghostty.
diff --git a/src/cli/list_keybinds.zig b/src/cli/list_keybinds.zig
index 8d9585be9..15df1815e 100644
--- a/src/cli/list_keybinds.zig
+++ b/src/cli/list_keybinds.zig
@@ -1,6 +1,7 @@
const std = @import("std");
const inputpkg = @import("../input.zig");
const args = @import("args.zig");
+const Action = @import("action.zig").Action;
const Arena = std.heap.ArenaAllocator;
const Allocator = std.mem.Allocator;
const Config = @import("../config/Config.zig");
@@ -13,6 +14,12 @@ pub const Options = struct {
pub fn deinit(self: Options) void {
_ = self;
}
+
+ /// Enables "-h" and "--help" to work.
+ pub fn help(self: Options) !void {
+ _ = self;
+ return Action.help_error;
+ }
};
/// The "list-keybinds" command is used to list all the available keybinds
diff --git a/src/cli/list_themes.zig b/src/cli/list_themes.zig
index be3a41c14..98c3859c6 100644
--- a/src/cli/list_themes.zig
+++ b/src/cli/list_themes.zig
@@ -1,6 +1,7 @@
const std = @import("std");
const inputpkg = @import("../input.zig");
const args = @import("args.zig");
+const Action = @import("action.zig").Action;
const Arena = std.heap.ArenaAllocator;
const Allocator = std.mem.Allocator;
const Config = @import("../config/Config.zig");
@@ -10,6 +11,12 @@ pub const Options = struct {
pub fn deinit(self: Options) void {
_ = self;
}
+
+ /// Enables "-h" and "--help" to work.
+ pub fn help(self: Options) !void {
+ _ = self;
+ return Action.help_error;
+ }
};
/// The "list-themes" command is used to list all the available themes
diff --git a/src/cli/version.zig b/src/cli/version.zig
index dca20ad2f..fb12faa2e 100644
--- a/src/cli/version.zig
+++ b/src/cli/version.zig
@@ -1,12 +1,36 @@
const std = @import("std");
+const Allocator = std.mem.Allocator;
const builtin = @import("builtin");
const build_config = @import("../build_config.zig");
const xev = @import("xev");
const renderer = @import("../renderer.zig");
+const args = @import("args.zig");
+const Action = @import("action.zig").Action;
+
+pub const Options = struct {
+ pub fn deinit(self: Options) void {
+ _ = self;
+ }
+
+ /// Enables "-h" and "--help" to work.
+ pub fn help(self: Options) !void {
+ _ = self;
+ return Action.help_error;
+ }
+};
/// The `version` command is used to display information
/// about Ghostty.
-pub fn run() !u8 {
+pub fn run(alloc: Allocator) !u8 {
+ var opts: Options = .{};
+ defer opts.deinit();
+
+ {
+ var iter = try std.process.argsWithAllocator(alloc);
+ defer iter.deinit();
+ try args.parse(Options, alloc, &opts, &iter);
+ }
+
const stdout = std.io.getStdOut().writer();
try stdout.print("Ghostty {s}\n\n", .{build_config.version_string});
try stdout.print("Build Config\n", .{});