From cf50f77abf2d99378ead7a88da9178ea225c6bcd Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Tue, 12 Nov 2024 22:20:02 +0100 Subject: [PATCH] refactor: move vim mode keybindings to keybind module --- src/keybind/static/input/flow.zig | 2 +- src/keybind/static/input/home.zig | 2 +- .../static}/input/vim/insert.zig | 35 ++++++--------- .../static}/input/vim/normal.zig | 31 +++++-------- .../static}/input/vim/visual.zig | 31 +++++-------- src/keybind/static/keybind.zig | 5 +++ src/tui/tui.zig | 43 +++++++++++++------ 7 files changed, 72 insertions(+), 77 deletions(-) rename src/{tui/mode => keybind/static}/input/vim/insert.zig (95%) rename src/{tui/mode => keybind/static}/input/vim/normal.zig (97%) rename src/{tui/mode => keybind/static}/input/vim/visual.zig (96%) diff --git a/src/keybind/static/input/flow.zig b/src/keybind/static/input/flow.zig index 6dc9ec5..6bd743e 100644 --- a/src/keybind/static/input/flow.zig +++ b/src/keybind/static/input/flow.zig @@ -16,7 +16,7 @@ input: std.ArrayList(u8), last_cmd: []const u8 = "", leader: ?struct { keypress: u32, modifiers: u32 } = null, -pub fn create(allocator: std.mem.Allocator) !EventHandler { +pub fn create(allocator: std.mem.Allocator, _: anytype) !EventHandler { const self: *Self = try allocator.create(Self); self.* = .{ .allocator = allocator, diff --git a/src/keybind/static/input/home.zig b/src/keybind/static/input/home.zig index 6021b9f..c9c6d7f 100644 --- a/src/keybind/static/input/home.zig +++ b/src/keybind/static/input/home.zig @@ -13,7 +13,7 @@ allocator: std.mem.Allocator, f: usize = 0, leader: ?struct { keypress: u32, modifiers: u32 } = null, -pub fn create(allocator: std.mem.Allocator) !EventHandler { +pub fn create(allocator: std.mem.Allocator, _: anytype) !EventHandler { const self: *Self = try allocator.create(Self); self.* = .{ .allocator = allocator, diff --git a/src/tui/mode/input/vim/insert.zig b/src/keybind/static/input/vim/insert.zig similarity index 95% rename from src/tui/mode/input/vim/insert.zig rename to src/keybind/static/input/vim/insert.zig index 5b57972..ce4f3cc 100644 --- a/src/tui/mode/input/vim/insert.zig +++ b/src/keybind/static/input/vim/insert.zig @@ -1,28 +1,23 @@ -const tp = @import("thespian"); const std = @import("std"); - +const tp = @import("thespian"); const key = @import("renderer").input.key; const mod = @import("renderer").input.modifier; const event_type = @import("renderer").input.event_type; const ucs32_to_utf8 = @import("renderer").ucs32_to_utf8; const command = @import("command"); const EventHandler = @import("EventHandler"); - -const tui = @import("../../../tui.zig"); - -const Allocator = @import("std").mem.Allocator; -const ArrayList = @import("std").ArrayList; -const eql = @import("std").mem.eql; +const keybind = @import("../../keybind.zig"); const Self = @This(); const input_buffer_size = 1024; -allocator: Allocator, -input: ArrayList(u8), +allocator: std.mem.Allocator, +input: std.ArrayList(u8), last_cmd: []const u8 = "", leader: ?struct { keypress: u32, modifiers: u32 } = null, commands: Commands = undefined, last_key: KeyPressEvent = .{}, +enable_chording: bool, pub const KeyPressEvent = struct { keypress: u32 = 0, @@ -31,19 +26,15 @@ pub const KeyPressEvent = struct { timestamp_ms: i64 = 0, }; -pub fn create(allocator: Allocator) !tui.Mode { +pub fn create(allocator: std.mem.Allocator, opts: anytype) !EventHandler { const self: *Self = try allocator.create(Self); self.* = .{ .allocator = allocator, - .input = try ArrayList(u8).initCapacity(allocator, input_buffer_size), + .input = try std.ArrayList(u8).initCapacity(allocator, input_buffer_size), + .enable_chording = opts.enable_chording, }; try self.commands.init(self); - return .{ - .input_handler = EventHandler.to_owned(self), - .name = "INSERT", - .line_numbers = if (tui.current().config.vim_insert_gutter_line_numbers_relative) .relative else .absolute, - .cursor_shape = .beam, - }; + return EventHandler.to_owned(self); } pub fn deinit(self: *Self) void { @@ -91,7 +82,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { else => {}, } - if (tui.current().config.vim_insert_chording_keybindings) { + if (self.enable_chording) { //reset chord if enough time has passed const chord_time_window_ms = 750; @@ -337,9 +328,9 @@ fn cmd(self: *Self, name_: []const u8, ctx: command.Context) tp.result { } fn cmd_cycle3(self: *Self, name1: []const u8, name2: []const u8, name3: []const u8, ctx: command.Context) tp.result { - return if (eql(u8, self.last_cmd, name2)) + return if (std.mem.eql(u8, self.last_cmd, name2)) self.cmd(name3, ctx) - else if (eql(u8, self.last_cmd, name1)) + else if (std.mem.eql(u8, self.last_cmd, name1)) self.cmd(name2, ctx) else self.cmd(name1, ctx); @@ -350,6 +341,8 @@ fn cmd_async(self: *Self, name_: []const u8) tp.result { return tp.self_pid().send(.{ "cmd", name_ }); } +pub const hints = keybind.KeybindHints.initComptime(.{}); + const Commands = command.Collection(cmds_); const cmds_ = struct { pub const Target = Self; diff --git a/src/tui/mode/input/vim/normal.zig b/src/keybind/static/input/vim/normal.zig similarity index 97% rename from src/tui/mode/input/vim/normal.zig rename to src/keybind/static/input/vim/normal.zig index 1ccd2c2..2c62b87 100644 --- a/src/tui/mode/input/vim/normal.zig +++ b/src/keybind/static/input/vim/normal.zig @@ -1,42 +1,31 @@ +const std = @import("std"); const tp = @import("thespian"); - const key = @import("renderer").input.key; const mod = @import("renderer").input.modifier; const event_type = @import("renderer").input.event_type; const ucs32_to_utf8 = @import("renderer").ucs32_to_utf8; const command = @import("command"); const EventHandler = @import("EventHandler"); - -const tui = @import("../../../tui.zig"); - -const Allocator = @import("std").mem.Allocator; -const ArrayList = @import("std").ArrayList; -const eql = @import("std").mem.eql; +const keybind = @import("../../keybind.zig"); const Self = @This(); const input_buffer_size = 1024; -allocator: Allocator, -input: ArrayList(u8), +allocator: std.mem.Allocator, +input: std.ArrayList(u8), last_cmd: []const u8 = "", leader: ?struct { keypress: u32, modifiers: u32 } = null, count: usize = 0, commands: Commands = undefined, -pub fn create(allocator: Allocator) !tui.Mode { +pub fn create(allocator: std.mem.Allocator, _: anytype) !EventHandler { const self: *Self = try allocator.create(Self); self.* = .{ .allocator = allocator, - .input = try ArrayList(u8).initCapacity(allocator, input_buffer_size), + .input = try std.ArrayList(u8).initCapacity(allocator, input_buffer_size), }; try self.commands.init(self); - return .{ - .input_handler = EventHandler.to_owned(self), - .name = "NORMAL", - .line_numbers = if (tui.current().config.vim_normal_gutter_line_numbers_relative) .relative else .absolute, - .keybind_hints = &hints, - .cursor_shape = .block, - }; + return EventHandler.to_owned(self); } pub fn deinit(self: *Self) void { @@ -471,9 +460,9 @@ fn cmd_count(self: *Self, name_: []const u8, ctx: command.Context) tp.result { } fn cmd_cycle3(self: *Self, name1: []const u8, name2: []const u8, name3: []const u8, ctx: command.Context) tp.result { - return if (eql(u8, self.last_cmd, name2)) + return if (std.mem.eql(u8, self.last_cmd, name2)) self.cmd(name3, ctx) - else if (eql(u8, self.last_cmd, name1)) + else if (std.mem.eql(u8, self.last_cmd, name1)) self.cmd(name2, ctx) else self.cmd(name1, ctx); @@ -503,7 +492,7 @@ fn seq_count(self: *Self, cmds: anytype, ctx: command.Context) tp.result { try self.cmd(@field(cmds, field_info.name), ctx); } -const hints = tui.KeybindHints.initComptime(.{ +pub const hints = keybind.KeybindHints.initComptime(.{ .{ "add_cursor_all_matches", "C-S-l" }, .{ "add_cursor_down", "S-A-down" }, .{ "add_cursor_next_match", "C-d" }, diff --git a/src/tui/mode/input/vim/visual.zig b/src/keybind/static/input/vim/visual.zig similarity index 96% rename from src/tui/mode/input/vim/visual.zig rename to src/keybind/static/input/vim/visual.zig index 0e2ad97..09faae1 100644 --- a/src/tui/mode/input/vim/visual.zig +++ b/src/keybind/static/input/vim/visual.zig @@ -1,42 +1,31 @@ +const std = @import("std"); const tp = @import("thespian"); - const key = @import("renderer").input.key; const mod = @import("renderer").input.modifier; const event_type = @import("renderer").input.event_type; const ucs32_to_utf8 = @import("renderer").ucs32_to_utf8; const command = @import("command"); const EventHandler = @import("EventHandler"); - -const tui = @import("../../../tui.zig"); - -const Allocator = @import("std").mem.Allocator; -const ArrayList = @import("std").ArrayList; -const eql = @import("std").mem.eql; +const keybind = @import("../../keybind.zig"); const Self = @This(); const input_buffer_size = 1024; -allocator: Allocator, -input: ArrayList(u8), +allocator: std.mem.Allocator, +input: std.ArrayList(u8), last_cmd: []const u8 = "", leader: ?struct { keypress: u32, modifiers: u32 } = null, count: usize = 0, commands: Commands = undefined, -pub fn create(allocator: Allocator) !tui.Mode { +pub fn create(allocator: std.mem.Allocator, _: anytype) !EventHandler { const self: *Self = try allocator.create(Self); self.* = .{ .allocator = allocator, - .input = try ArrayList(u8).initCapacity(allocator, input_buffer_size), + .input = try std.ArrayList(u8).initCapacity(allocator, input_buffer_size), }; try self.commands.init(self); - return .{ - .input_handler = EventHandler.to_owned(self), - .name = "VISUAL", - .line_numbers = if (tui.current().config.vim_visual_gutter_line_numbers_relative) .relative else .absolute, - .keybind_hints = &hints, - .cursor_shape = .underline, - }; + return EventHandler.to_owned(self); } pub fn deinit(self: *Self) void { @@ -422,9 +411,9 @@ fn cmd_count(self: *Self, name_: []const u8, ctx: command.Context) tp.result { } fn cmd_cycle3(self: *Self, name1: []const u8, name2: []const u8, name3: []const u8, ctx: command.Context) tp.result { - return if (eql(u8, self.last_cmd, name2)) + return if (std.mem.eql(u8, self.last_cmd, name2)) self.cmd(name3, ctx) - else if (eql(u8, self.last_cmd, name1)) + else if (std.mem.eql(u8, self.last_cmd, name1)) self.cmd(name2, ctx) else self.cmd(name1, ctx); @@ -454,7 +443,7 @@ fn seq_count(self: *Self, cmds: anytype, ctx: command.Context) tp.result { try self.cmd(@field(cmds, field_info.name), ctx); } -const hints = tui.KeybindHints.initComptime(.{ +pub const hints = keybind.KeybindHints.initComptime(.{ .{ "add_cursor_all_matches", "C-S-l" }, .{ "add_cursor_down", "S-A-down" }, .{ "add_cursor_next_match", "C-d" }, diff --git a/src/keybind/static/keybind.zig b/src/keybind/static/keybind.zig index 77a0855..5a9f47f 100644 --- a/src/keybind/static/keybind.zig +++ b/src/keybind/static/keybind.zig @@ -2,6 +2,11 @@ pub const mode = struct { pub const input = struct { pub const flow = @import("input/flow.zig"); pub const home = @import("input/home.zig"); + pub const vim = struct { + pub const normal = @import("input/vim/normal.zig"); + pub const insert = @import("input/vim/insert.zig"); + pub const visual = @import("input/vim/visual.zig"); + }; }; pub const overlay = struct { pub const palette = @import("overlay/palette.zig"); diff --git a/src/tui/tui.zig b/src/tui/tui.zig index 307a615..195c716 100644 --- a/src/tui/tui.zig +++ b/src/tui/tui.zig @@ -561,11 +561,20 @@ fn enter_overlay_mode(self: *Self, mode: type) command.Result { self.refresh_hover(); } -fn static_mode(self: *Self, mode: anytype, name: []const u8) !Mode { +fn static_mode(self: *Self, mode: anytype, name: []const u8, opts: anytype) !Mode { + // .line_numbers_relative = if (self.config.vim_normal_gutter_line_numbers_relative) .relative else .absolute, return .{ - .input_handler = try mode.create(self.allocator), + .input_handler = try mode.create(self.allocator, opts), .name = name, .keybind_hints = &mode.hints, + .line_numbers = if (@hasField(@TypeOf(opts), "line_numbers_relative")) + if (opts.line_numbers_relative) + .relative + else + .absolute + else + .absolute, + .cursor_shape = if (@hasField(@TypeOf(opts), "cursor_shape")) opts.cursor_shape else .block, }; } @@ -656,11 +665,21 @@ const cmds = struct { if (self.input_mode_outer) |_| try exit_overlay_mode(self, .{}); if (self.input_mode) |*m| m.deinit(); self.input_mode = if (std.mem.eql(u8, mode, "vim/normal")) - try @import("mode/input/vim/normal.zig").create(self.allocator) + try self.static_mode(keybind.mode.input.vim.normal, "NORMAL", .{ + .line_numbers_relative = self.config.vim_normal_gutter_line_numbers_relative, + .cursor_shape = .block, + }) else if (std.mem.eql(u8, mode, "vim/insert")) - try @import("mode/input/vim/insert.zig").create(self.allocator) + try self.static_mode(keybind.mode.input.vim.insert, "INSERT", .{ + .enable_chording = self.config.vim_insert_chording_keybindings, + .line_numbers_relative = self.config.vim_insert_gutter_line_numbers_relative, + .cursor_shape = .beam, + }) else if (std.mem.eql(u8, mode, "vim/visual")) - try @import("mode/input/vim/visual.zig").create(self.allocator) + try self.static_mode(keybind.mode.input.vim.visual, "VISUAL", .{ + .line_numbers_relative = self.config.vim_visual_gutter_line_numbers_relative, + .cursor_shape = .underline, + }) else if (std.mem.eql(u8, mode, "helix/normal")) try @import("mode/input/helix/normal.zig").create(self.allocator) else if (std.mem.eql(u8, mode, "helix/insert")) @@ -668,12 +687,12 @@ const cmds = struct { else if (std.mem.eql(u8, mode, "helix/select")) try @import("mode/input/helix/select.zig").create(self.allocator) else if (std.mem.eql(u8, mode, "flow")) - try self.static_mode(keybind.mode.input.flow, "flow") + try self.static_mode(keybind.mode.input.flow, "flow", .{}) else if (std.mem.eql(u8, mode, "home")) - try self.static_mode(keybind.mode.input.home, "home") + try self.static_mode(keybind.mode.input.home, "home", .{}) else ret: { self.logger.print("unknown mode {s}", .{mode}); - break :ret try self.static_mode(keybind.mode.input.flow, "flow"); + break :ret try self.static_mode(keybind.mode.input.flow, "flow", .{}); }; // self.logger.print("input mode: {s}", .{(self.input_mode orelse return).description}); } @@ -932,10 +951,10 @@ pub const fallbacks: []const FallBack = &[_]FallBack{ .{ .ts = "repeat", .tm = "keyword.control.repeat" }, .{ .ts = "keyword.conditional", .tm = "keyword.control.conditional" }, .{ .ts = "keyword.repeat", .tm = "keyword.control.repeat" }, - .{ .ts = "keyword.modifier", .tm = "keyword.storage" }, - .{ .ts = "keyword.type", .tm = "keyword.structure" }, - .{ .ts = "keyword.function", .tm = "storage.type.function" }, - .{ .ts = "constant.builtin", .tm = "keyword.constant" }, + .{ .ts = "keyword.modifier", .tm = "keyword.storage" }, + .{ .ts = "keyword.type", .tm = "keyword.structure" }, + .{ .ts = "keyword.function", .tm = "storage.type.function" }, + .{ .ts = "constant.builtin", .tm = "keyword.constant" }, }; fn set_terminal_style(self: *Self) void {