Chording support for vim mode (#53)

* initial experimental success

* refined chording

* add default value

* refactor chording from switch to if

* revert change introduced when debugging

* remove unnecessary try

* added configuration option
This commit is contained in:
Visen 2024-10-22 11:59:06 -05:00 committed by GitHub
parent 2f3487fff0
commit b70da1918c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 50 additions and 0 deletions

View file

@ -8,6 +8,7 @@ gutter_line_numbers_relative: bool = false,
vim_normal_gutter_line_numbers_relative: bool = true,
vim_visual_gutter_line_numbers_relative: bool = true,
vim_insert_gutter_line_numbers_relative: bool = false,
vim_insert_chording_keybindings: bool = true,
enable_terminal_cursor: bool = false,
enable_terminal_color_scheme: bool = builtin.os.tag != .windows,
highlight_current_line: bool = true,

View file

@ -1,4 +1,5 @@
const tp = @import("thespian");
const std = @import("std");
const key = @import("renderer").input.key;
const mod = @import("renderer").input.modifier;
@ -21,6 +22,14 @@ input: ArrayList(u8),
last_cmd: []const u8 = "",
leader: ?struct { keypress: u32, modifiers: u32 } = null,
commands: Commands = undefined,
last_key: KeyPressEvent = .{},
pub const KeyPressEvent = struct {
keypress: u32 = 0,
modifiers: u32 = std.math.maxInt(u32),
egc: u32 = 0,
timestamp_ms: i64 = 0,
};
pub fn create(allocator: Allocator) !tui.Mode {
const self: *Self = try allocator.create(Self);
@ -82,6 +91,46 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void {
key.LALT, key.RALT => return self.cmd("enable_jump_mode", .{}),
else => {},
}
if (tui.current().config.vim_insert_chording_keybindings) {
//reset chord if enough time has passed
const chord_time_window_ms = 750;
if (std.time.milliTimestamp() - self.last_key.timestamp_ms > chord_time_window_ms) {
self.last_key = .{};
}
//chording
if (self.last_key.keypress == 'j' and self.last_key.modifiers == 0 and keypress == 'k' and modifiers == 0) {
try self.cmd("delete_backward", .{});
try self.cmd("enter_mode", command.fmt(.{"vim/normal"}));
return;
}
if (self.last_key.keypress == 'k' and self.last_key.modifiers == 0 and keypress == 'j' and modifiers == 0) {
try self.cmd("delete_backward", .{});
try self.cmd("enter_mode", command.fmt(.{"vim/normal"}));
return;
}
if (self.last_key.keypress == 'f' and self.last_key.modifiers == 0 and keypress == 'j' and modifiers == 0) {
try self.cmd("delete_backward", .{});
try self.cmd("enter_mode", command.fmt(.{"vim/normal"}));
return;
}
if (self.last_key.keypress == 'j' and self.last_key.modifiers == 0 and keypress == 'f' and modifiers == 0) {
try self.cmd("delete_backward", .{});
try self.cmd("enter_mode", command.fmt(.{"vim/normal"}));
return;
}
//record current key event
self.last_key = .{
.keypress = keypress,
.modifiers = modifiers,
.egc = egc,
.timestamp_ms = std.time.milliTimestamp(),
};
}
return switch (modifiers) {
mod.CTRL => switch (keynormal) {
'E' => self.cmd("open_recent", .{}),