mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 16:26:08 +03:00
feat(actions): add new list-keybinds action
This commit is contained in:
@ -3,6 +3,7 @@ const Allocator = std.mem.Allocator;
|
|||||||
|
|
||||||
const list_fonts = @import("list_fonts.zig");
|
const list_fonts = @import("list_fonts.zig");
|
||||||
const version = @import("version.zig");
|
const version = @import("version.zig");
|
||||||
|
const list_keybinds = @import("list_keybinds.zig");
|
||||||
|
|
||||||
/// Special commands that can be invoked via CLI flags. These are all
|
/// Special commands that can be invoked via CLI flags. These are all
|
||||||
/// invoked by using `+<action>` as a CLI flag. The only exception is
|
/// invoked by using `+<action>` as a CLI flag. The only exception is
|
||||||
@ -14,6 +15,9 @@ pub const Action = enum {
|
|||||||
/// List available fonts
|
/// List available fonts
|
||||||
@"list-fonts",
|
@"list-fonts",
|
||||||
|
|
||||||
|
/// List available keybinds
|
||||||
|
@"list-keybinds",
|
||||||
|
|
||||||
pub const Error = error{
|
pub const Error = error{
|
||||||
/// Multiple actions were detected. You can specify at most one
|
/// Multiple actions were detected. You can specify at most one
|
||||||
/// action on the CLI otherwise the behavior desired is ambiguous.
|
/// action on the CLI otherwise the behavior desired is ambiguous.
|
||||||
@ -52,6 +56,7 @@ pub const Action = enum {
|
|||||||
return switch (self) {
|
return switch (self) {
|
||||||
.version => try version.run(),
|
.version => try version.run(),
|
||||||
.@"list-fonts" => try list_fonts.run(alloc),
|
.@"list-fonts" => try list_fonts.run(alloc),
|
||||||
|
.@"list-keybinds" => try list_keybinds.run(alloc),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
105
src/cli/list_keybinds.zig
Normal file
105
src/cli/list_keybinds.zig
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const inputpkg = @import("../input.zig");
|
||||||
|
const args = @import("args.zig");
|
||||||
|
const Arena = std.heap.ArenaAllocator;
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
|
const Config = @import("../config/Config.zig");
|
||||||
|
|
||||||
|
pub const Options = struct {
|
||||||
|
_arena: ?Arena = null,
|
||||||
|
default: bool = false,
|
||||||
|
|
||||||
|
pub fn deinit(self: *Options) void {
|
||||||
|
if (self._arena) |arena| arena.deinit();
|
||||||
|
self.* = undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The "list-keybinds" command is used to list all the available keybinds for Ghostty.
|
||||||
|
///
|
||||||
|
/// When executed without any arguments this will list the current keybinds loaded by the config file.
|
||||||
|
/// If no config file is found or there aren't any changes to the keybinds it will print out the default ones configured for Ghostty
|
||||||
|
///
|
||||||
|
/// The "--default" argument will print out all the default keybinds configured for Ghostty
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (opts.default) {
|
||||||
|
return try listDefaultKeybinds(alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return try listKeybinds(alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn listKeybinds(alloc: Allocator) !u8 {
|
||||||
|
var loaded_config = try Config.load(alloc);
|
||||||
|
defer loaded_config.deinit();
|
||||||
|
|
||||||
|
const stdout = std.io.getStdOut().writer();
|
||||||
|
var iter = loaded_config.keybind.set.bindings.iterator();
|
||||||
|
|
||||||
|
return try iterConfig(&stdout, &iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn listDefaultKeybinds(alloc: Allocator) !u8 {
|
||||||
|
var default = try Config.default(alloc);
|
||||||
|
defer default.deinit();
|
||||||
|
|
||||||
|
const stdout = std.io.getStdOut().writer();
|
||||||
|
var iter = default.keybind.set.bindings.iterator();
|
||||||
|
|
||||||
|
return try iterConfig(&stdout, &iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn iterConfig(stdout: anytype, iter: anytype) !u8 {
|
||||||
|
const start = @intFromEnum(inputpkg.Key.one);
|
||||||
|
var amount: u8 = 0;
|
||||||
|
|
||||||
|
while (iter.next()) |next| {
|
||||||
|
const keys = next.key_ptr.*;
|
||||||
|
const value = next.value_ptr.*;
|
||||||
|
try stdout.print("{s}", .{@tagName(value)});
|
||||||
|
switch (value) {
|
||||||
|
.goto_tab => |val| try stdout.print(" {d}:", .{val}),
|
||||||
|
.jump_to_prompt => |val| try stdout.print(" {d}:", .{val}),
|
||||||
|
.increase_font_size, .decrease_font_size => |val| try stdout.print(" {d}:", .{val}),
|
||||||
|
.goto_split => |val| try stdout.print(" {s}:", .{@tagName(val)}),
|
||||||
|
.inspector => |val| try stdout.print(" {s}:", .{@tagName(val)}),
|
||||||
|
inline else => try stdout.print(":", .{}),
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (keys.key) {
|
||||||
|
.one, .two, .three, .four, .five, .six, .seven, .eight, .nine => try stdout.print(" {d} +", .{(@intFromEnum(keys.key) - start) + 1}),
|
||||||
|
inline else => try stdout.print(" {s} +", .{@tagName(keys.key)}),
|
||||||
|
}
|
||||||
|
const fields = @typeInfo(@TypeOf(keys.mods)).Struct.fields;
|
||||||
|
inline for (fields) |field| {
|
||||||
|
switch (field.type) {
|
||||||
|
bool => {
|
||||||
|
if (@field(keys.mods, field.name)) {
|
||||||
|
if (amount >= 1) {
|
||||||
|
try stdout.print(" +", .{});
|
||||||
|
}
|
||||||
|
try stdout.print(" {s}", .{field.name});
|
||||||
|
amount += 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
u6 => continue,
|
||||||
|
|
||||||
|
inline else => {
|
||||||
|
try stdout.print("\n", .{});
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
amount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Reference in New Issue
Block a user