From 9724decc4ade5757260e1e5c7b1343e2b7ad847e Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Sat, 26 Oct 2024 21:11:55 +0200 Subject: [PATCH] refactor: move move_to_char mine mode keybinds --- src/keybind/static/goto.zig | 4 +- src/keybind/static/move_to_char.zig | 56 +++++++++++++++++++++++++++ src/keybind/static/root.zig | 1 + src/tui/mode/mini/move_to_char.zig | 60 +++++++++++++++++++---------- 4 files changed, 98 insertions(+), 23 deletions(-) create mode 100644 src/keybind/static/move_to_char.zig diff --git a/src/keybind/static/goto.zig b/src/keybind/static/goto.zig index 45c0c5c..ad609c5 100644 --- a/src/keybind/static/goto.zig +++ b/src/keybind/static/goto.zig @@ -11,9 +11,7 @@ const fmt = @import("std").fmt; const Mode = @import("root.zig").Mode; pub fn create(_: Allocator) error{OutOfMemory}!Mode { - return .{ - .handler = EventHandler.static(@This()), - }; + return .{ .handler = EventHandler.static(@This()) }; } pub fn receive(_: tp.pid_ref, m: tp.message) error{Exit}!bool { diff --git a/src/keybind/static/move_to_char.zig b/src/keybind/static/move_to_char.zig new file mode 100644 index 0000000..b37add6 --- /dev/null +++ b/src/keybind/static/move_to_char.zig @@ -0,0 +1,56 @@ +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 command = @import("command"); +const EventHandler = @import("EventHandler"); + +const Allocator = @import("std").mem.Allocator; + +const Mode = @import("root.zig").Mode; + +pub fn create(_: Allocator) !Mode { + return .{ .handler = EventHandler.static(@This()) }; +} + +pub fn receive(_: tp.pid_ref, m: tp.message) error{Exit}!bool { + var evtype: u32 = undefined; + var keypress: u32 = undefined; + var modifiers: u32 = undefined; + var egc: u32 = undefined; + if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) + try mapEvent(evtype, keypress, egc, modifiers); + return false; +} + +fn mapEvent(evtype: u32, keypress: u32, egc: u32, modifiers: u32) tp.result { + switch (evtype) { + event_type.PRESS => try mapPress(keypress, egc, modifiers), + else => {}, + } +} + +fn mapPress(keypress: u32, egc: u32, modifiers: u32) tp.result { + switch (keypress) { + key.LSUPER, key.RSUPER => return, + key.LSHIFT, key.RSHIFT => return, + key.LCTRL, key.RCTRL => return, + key.LALT, key.RALT => return, + else => {}, + } + return switch (modifiers) { + mod.SHIFT => if (!key.synthesized_p(keypress)) + command.executeName("mini_mode_insert_code_point", command.fmt(.{egc})) + else + command.executeName("mini_mode_cancel", .{}), + 0 => switch (keypress) { + key.ESC => command.executeName("mini_mode_cancel", .{}), + key.ENTER => command.executeName("mini_mode_cancel", .{}), + else => if (!key.synthesized_p(keypress)) + command.executeName("mini_mode_insert_code_point", command.fmt(.{egc})) + else + command.executeName("mini_mode_cancel", .{}), + }, + else => command.executeName("mini_mode_cancel", .{}), + }; +} diff --git a/src/keybind/static/root.zig b/src/keybind/static/root.zig index ec03304..6daa480 100644 --- a/src/keybind/static/root.zig +++ b/src/keybind/static/root.zig @@ -1,6 +1,7 @@ pub const mode = struct { pub const mini = struct { pub const goto = @import("goto.zig"); + pub const move_to_char = @import("move_to_char.zig"); }; }; diff --git a/src/tui/mode/mini/move_to_char.zig b/src/tui/mode/mini/move_to_char.zig index a84a616..a57e693 100644 --- a/src/tui/mode/mini/move_to_char.zig +++ b/src/tui/mode/mini/move_to_char.zig @@ -4,6 +4,7 @@ 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 keybind = @import("keybind"); const command = @import("command"); const EventHandler = @import("EventHandler"); @@ -14,10 +15,13 @@ const Allocator = @import("std").mem.Allocator; const Self = @This(); +const Commands = command.Collection(cmds); + allocator: Allocator, key: [6]u8 = undefined, direction: Direction, operation: Operation, +commands: Commands = undefined, const Direction = enum { left, @@ -39,17 +43,18 @@ pub fn create(allocator: Allocator, ctx: command.Context) !struct { tui.Mode, tu .direction = if (right) .right else .left, .operation = if (select) .select else .move, }; + try self.commands.init(self); return .{ + try keybind.mode.mini.move_to_char.create(allocator), .{ - .handler = EventHandler.to_owned(self), - }, - .{ + .event_handler = EventHandler.to_owned(self), .name = self.name(), }, }; } pub fn deinit(self: *Self) void { + self.commands.deinit(); self.allocator.destroy(self); } @@ -66,23 +71,10 @@ fn name(self: *Self) []const u8 { }; } -pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { - var evtype: u32 = undefined; - var keypress: u32 = undefined; - var modifiers: u32 = undefined; - var egc: u32 = undefined; - if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) - try self.mapEvent(evtype, keypress, egc, modifiers); +pub fn receive(_: *Self, _: tp.pid_ref, _: tp.message) error{Exit}!bool { return false; } -fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) tp.result { - switch (evtype) { - event_type.PRESS => try self.mapPress(keypress, egc, modifiers), - else => {}, - } -} - fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { switch (keypress) { key.LSUPER, key.RSUPER => return, @@ -119,6 +111,34 @@ fn execute_operation(self: *Self, c: u32) void { command.executeName("exit_mini_mode", .{}) catch {}; } -fn cancel(_: *Self) void { - command.executeName("exit_mini_mode", .{}) catch {}; -} +const cmds = struct { + pub const Target = Self; + const Ctx = command.Context; + const Result = command.Result; + + pub fn mini_mode_insert_code_point(self: *Self, ctx: Ctx) Result { + var code_point: u32 = 0; + if (!try ctx.args.match(.{tp.extract(&code_point)})) + return error.InvalidArgument; + var buf: [6]u8 = undefined; + const bytes = ucs32_to_utf8(&[_]u32{code_point}, &buf) catch return error.InvalidArgument; + const cmd = switch (self.direction) { + .left => switch (self.operation) { + .move => "move_to_char_left", + .select => "select_to_char_left", + }, + .right => switch (self.operation) { + .move => "move_to_char_right", + .select => "select_to_char_right", + }, + }; + try command.executeName(cmd, command.fmt(.{buf[0..bytes]})); + try command.executeName("exit_mini_mode", .{}); + } + pub const mini_mode_insert_code_point_meta = .{ .interactive = false }; + + pub fn mini_mode_cancel(_: *Self, _: Ctx) Result { + command.executeName("exit_mini_mode", .{}) catch {}; + } + pub const mini_mode_cancel_meta = .{ .description = "Cancel input" }; +};