mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
@ -335,6 +335,11 @@ class: ?[:0]const u8 = null,
|
||||
/// but valid.
|
||||
/// - only a single key input is allowed, "ctrl+a+b" is invalid.
|
||||
///
|
||||
/// Valid modifiers are "shift", "ctrl" (alias: "control"),
|
||||
/// "alt" (alias: "opt", "option"), and "super" (alias: "cmd", "command").
|
||||
/// You may use the modifier or the alias. When debugging keybinds,
|
||||
/// the non-aliased modifier will always be used in output.
|
||||
///
|
||||
/// Action is the action to take when the trigger is satisfied. It takes
|
||||
/// the format "action" or "action:param". The latter form is only valid
|
||||
/// if the action requires a parameter.
|
||||
|
@ -57,13 +57,27 @@ pub fn parse(raw_input: []const u8) !Binding {
|
||||
if (std.mem.eql(u8, part, field.name)) {
|
||||
// Repeat not allowed
|
||||
if (@field(result.mods, field.name)) return Error.InvalidFormat;
|
||||
|
||||
@field(result.mods, field.name) = true;
|
||||
continue :loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Alias modifiers
|
||||
const alias_mods = .{
|
||||
.{ "cmd", "super" }, .{ "command", "super" },
|
||||
.{ "opt", "alt" }, .{ "option", "alt" },
|
||||
.{ "control", "ctrl" },
|
||||
};
|
||||
inline for (alias_mods) |pair| {
|
||||
if (std.mem.eql(u8, part, pair[0])) {
|
||||
// Repeat not allowed
|
||||
if (@field(result.mods, pair[1])) return Error.InvalidFormat;
|
||||
@field(result.mods, pair[1]) = true;
|
||||
continue :loop;
|
||||
}
|
||||
}
|
||||
|
||||
// If the key starts with "physical" then this is an physical key.
|
||||
const physical = "physical:";
|
||||
const key_part = if (std.mem.startsWith(u8, part, physical)) key_part: {
|
||||
@ -754,6 +768,48 @@ test "parse: triggers" {
|
||||
try testing.expectError(Error.InvalidFormat, parse("a+b=ignore"));
|
||||
}
|
||||
|
||||
test "parse: modifier aliases" {
|
||||
const testing = std.testing;
|
||||
|
||||
try testing.expectEqual(Binding{
|
||||
.trigger = .{
|
||||
.mods = .{ .super = true },
|
||||
.key = .a,
|
||||
},
|
||||
.action = .{ .ignore = {} },
|
||||
}, try parse("cmd+a=ignore"));
|
||||
try testing.expectEqual(Binding{
|
||||
.trigger = .{
|
||||
.mods = .{ .super = true },
|
||||
.key = .a,
|
||||
},
|
||||
.action = .{ .ignore = {} },
|
||||
}, try parse("command+a=ignore"));
|
||||
|
||||
try testing.expectEqual(Binding{
|
||||
.trigger = .{
|
||||
.mods = .{ .alt = true },
|
||||
.key = .a,
|
||||
},
|
||||
.action = .{ .ignore = {} },
|
||||
}, try parse("opt+a=ignore"));
|
||||
try testing.expectEqual(Binding{
|
||||
.trigger = .{
|
||||
.mods = .{ .alt = true },
|
||||
.key = .a,
|
||||
},
|
||||
.action = .{ .ignore = {} },
|
||||
}, try parse("option+a=ignore"));
|
||||
|
||||
try testing.expectEqual(Binding{
|
||||
.trigger = .{
|
||||
.mods = .{ .ctrl = true },
|
||||
.key = .a,
|
||||
},
|
||||
.action = .{ .ignore = {} },
|
||||
}, try parse("control+a=ignore"));
|
||||
}
|
||||
|
||||
test "parse: action invalid" {
|
||||
const testing = std.testing;
|
||||
|
||||
|
Reference in New Issue
Block a user