add the catch_all binding key

Part of #9963

This adds a new special key `catch_all` that can be used in keybinding
definitions to match any key that is not explicitly bound. For example:
`keybind = catch_all=new_window` (chaos!). 

`catch_all` can be used in combination with modifiers, so if you want to
catch any non-bound key with Ctrl held down, you can do:
`keybind = ctrl+catch_all=new_window`.

`catch_all` can also be used with trigger sequences, so you can do:
`keybind = ctrl+a>catch_all=new_window` to catch any key pressed after
`ctrl+a` that is not explicitly bound and make a new window!

And if you want to remove the catch all binding, it is like any other:
`keybind = catch_all=unbind`.
This commit is contained in:
Mitchell Hashimoto
2025-12-19 11:56:04 -08:00
parent 73a93abf7b
commit 63422f4d4e
6 changed files with 148 additions and 1 deletions

View File

@@ -166,16 +166,19 @@ const ChordBinding = struct {
var r_trigger = rhs.triggers.first;
while (l_trigger != null and r_trigger != null) {
// We want catch_all to sort last.
const lhs_key: c_int = blk: {
switch (TriggerNode.get(l_trigger.?).data.key) {
.physical => |key| break :blk @intFromEnum(key),
.unicode => |key| break :blk @intCast(key),
.catch_all => break :blk std.math.maxInt(c_int),
}
};
const rhs_key: c_int = blk: {
switch (TriggerNode.get(r_trigger.?).data.key) {
.physical => |key| break :blk @intFromEnum(key),
.unicode => |key| break :blk @intCast(key),
.catch_all => break :blk std.math.maxInt(c_int),
}
};
@@ -268,6 +271,7 @@ fn prettyPrint(alloc: Allocator, keybinds: Config.Keybinds) !u8 {
const key = switch (trigger.data.key) {
.physical => |k| try std.fmt.allocPrint(alloc, "{t}", .{k}),
.unicode => |c| try std.fmt.allocPrint(alloc, "{u}", .{c}),
.catch_all => "catch_all",
};
result = win.printSegment(.{ .text = key }, .{ .col_offset = result.col });
@@ -314,6 +318,7 @@ fn iterateBindings(
switch (t.key) {
.physical => |k| try buf.writer.print("{t}", .{k}),
.unicode => |c| try buf.writer.print("{u}", .{c}),
.catch_all => try buf.writer.print("catch_all", .{}),
}
break :blk win.gwidth(buf.written());