diff --git a/build.zig b/build.zig index 601fe2e..eb48955 100644 --- a/build.zig +++ b/build.zig @@ -146,10 +146,18 @@ pub fn build(b: *std.Build) void { }, }); + const input_mod = b.createModule(.{ + .root_source_file = b.path("src/renderer/vaxis/input.zig"), + .imports = &.{ + .{ .name = "vaxis", .module = vaxis_mod }, + }, + }); + const renderer_mod = b.createModule(.{ .root_source_file = b.path("src/renderer/vaxis/renderer.zig"), .imports = &.{ .{ .name = "vaxis", .module = vaxis_mod }, + .{ .name = "input", .module = input_mod }, .{ .name = "theme", .module = themes_dep.module("theme") }, .{ .name = "cbor", .module = cbor_mod }, .{ .name = "log", .module = log_mod }, @@ -165,7 +173,7 @@ pub fn build(b: *std.Build) void { .{ .name = "cbor", .module = cbor_mod }, .{ .name = "command", .module = command_mod }, .{ .name = "EventHandler", .module = EventHandler_mod }, - .{ .name = "renderer", .module = renderer_mod }, + .{ .name = "input", .module = input_mod }, .{ .name = "thespian", .module = thespian_mod }, }, }); @@ -175,7 +183,7 @@ pub fn build(b: *std.Build) void { .{ .name = "cbor", .module = cbor_mod }, .{ .name = "command", .module = command_mod }, .{ .name = "EventHandler", .module = EventHandler_mod }, - .{ .name = "renderer", .module = renderer_mod }, + .{ .name = "input", .module = input_mod }, .{ .name = "thespian", .module = thespian_mod }, .{ .name = "log", .module = log_mod }, }, @@ -191,7 +199,7 @@ pub fn build(b: *std.Build) void { tests.root_module.addImport("cbor", cbor_mod); tests.root_module.addImport("command", command_mod); tests.root_module.addImport("EventHandler", EventHandler_mod); - tests.root_module.addImport("renderer", renderer_mod); + tests.root_module.addImport("input", input_mod); tests.root_module.addImport("thespian", thespian_mod); tests.root_module.addImport("log", log_mod); // b.installArtifact(tests); @@ -249,6 +257,7 @@ pub fn build(b: *std.Build) void { .root_source_file = b.path("src/tui/tui.zig"), .imports = &.{ .{ .name = "renderer", .module = renderer_mod }, + .{ .name = "input", .module = input_mod }, .{ .name = "thespian", .module = thespian_mod }, .{ .name = "cbor", .module = cbor_mod }, .{ .name = "config", .module = config_mod }, @@ -297,6 +306,7 @@ pub fn build(b: *std.Build) void { exe.root_module.addImport("log", log_mod); exe.root_module.addImport("tracy", tracy_mod); exe.root_module.addImport("renderer", renderer_mod); + exe.root_module.addImport("input", input_mod); exe.root_module.addImport("syntax", syntax_mod); exe.root_module.addImport("version_info", b.createModule(.{ .root_source_file = version_info_file })); b.installArtifact(exe); @@ -326,6 +336,7 @@ pub fn build(b: *std.Build) void { check_exe.root_module.addImport("log", log_mod); check_exe.root_module.addImport("tracy", tracy_mod); check_exe.root_module.addImport("renderer", renderer_mod); + check_exe.root_module.addImport("input", input_mod); check_exe.root_module.addImport("syntax", syntax_mod); check_exe.root_module.addImport("version_info", b.createModule(.{ .root_source_file = version_info_file })); const check = b.step("check", "Check the app"); diff --git a/src/keybind/dynamic/KeyEvent.zig b/src/keybind/dynamic/KeyEvent.zig new file mode 100644 index 0000000..8f1eea8 --- /dev/null +++ b/src/keybind/dynamic/KeyEvent.zig @@ -0,0 +1,10 @@ +const std = @import("std"); +const input = @import("input"); + +key: input.Key = 0, +event: input.Event = input.event.press, +modifiers: input.Mods = 0, + +pub fn eql(self: @This(), other: @This()) bool { + return std.meta.eql(self, other); +} diff --git a/src/keybind/dynamic/keybind.zig b/src/keybind/dynamic/keybind.zig index 50306f7..e945ade 100644 --- a/src/keybind/dynamic/keybind.zig +++ b/src/keybind/dynamic/keybind.zig @@ -8,14 +8,12 @@ const cbor = @import("cbor"); const builtin = @import("builtin"); const log = @import("log"); -const renderer = @import("renderer"); -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 input = @import("input"); const command = @import("command"); const EventHandler = @import("EventHandler"); +const KeyEvent = @import("KeyEvent.zig"); + pub const mode = struct { pub const input = struct { pub const flow = Handler("flow", "normal"); @@ -73,7 +71,7 @@ pub const Mode = struct { name: []const u8 = "", line_numbers: enum { absolute, relative } = .absolute, keybind_hints: ?*const KeybindHints = null, - cursor_shape: renderer.CursorShape = .block, + cursor_shape: CursorShape = .block, pub fn deinit(self: *Mode) void { self.input_handler.deinit(); @@ -83,17 +81,6 @@ pub const Mode = struct { pub const KeybindHints = std.static_string_map.StaticStringMap([]const u8); -//A single key event, such as Ctrl-E -const KeyEvent = struct { - key: u32 = 0, //keypress value - event_type: usize = event_type.PRESS, - modifiers: u32 = 0, - - fn eql(self: @This(), other: @This()) bool { - return std.meta.eql(self, other); - } -}; - fn peek(str: []const u8, i: usize) !u8 { if (i + 1 < str.len) { return str[i + 1]; @@ -121,7 +108,7 @@ pub fn parse_key_events(allocator: std.mem.Allocator, str: []const u8) ![]KeyEve }; var state: State = .base; var function_key_number: u8 = 0; - var modifiers: u32 = 0; + var modifiers: input.Mods = 0; var result = std.ArrayList(KeyEvent).init(allocator); defer result.deinit(); @@ -213,7 +200,7 @@ pub fn parse_key_events(allocator: std.mem.Allocator, str: []const u8) ![]KeyEve }, .cr => { if (std.mem.indexOf(u8, str[i..], "CR") == 0) { - try result.append(.{ .key = key.ENTER, .modifiers = modifiers }); + try result.append(.{ .key = input.key.enter, .modifiers = modifiers }); modifiers = 0; state = .escape_sequence_end; i += 2; @@ -221,7 +208,7 @@ pub fn parse_key_events(allocator: std.mem.Allocator, str: []const u8) ![]KeyEve }, .space => { if (std.mem.indexOf(u8, str[i..], "Space") == 0) { - try result.append(.{ .key = key.SPACE, .modifiers = modifiers }); + try result.append(.{ .key = input.key.space, .modifiers = modifiers }); modifiers = 0; state = .escape_sequence_end; i += 5; @@ -232,7 +219,7 @@ pub fn parse_key_events(allocator: std.mem.Allocator, str: []const u8) ![]KeyEve }, .del => { if (std.mem.indexOf(u8, str[i..], "Del") == 0) { - try result.append(.{ .key = key.DEL, .modifiers = modifiers }); + try result.append(.{ .key = input.key.delete, .modifiers = modifiers }); modifiers = 0; state = .escape_sequence_end; i += 3; @@ -240,7 +227,7 @@ pub fn parse_key_events(allocator: std.mem.Allocator, str: []const u8) ![]KeyEve }, .tab => { if (std.mem.indexOf(u8, str[i..], "Tab") == 0) { - try result.append(.{ .key = key.TAB, .modifiers = modifiers }); + try result.append(.{ .key = input.key.tab, .modifiers = modifiers }); modifiers = 0; state = .escape_sequence_end; i += 3; @@ -248,7 +235,7 @@ pub fn parse_key_events(allocator: std.mem.Allocator, str: []const u8) ![]KeyEve }, .up => { if (std.mem.indexOf(u8, str[i..], "Up") == 0) { - try result.append(.{ .key = key.UP, .modifiers = modifiers }); + try result.append(.{ .key = input.key.up, .modifiers = modifiers }); modifiers = 0; state = .escape_sequence_end; i += 2; @@ -256,7 +243,7 @@ pub fn parse_key_events(allocator: std.mem.Allocator, str: []const u8) ![]KeyEve }, .esc => { if (std.mem.indexOf(u8, str[i..], "Esc") == 0) { - try result.append(.{ .key = key.ESC, .modifiers = modifiers }); + try result.append(.{ .key = input.key.escape, .modifiers = modifiers }); modifiers = 0; state = .escape_sequence_end; i += 3; @@ -264,7 +251,7 @@ pub fn parse_key_events(allocator: std.mem.Allocator, str: []const u8) ![]KeyEve }, .down => { if (std.mem.indexOf(u8, str[i..], "Down") == 0) { - try result.append(.{ .key = key.DOWN, .modifiers = modifiers }); + try result.append(.{ .key = input.key.down, .modifiers = modifiers }); modifiers = 0; state = .escape_sequence_end; i += 4; @@ -272,7 +259,7 @@ pub fn parse_key_events(allocator: std.mem.Allocator, str: []const u8) ![]KeyEve }, .left => { if (std.mem.indexOf(u8, str[i..], "Left") == 0) { - try result.append(.{ .key = key.LEFT, .modifiers = modifiers }); + try result.append(.{ .key = input.key.left, .modifiers = modifiers }); modifiers = 0; state = .escape_sequence_end; i += 4; @@ -280,7 +267,7 @@ pub fn parse_key_events(allocator: std.mem.Allocator, str: []const u8) ![]KeyEve }, .right => { if (std.mem.indexOf(u8, str[i..], "Right") == 0) { - try result.append(.{ .key = key.RIGHT, .modifiers = modifiers }); + try result.append(.{ .key = input.key.right, .modifiers = modifiers }); modifiers = 0; state = .escape_sequence_end; i += 5; @@ -298,7 +285,7 @@ pub fn parse_key_events(allocator: std.mem.Allocator, str: []const u8) ![]KeyEve i += 1; }, '>' => { - const function_key = key.F01 - 1 + function_key_number; + const function_key = input.key.f1 - 1 + function_key_number; try result.append(.{ .key = function_key, .modifiers = modifiers }); modifiers = 0; function_key_number = 0; @@ -334,10 +321,10 @@ pub fn parse_key_events(allocator: std.mem.Allocator, str: []const u8) ![]KeyEve }, .modifier => { modifiers |= switch (str[i]) { - 'A' => mod.ALT, - 'C' => mod.CTRL, - 'D' => mod.SUPER, - 'S' => mod.SHIFT, + 'A' => input.mod.alt, + 'C' => input.mod.ctrl, + 'D' => input.mod.super, + 'S' => input.mod.shift, else => return error.parseModifier, }; @@ -552,22 +539,22 @@ const BindingSet = struct { } fn receive(self: *@This(), _: tp.pid_ref, m: tp.message) error{Exit}!bool { - var evtype: u32 = 0; - var keypress: u32 = 0; - var egc: u32 = 0; - var modifiers: u32 = 0; + var event: input.Event = 0; + var keypress: input.Key = 0; + var egc: input.Key = 0; + var modifiers: input.Mods = 0; var text: []const u8 = ""; if (try m.match(.{ "I", - tp.extract(&evtype), + tp.extract(&event), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers), })) { self.process_key_event(egc, .{ - .event_type = evtype, + .event = event, .key = keypress, .modifiers = modifiers, }) catch |e| return tp.exit_error(e, @errorReturnTrace()); @@ -582,10 +569,10 @@ const BindingSet = struct { } //register a key press and try to match it with a binding - fn process_key_event(self: *BindingSet, egc: u32, event: KeyEvent) !void { + fn process_key_event(self: *BindingSet, egc: input.Key, event: KeyEvent) !void { //hacky fix since we are ignoring repeats and keyups right now - if (event.event_type != event_type.PRESS) return; + if (event.event != input.event.press) return; //clear key history if enough time has passed since last key press const timestamp = std.time.milliTimestamp(); @@ -596,7 +583,7 @@ const BindingSet = struct { try self.current_sequence.append(event); var buf: [6]u8 = undefined; - const bytes = try ucs32_to_utf8(&[_]u32{egc}, &buf); + const bytes = try input.ucs32_to_utf8(&[_]u32{egc}, &buf); try self.current_sequence_egc.appendSlice(buf[0..bytes]); var all_matches_impossible = true; @@ -641,7 +628,7 @@ const BindingSet = struct { } const AbortType = enum { timeout, match_impossible }; - fn terminate_sequence(self: *@This(), abort_type: AbortType, egc: u32, key_event: KeyEvent) anyerror!void { + fn terminate_sequence(self: *@This(), abort_type: AbortType, egc: input.Key, key_event: KeyEvent) anyerror!void { _ = egc; _ = key_event; if (abort_type == .match_impossible) { @@ -692,16 +679,26 @@ const Namespace = struct { } }; +pub const CursorShape = enum { + default, + block_blink, + block, + underline_blink, + underline, + beam_blink, + beam, +}; + const expectEqual = std.testing.expectEqual; const parse_test_cases = .{ //input, expected .{ "j", &.{KeyEvent{ .key = 'j' }} }, .{ "jk", &.{ KeyEvent{ .key = 'j' }, KeyEvent{ .key = 'k' } } }, - .{ "", &.{KeyEvent{ .key = key.SPACE }} }, - .{ "", &.{ KeyEvent{ .key = 'x', .modifiers = mod.CTRL }, KeyEvent{ .key = 'c', .modifiers = mod.CTRL } } }, - .{ "", &.{ KeyEvent{ .key = 'x', .modifiers = mod.ALT }, KeyEvent{ .key = key.TAB } } }, - .{ "", &.{ KeyEvent{ .key = 'x', .modifiers = mod.ALT | mod.SHIFT }, KeyEvent{ .key = key.DEL, .modifiers = mod.SUPER } } }, + .{ "", &.{KeyEvent{ .key = input.key.space }} }, + .{ "", &.{ KeyEvent{ .key = 'x', .modifiers = input.mod.ctrl }, KeyEvent{ .key = 'c', .modifiers = input.mod.ctrl } } }, + .{ "", &.{ KeyEvent{ .key = 'x', .modifiers = input.mod.alt }, KeyEvent{ .key = input.key.tab } } }, + .{ "", &.{ KeyEvent{ .key = 'x', .modifiers = input.mod.alt | input.mod.shift }, KeyEvent{ .key = input.key.delete, .modifiers = input.mod.super } } }, }; test "parse" { @@ -733,8 +730,8 @@ const match_test_cases = .{ test "match" { const alloc = std.testing.allocator; inline for (match_test_cases) |case| { - const input = try parse_key_events(alloc, case[0]); - defer alloc.free(input); + const events = try parse_key_events(alloc, case[0]); + defer alloc.free(events); const binding: Binding = .{ .keys = try parse_key_events(alloc, case[1]), .command = undefined, @@ -742,7 +739,7 @@ test "match" { }; defer alloc.free(binding.keys); - try expectEqual(case[2], binding.match(input)); + try expectEqual(case[2], binding.match(events)); } } @@ -754,5 +751,5 @@ test "json" { try bindings.process_key_event('k', .{ .key = 'k' }); try bindings.process_key_event('g', .{ .key = 'g' }); try bindings.process_key_event('i', .{ .key = 'i' }); - try bindings.process_key_event(0, .{ .key = 'i', .modifiers = mod.CTRL }); + try bindings.process_key_event(0, .{ .key = 'i', .modifiers = input.mod.ctrl }); } diff --git a/src/keybind/static/input/flow.zig b/src/keybind/static/input/flow.zig index 6bd743e..5454ce2 100644 --- a/src/keybind/static/input/flow.zig +++ b/src/keybind/static/input/flow.zig @@ -1,9 +1,6 @@ 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 input = @import("input"); const command = @import("command"); const EventHandler = @import("EventHandler"); const keybind = @import("../keybind.zig"); @@ -14,7 +11,7 @@ const input_buffer_size = 1024; allocator: std.mem.Allocator, input: std.ArrayList(u8), last_cmd: []const u8 = "", -leader: ?struct { keypress: u32, modifiers: u32 } = null, +leader: ?struct { keypress: input.Key, modifiers: input.Mods } = null, pub fn create(allocator: std.mem.Allocator, _: anytype) !EventHandler { const self: *Self = try allocator.create(Self); @@ -31,14 +28,14 @@ pub fn deinit(self: *Self) void { } pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { - var evtype: u32 = undefined; - var keypress: u32 = undefined; - var egc: u32 = undefined; - var modifiers: u32 = undefined; + var event: input.Event = undefined; + var keypress: input.Key = undefined; + var egc: input.Key = undefined; + var modifiers: input.Mods = undefined; var text: []const u8 = undefined; - if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { - self.mapEvent(evtype, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); + if (try m.match(.{ "I", tp.extract(&event), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { + self.map_event(event, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{"F"})) { self.flush_input() catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{ "system_clipboard", tp.extract(&text) })) { @@ -49,25 +46,25 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { pub fn add_keybind() void {} -fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) !void { - return switch (evtype) { - event_type.PRESS => self.mapPress(keypress, egc, modifiers), - event_type.REPEAT => self.mapPress(keypress, egc, modifiers), - event_type.RELEASE => self.mapRelease(keypress, egc, modifiers), +fn map_event(self: *Self, event: input.Event, keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { + return switch (event) { + input.event.press => self.map_press(keypress, egc, modifiers), + input.event.repeat => self.map_press(keypress, egc, modifiers), + input.event.release => self.map_release(keypress, egc, modifiers), else => {}, }; } -fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { +fn map_press(self: *Self, keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { const keynormal = if ('a' <= keypress and keypress <= 'z') keypress - ('a' - 'A') else keypress; - if (self.leader) |_| return self.mapFollower(keynormal, egc, modifiers); + if (self.leader) |_| return self.map_follower(keynormal, modifiers); switch (keypress) { - key.LCTRL, key.RCTRL => return self.cmd("enable_fast_scroll", .{}), - key.LALT, key.RALT => return self.cmd("enable_jump_mode", .{}), + input.key.left_control, input.key.right_control => return self.cmd("enable_fast_scroll", .{}), + input.key.left_alt, input.key.right_alt => return self.cmd("enable_jump_mode", .{}), else => {}, } return switch (modifiers) { - mod.CTRL => switch (keynormal) { + input.mod.ctrl => switch (keynormal) { 'E' => self.cmd("open_recent", .{}), 'R' => self.cmd("open_recent_project", .{}), 'J' => self.cmd("toggle_panel", .{}), @@ -93,24 +90,24 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 'A' => self.cmd("select_all", .{}), 'I' => self.insert_bytes("\t"), '/' => self.cmd("toggle_comment", .{}), - key.ENTER => self.cmd("smart_insert_line_after", .{}), - key.SPACE => self.cmd("completion", .{}), - key.END => self.cmd("move_buffer_end", .{}), - key.HOME => self.cmd("move_buffer_begin", .{}), - key.UP => self.cmd("move_scroll_up", .{}), - key.DOWN => self.cmd("move_scroll_down", .{}), - key.PGUP => self.cmd("move_scroll_page_up", .{}), - key.PGDOWN => self.cmd("move_scroll_page_down", .{}), - key.LEFT => self.cmd("move_word_left", .{}), - key.RIGHT => self.cmd("move_word_right", .{}), - key.BACKSPACE => self.cmd("delete_word_left", .{}), - key.DEL => self.cmd("delete_word_right", .{}), - key.F05 => self.cmd("toggle_inspector_view", .{}), - key.F10 => self.cmd("toggle_whitespace_mode", .{}), // aka F34 - key.F12 => self.cmd("goto_implementation", .{}), + input.key.enter => self.cmd("smart_insert_line_after", .{}), + input.key.space => self.cmd("completion", .{}), + input.key.end => self.cmd("move_buffer_end", .{}), + input.key.home => self.cmd("move_buffer_begin", .{}), + input.key.up => self.cmd("move_scroll_up", .{}), + input.key.down => self.cmd("move_scroll_down", .{}), + input.key.page_up => self.cmd("move_scroll_page_up", .{}), + input.key.page_down => self.cmd("move_scroll_page_down", .{}), + input.key.left => self.cmd("move_word_left", .{}), + input.key.right => self.cmd("move_word_right", .{}), + input.key.backspace => self.cmd("delete_word_left", .{}), + input.key.delete => self.cmd("delete_word_right", .{}), + input.key.f5 => self.cmd("toggle_inspector_view", .{}), + input.key.f10 => self.cmd("toggle_whitespace_mode", .{}), // aka F34 + input.key.f12 => self.cmd("goto_implementation", .{}), else => {}, }, - mod.CTRL | mod.SHIFT => switch (keynormal) { + input.mod.ctrl | input.mod.shift => switch (keynormal) { 'S' => self.cmd("save_as", .{}), 'P' => self.cmd("open_command_palette", .{}), 'D' => self.cmd("dupe_down", .{}), @@ -121,17 +118,17 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 'L' => self.cmd_async("add_cursor_all_matches"), 'I' => self.cmd_async("toggle_inspector_view"), 'M' => self.cmd("show_diagnostics", .{}), - key.ENTER => self.cmd("smart_insert_line_before", .{}), - key.END => self.cmd("select_buffer_end", .{}), - key.HOME => self.cmd("select_buffer_begin", .{}), - key.UP => self.cmd("select_scroll_up", .{}), - key.DOWN => self.cmd("select_scroll_down", .{}), - key.LEFT => self.cmd("select_word_left", .{}), - key.RIGHT => self.cmd("select_word_right", .{}), - key.SPACE => self.cmd("selections_reverse", .{}), + input.key.enter => self.cmd("smart_insert_line_before", .{}), + input.key.end => self.cmd("select_buffer_end", .{}), + input.key.home => self.cmd("select_buffer_begin", .{}), + input.key.up => self.cmd("select_scroll_up", .{}), + input.key.down => self.cmd("select_scroll_down", .{}), + input.key.left => self.cmd("select_word_left", .{}), + input.key.right => self.cmd("select_word_right", .{}), + input.key.space => self.cmd("selections_reverse", .{}), else => {}, }, - mod.ALT => switch (keynormal) { + input.mod.alt => switch (keynormal) { 'O' => self.cmd("open_previous_file", .{}), 'J' => self.cmd("join_next_line", .{}), 'N' => self.cmd("goto_next_file_or_diagnostic", .{}), @@ -145,16 +142,16 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 'S' => self.cmd("filter", command.fmt(.{"sort"})), 'V' => self.cmd("paste", .{}), 'X' => self.cmd("open_command_palette", .{}), - key.LEFT => self.cmd("jump_back", .{}), - key.RIGHT => self.cmd("jump_forward", .{}), - key.UP => self.cmd("pull_up", .{}), - key.DOWN => self.cmd("pull_down", .{}), - key.ENTER => self.cmd("insert_line", .{}), - key.F10 => self.cmd("gutter_mode_next", .{}), // aka F58 - key.F12 => self.cmd("goto_declaration", .{}), + input.key.left => self.cmd("jump_back", .{}), + input.key.right => self.cmd("jump_forward", .{}), + input.key.up => self.cmd("pull_up", .{}), + input.key.down => self.cmd("pull_down", .{}), + input.key.enter => self.cmd("insert_line", .{}), + input.key.f10 => self.cmd("gutter_mode_next", .{}), // aka F58 + input.key.f12 => self.cmd("goto_declaration", .{}), else => {}, }, - mod.ALT | mod.SHIFT => switch (keynormal) { + input.mod.alt | input.mod.shift => switch (keynormal) { 'P' => self.cmd("open_command_palette", .{}), 'D' => self.cmd("dupe_up", .{}), // 'B' => self.cmd("select_word_left", .{}), @@ -163,61 +160,60 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 'S' => self.cmd("filter", command.fmt(.{ "sort", "-u" })), 'V' => self.cmd("paste", .{}), 'I' => self.cmd("add_cursors_to_line_ends", .{}), - key.LEFT => self.cmd("shrink_selection", .{}), - key.RIGHT => self.cmd("expand_selection", .{}), - key.HOME => self.cmd("move_scroll_left", .{}), - key.END => self.cmd("move_scroll_right", .{}), - key.UP => self.cmd("add_cursor_up", .{}), - key.DOWN => self.cmd("add_cursor_down", .{}), - key.F12 => self.cmd("goto_type_definition", .{}), + input.key.left => self.cmd("shrink_selection", .{}), + input.key.right => self.cmd("expand_selection", .{}), + input.key.home => self.cmd("move_scroll_left", .{}), + input.key.end => self.cmd("move_scroll_right", .{}), + input.key.up => self.cmd("add_cursor_up", .{}), + input.key.down => self.cmd("add_cursor_down", .{}), + input.key.f12 => self.cmd("goto_type_definition", .{}), else => {}, }, - mod.SHIFT => switch (keypress) { - key.F03 => self.cmd("goto_prev_match", .{}), - key.F10 => self.cmd("toggle_syntax_highlighting", .{}), - key.F12 => self.cmd("references", .{}), - key.LEFT => self.cmd("select_left", .{}), - key.RIGHT => self.cmd("select_right", .{}), - key.UP => self.cmd("select_up", .{}), - key.DOWN => self.cmd("select_down", .{}), - key.HOME => self.cmd("smart_select_begin", .{}), - key.END => self.cmd("select_end", .{}), - key.PGUP => self.cmd("select_page_up", .{}), - key.PGDOWN => self.cmd("select_page_down", .{}), - key.ENTER => self.cmd("smart_insert_line_before", .{}), - key.BACKSPACE => self.cmd("delete_backward", .{}), - key.TAB => self.cmd("unindent", .{}), - else => if (!key.synthesized_p(keypress)) + input.mod.shift => switch (keypress) { + input.key.f3 => self.cmd("goto_prev_match", .{}), + input.key.f10 => self.cmd("toggle_syntax_highlighting", .{}), + input.key.f12 => self.cmd("references", .{}), + input.key.left => self.cmd("select_left", .{}), + input.key.right => self.cmd("select_right", .{}), + input.key.up => self.cmd("select_up", .{}), + input.key.down => self.cmd("select_down", .{}), + input.key.home => self.cmd("smart_select_begin", .{}), + input.key.end => self.cmd("select_end", .{}), + input.key.page_up => self.cmd("select_page_up", .{}), + input.key.page_down => self.cmd("select_page_down", .{}), + input.key.enter => self.cmd("smart_insert_line_before", .{}), + input.key.backspace => self.cmd("delete_backward", .{}), + input.key.tab => self.cmd("unindent", .{}), + else => if (!input.is_non_input_key(keypress)) self.insert_code_point(egc) else {}, }, 0 => switch (keypress) { - key.F02 => self.cmd("toggle_input_mode", .{}), - key.F03 => self.cmd("goto_next_match", .{}), - key.F15 => self.cmd("goto_prev_match", .{}), // S-F3 - key.F05 => self.cmd("toggle_inspector_view", .{}), // C-F5 - key.F06 => self.cmd("dump_current_line_tree", .{}), - key.F07 => self.cmd("dump_current_line", .{}), - key.F09 => self.cmd("theme_prev", .{}), - key.F10 => self.cmd("theme_next", .{}), - key.F11 => self.cmd("toggle_panel", .{}), - key.F12 => self.cmd("goto_definition", .{}), - key.F34 => self.cmd("toggle_whitespace_mode", .{}), // C-F10 - key.F58 => self.cmd("gutter_mode_next", .{}), // A-F10 - key.ESC => self.cmd("cancel", .{}), - key.ENTER => self.cmd("smart_insert_line", .{}), - key.DEL => self.cmd("delete_forward", .{}), - key.BACKSPACE => self.cmd("delete_backward", .{}), - key.LEFT => self.cmd("move_left", .{}), - key.RIGHT => self.cmd("move_right", .{}), - key.UP => self.cmd("move_up", .{}), - key.DOWN => self.cmd("move_down", .{}), - key.HOME => self.cmd("smart_move_begin", .{}), - key.END => self.cmd("move_end", .{}), - key.PGUP => self.cmd("move_page_up", .{}), - key.PGDOWN => self.cmd("move_page_down", .{}), - key.TAB => self.cmd("indent", .{}), - else => if (!key.synthesized_p(keypress)) + input.key.f2 => self.cmd("toggle_input_mode", .{}), + input.key.f3 => self.cmd("goto_next_match", .{}), + input.key.f15 => self.cmd("goto_prev_match", .{}), // S-F3 + input.key.f5 => self.cmd("toggle_inspector_view", .{}), // C-F5 + input.key.f6 => self.cmd("dump_current_line_tree", .{}), + input.key.f7 => self.cmd("dump_current_line", .{}), + input.key.f9 => self.cmd("theme_prev", .{}), + input.key.f10 => self.cmd("theme_next", .{}), + input.key.f11 => self.cmd("toggle_panel", .{}), + input.key.f12 => self.cmd("goto_definition", .{}), + input.key.f34 => self.cmd("toggle_whitespace_mode", .{}), // C-F10 + input.key.escape => self.cmd("cancel", .{}), + input.key.enter => self.cmd("smart_insert_line", .{}), + input.key.delete => self.cmd("delete_forward", .{}), + input.key.backspace => self.cmd("delete_backward", .{}), + input.key.left => self.cmd("move_left", .{}), + input.key.right => self.cmd("move_right", .{}), + input.key.up => self.cmd("move_up", .{}), + input.key.down => self.cmd("move_down", .{}), + input.key.home => self.cmd("smart_move_begin", .{}), + input.key.end => self.cmd("move_end", .{}), + input.key.page_up => self.cmd("move_page_up", .{}), + input.key.page_down => self.cmd("move_page_down", .{}), + input.key.tab => self.cmd("indent", .{}), + else => if (!input.is_non_input_key(keypress)) self.insert_code_point(egc) else {}, }, @@ -225,13 +221,13 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { }; } -fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) !void { +fn map_follower(self: *Self, keypress: input.Key, modifiers: input.Mods) !void { defer self.leader = null; const ldr = if (self.leader) |leader| leader else return; return switch (ldr.modifiers) { - mod.CTRL => switch (ldr.keypress) { + input.mod.ctrl => switch (ldr.keypress) { 'K' => switch (modifiers) { - mod.CTRL => switch (keypress) { + input.mod.ctrl => switch (keypress) { 'U' => self.cmd("delete_to_begin", .{}), 'K' => self.cmd("delete_to_end", .{}), 'D' => self.cmd("move_cursor_next_match", .{}), @@ -247,10 +243,10 @@ fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) !void { }; } -fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) !void { +fn map_release(self: *Self, keypress: input.Key, _: u32, _: u32) !void { return switch (keypress) { - key.LCTRL, key.RCTRL => self.cmd("disable_fast_scroll", .{}), - key.LALT, key.RALT => self.cmd("disable_jump_mode", .{}), + input.key.left_control, input.key.right_control => self.cmd("disable_fast_scroll", .{}), + input.key.left_alt, input.key.right_alt => self.cmd("disable_jump_mode", .{}), else => {}, }; } @@ -259,7 +255,7 @@ fn insert_code_point(self: *Self, c: u32) !void { if (self.input.items.len + 4 > input_buffer_size) try self.flush_input(); var buf: [6]u8 = undefined; - const bytes = try ucs32_to_utf8(&[_]u32{c}, &buf); + const bytes = try input.ucs32_to_utf8(&[_]u32{c}, &buf); try self.input.appendSlice(buf[0..bytes]); } diff --git a/src/keybind/static/input/helix/insert.zig b/src/keybind/static/input/helix/insert.zig index 5458cb3..52515ea 100644 --- a/src/keybind/static/input/helix/insert.zig +++ b/src/keybind/static/input/helix/insert.zig @@ -1,9 +1,6 @@ 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 input = @import("input"); const command = @import("command"); const EventHandler = @import("EventHandler"); const keybind = @import("../../keybind.zig"); @@ -14,7 +11,7 @@ const input_buffer_size = 1024; allocator: std.mem.Allocator, input: std.ArrayList(u8), last_cmd: []const u8 = "", -leader: ?struct { keypress: u32, modifiers: u32 } = null, +leader: ?struct { keypress: input.Key, modifiers: input.Mods } = null, commands: Commands = undefined, pub fn create(allocator: std.mem.Allocator, _: anytype) !EventHandler { @@ -34,14 +31,14 @@ pub fn deinit(self: *Self) void { } pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { - var evtype: u32 = undefined; - var keypress: u32 = undefined; - var egc: u32 = undefined; - var modifiers: u32 = undefined; + var event: input.Event = undefined; + var keypress: input.Key = undefined; + var egc: input.Key = undefined; + var modifiers: input.Mods = undefined; var text: []const u8 = undefined; - if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { - self.mapEvent(evtype, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); + if (try m.match(.{ "I", tp.extract(&event), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { + self.mapEvent(event, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{"F"})) { self.flush_input() catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{ "system_clipboard", tp.extract(&text) })) { @@ -54,25 +51,25 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { pub fn add_keybind() void {} -fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) !void { - return switch (evtype) { - event_type.PRESS => self.mapPress(keypress, egc, modifiers), - event_type.REPEAT => self.mapPress(keypress, egc, modifiers), - event_type.RELEASE => self.mapRelease(keypress, egc, modifiers), +fn mapEvent(self: *Self, event: input.Event, keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { + return switch (event) { + input.event.press => self.map_press(keypress, egc, modifiers), + input.event.repeat => self.map_press(keypress, egc, modifiers), + input.event.release => self.map_release(keypress), else => {}, }; } -fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { +fn map_press(self: *Self, keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { const keynormal = if ('a' <= keypress and keypress <= 'z') keypress - ('a' - 'A') else keypress; - if (self.leader) |_| return self.mapFollower(keynormal, egc, modifiers); + if (self.leader) |_| return self.map_follower(keynormal, modifiers); switch (keypress) { - key.LCTRL, key.RCTRL => return self.cmd("enable_fast_scroll", .{}), - key.LALT, key.RALT => return self.cmd("enable_jump_mode", .{}), + input.key.left_control, input.key.right_control => return self.cmd("enable_fast_scroll", .{}), + input.key.left_alt, input.key.right_alt => return self.cmd("enable_jump_mode", .{}), else => {}, } return switch (modifiers) { - mod.CTRL => switch (keynormal) { + input.mod.ctrl => switch (keynormal) { 'E' => self.cmd("open_recent", .{}), 'U' => self.cmd("move_scroll_page_up", .{}), 'D' => self.cmd("move_scroll_page_down", .{}), @@ -97,23 +94,23 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 'A' => self.cmd("select_all", .{}), 'I' => self.insert_bytes("\t"), '/' => self.cmd("toggle_comment", .{}), - key.ENTER => self.cmd("smart_insert_line_after", .{}), - key.SPACE => self.cmd("selections_reverse", .{}), - key.END => self.cmd("move_buffer_end", .{}), - key.HOME => self.cmd("move_buffer_begin", .{}), - key.UP => self.cmd("move_scroll_up", .{}), - key.DOWN => self.cmd("move_scroll_down", .{}), - key.PGUP => self.cmd("move_scroll_page_up", .{}), - key.PGDOWN => self.cmd("move_scroll_page_down", .{}), - key.LEFT => self.cmd("move_word_left", .{}), - key.RIGHT => self.cmd("move_word_right", .{}), - key.BACKSPACE => self.cmd("delete_word_left", .{}), - key.DEL => self.cmd("delete_word_right", .{}), - key.F05 => self.cmd("toggle_inspector_view", .{}), - key.F10 => self.cmd("toggle_whitespace_mode", .{}), // aka F34 + input.key.enter => self.cmd("smart_insert_line_after", .{}), + input.key.space => self.cmd("selections_reverse", .{}), + input.key.end => self.cmd("move_buffer_end", .{}), + input.key.home => self.cmd("move_buffer_begin", .{}), + input.key.up => self.cmd("move_scroll_up", .{}), + input.key.down => self.cmd("move_scroll_down", .{}), + input.key.page_up => self.cmd("move_scroll_page_up", .{}), + input.key.page_down => self.cmd("move_scroll_page_down", .{}), + input.key.left => self.cmd("move_word_left", .{}), + input.key.right => self.cmd("move_word_right", .{}), + input.key.backspace => self.cmd("delete_word_left", .{}), + input.key.delete => self.cmd("delete_word_right", .{}), + input.key.f5 => self.cmd("toggle_inspector_view", .{}), + input.key.f10 => self.cmd("toggle_whitespace_mode", .{}), // aka F34 else => {}, }, - mod.CTRL | mod.SHIFT => switch (keynormal) { + input.mod.ctrl | input.mod.shift => switch (keynormal) { 'P' => self.cmd("open_command_palette", .{}), 'D' => self.cmd("dupe_down", .{}), 'Z' => self.cmd("redo", .{}), @@ -122,16 +119,16 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 'F' => self.cmd("find_in_files", .{}), 'L' => self.cmd_async("add_cursor_all_matches"), 'I' => self.cmd_async("toggle_inspector_view"), - key.ENTER => self.cmd("smart_insert_line_before", .{}), - key.END => self.cmd("select_buffer_end", .{}), - key.HOME => self.cmd("select_buffer_begin", .{}), - key.UP => self.cmd("select_scroll_up", .{}), - key.DOWN => self.cmd("select_scroll_down", .{}), - key.LEFT => self.cmd("select_word_left", .{}), - key.RIGHT => self.cmd("select_word_right", .{}), + input.key.enter => self.cmd("smart_insert_line_before", .{}), + input.key.end => self.cmd("select_buffer_end", .{}), + input.key.home => self.cmd("select_buffer_begin", .{}), + input.key.up => self.cmd("select_scroll_up", .{}), + input.key.down => self.cmd("select_scroll_down", .{}), + input.key.left => self.cmd("select_word_left", .{}), + input.key.right => self.cmd("select_word_right", .{}), else => {}, }, - mod.ALT => switch (keynormal) { + input.mod.alt => switch (keynormal) { 'J' => self.cmd("join_next_line", .{}), 'N' => self.cmd("goto_next_match", .{}), 'P' => self.cmd("goto_prev_match", .{}), @@ -142,71 +139,70 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 'F' => self.cmd("move_word_right", .{}), 'S' => self.cmd("filter", command.fmt(.{"sort"})), 'V' => self.cmd("paste", .{}), - key.LEFT => self.cmd("jump_back", .{}), - key.RIGHT => self.cmd("jump_forward", .{}), - key.UP => self.cmd("pull_up", .{}), - key.DOWN => self.cmd("pull_down", .{}), - key.ENTER => self.cmd("insert_line", .{}), - key.F10 => self.cmd("gutter_mode_next", .{}), // aka F58 + input.key.left => self.cmd("jump_back", .{}), + input.key.right => self.cmd("jump_forward", .{}), + input.key.up => self.cmd("pull_up", .{}), + input.key.down => self.cmd("pull_down", .{}), + input.key.enter => self.cmd("insert_line", .{}), + input.key.f10 => self.cmd("gutter_mode_next", .{}), // aka F58 else => {}, }, - mod.ALT | mod.SHIFT => switch (keynormal) { + input.mod.alt | input.mod.shift => switch (keynormal) { 'P' => self.cmd("open_command_palette", .{}), 'D' => self.cmd("dupe_up", .{}), 'F' => self.cmd("filter", command.fmt(.{ "zig", "fmt", "--stdin" })), 'S' => self.cmd("filter", command.fmt(.{ "sort", "-u" })), 'V' => self.cmd("paste", .{}), 'I' => self.cmd("add_cursors_to_line_ends", .{}), - key.LEFT => self.cmd("move_scroll_left", .{}), - key.RIGHT => self.cmd("move_scroll_right", .{}), - key.UP => self.cmd("add_cursor_up", .{}), - key.DOWN => self.cmd("add_cursor_down", .{}), + input.key.left => self.cmd("move_scroll_left", .{}), + input.key.right => self.cmd("move_scroll_right", .{}), + input.key.up => self.cmd("add_cursor_up", .{}), + input.key.down => self.cmd("add_cursor_down", .{}), else => {}, }, - mod.SHIFT => switch (keypress) { - key.F03 => self.cmd("goto_prev_match", .{}), - key.LEFT => self.cmd("select_left", .{}), - key.RIGHT => self.cmd("select_right", .{}), - key.UP => self.cmd("select_up", .{}), - key.DOWN => self.cmd("select_down", .{}), - key.HOME => self.cmd("smart_select_begin", .{}), - key.END => self.cmd("select_end", .{}), - key.PGUP => self.cmd("select_page_up", .{}), - key.PGDOWN => self.cmd("select_page_down", .{}), - key.ENTER => self.cmd("smart_insert_line_before", .{}), - key.BACKSPACE => self.cmd("delete_backward", .{}), - key.TAB => self.cmd("unindent", .{}), - else => if (!key.synthesized_p(keypress)) + input.mod.shift => switch (keypress) { + input.key.f3 => self.cmd("goto_prev_match", .{}), + input.key.left => self.cmd("select_left", .{}), + input.key.right => self.cmd("select_right", .{}), + input.key.up => self.cmd("select_up", .{}), + input.key.down => self.cmd("select_down", .{}), + input.key.home => self.cmd("smart_select_begin", .{}), + input.key.end => self.cmd("select_end", .{}), + input.key.page_up => self.cmd("select_page_up", .{}), + input.key.page_down => self.cmd("select_page_down", .{}), + input.key.enter => self.cmd("smart_insert_line_before", .{}), + input.key.backspace => self.cmd("delete_backward", .{}), + input.key.tab => self.cmd("unindent", .{}), + else => if (!input.is_non_input_key(keypress)) self.insert_code_point(egc) else {}, }, 0 => switch (keypress) { - key.F02 => self.cmd("toggle_input_mode", .{}), - key.F03 => self.cmd("goto_next_match", .{}), - key.F15 => self.cmd("goto_prev_match", .{}), // S-F3 - key.F05 => self.cmd("toggle_inspector_view", .{}), // C-F5 - key.F06 => self.cmd("dump_current_line_tree", .{}), - key.F07 => self.cmd("dump_current_line", .{}), - key.F09 => self.cmd("theme_prev", .{}), - key.F10 => self.cmd("theme_next", .{}), - key.F11 => self.cmd("toggle_panel", .{}), - key.F12 => self.cmd("goto_definition", .{}), - key.F34 => self.cmd("toggle_whitespace_mode", .{}), // C-F10 - key.F58 => self.cmd("gutter_mode_next", .{}), // A-F10 - key.ESC => self.cmd("enter_mode", command.fmt(.{"helix/normal"})), - key.ENTER => self.cmd("smart_insert_line", .{}), - key.DEL => self.cmd("delete_forward", .{}), - key.BACKSPACE => self.cmd("delete_backward", .{}), - key.LEFT => self.cmd("move_left", .{}), - key.RIGHT => self.cmd("move_right", .{}), - key.UP => self.cmd("move_up", .{}), - key.DOWN => self.cmd("move_down", .{}), - key.HOME => self.cmd("smart_move_begin", .{}), - key.END => self.cmd("move_end", .{}), - key.PGUP => self.cmd("move_page_up", .{}), - key.PGDOWN => self.cmd("move_page_down", .{}), - key.TAB => self.cmd("indent", .{}), - else => if (!key.synthesized_p(keypress)) + input.key.f2 => self.cmd("toggle_input_mode", .{}), + input.key.f3 => self.cmd("goto_next_match", .{}), + input.key.f15 => self.cmd("goto_prev_match", .{}), // S-F3 + input.key.f5 => self.cmd("toggle_inspector_view", .{}), // C-F5 + input.key.f6 => self.cmd("dump_current_line_tree", .{}), + input.key.f7 => self.cmd("dump_current_line", .{}), + input.key.f9 => self.cmd("theme_prev", .{}), + input.key.f10 => self.cmd("theme_next", .{}), + input.key.f11 => self.cmd("toggle_panel", .{}), + input.key.f12 => self.cmd("goto_definition", .{}), + input.key.f34 => self.cmd("toggle_whitespace_mode", .{}), // C-F10 + input.key.escape => self.cmd("enter_mode", command.fmt(.{"helix/normal"})), + input.key.enter => self.cmd("smart_insert_line", .{}), + input.key.delete => self.cmd("delete_forward", .{}), + input.key.backspace => self.cmd("delete_backward", .{}), + input.key.left => self.cmd("move_left", .{}), + input.key.right => self.cmd("move_right", .{}), + input.key.up => self.cmd("move_up", .{}), + input.key.down => self.cmd("move_down", .{}), + input.key.home => self.cmd("smart_move_begin", .{}), + input.key.end => self.cmd("move_end", .{}), + input.key.page_up => self.cmd("move_page_up", .{}), + input.key.page_down => self.cmd("move_page_down", .{}), + input.key.tab => self.cmd("indent", .{}), + else => if (!input.is_non_input_key(keypress)) self.insert_code_point(egc) else {}, }, @@ -214,13 +210,13 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { }; } -fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) !void { +fn map_follower(self: *Self, keypress: input.Key, modifiers: input.Mods) !void { defer self.leader = null; const ldr = if (self.leader) |leader| leader else return; return switch (ldr.modifiers) { - mod.CTRL => switch (ldr.keypress) { + input.mod.ctrl => switch (ldr.keypress) { 'K' => switch (modifiers) { - mod.CTRL => switch (keypress) { + input.mod.ctrl => switch (keypress) { 'U' => self.cmd("delete_to_begin", .{}), 'K' => self.cmd("delete_to_end", .{}), 'D' => self.cmd("move_cursor_next_match", .{}), @@ -235,10 +231,10 @@ fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) !void { }; } -fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) !void { +fn map_release(self: *Self, keypress: input.Key) !void { return switch (keypress) { - key.LCTRL, key.RCTRL => self.cmd("disable_fast_scroll", .{}), - key.LALT, key.RALT => self.cmd("disable_jump_mode", .{}), + input.key.left_control, input.key.right_control => self.cmd("disable_fast_scroll", .{}), + input.key.left_alt, input.key.right_alt => self.cmd("disable_jump_mode", .{}), else => {}, }; } @@ -247,7 +243,7 @@ fn insert_code_point(self: *Self, c: u32) !void { if (self.input.items.len + 4 > input_buffer_size) try self.flush_input(); var buf: [6]u8 = undefined; - const bytes = try ucs32_to_utf8(&[_]u32{c}, &buf); + const bytes = try input.ucs32_to_utf8(&[_]u32{c}, &buf); try self.input.appendSlice(buf[0..bytes]); } diff --git a/src/keybind/static/input/helix/normal.zig b/src/keybind/static/input/helix/normal.zig index 3aaf984..c0668a8 100644 --- a/src/keybind/static/input/helix/normal.zig +++ b/src/keybind/static/input/helix/normal.zig @@ -1,9 +1,6 @@ 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 input = @import("input"); const command = @import("command"); const EventHandler = @import("EventHandler"); const keybind = @import("../../keybind.zig"); @@ -14,7 +11,7 @@ const input_buffer_size = 1024; allocator: std.mem.Allocator, input: std.ArrayList(u8), last_cmd: []const u8 = "", -leader: ?struct { keypress: u32, modifiers: u32 } = null, +leader: ?struct { keypress: input.Key, modifiers: input.Mods } = null, count: usize = 0, commands: Commands = undefined, @@ -35,14 +32,14 @@ pub fn deinit(self: *Self) void { } pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { - var evtype: u32 = undefined; - var keypress: u32 = undefined; - var egc: u32 = undefined; - var modifiers: u32 = undefined; + var event: input.Event = undefined; + var keypress: input.Key = undefined; + var egc: input.Key = undefined; + var modifiers: input.Mods = undefined; var text: []const u8 = undefined; - if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { - self.mapEvent(evtype, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); + if (try m.match(.{ "I", tp.extract(&event), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { + self.map_event(event, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{"F"})) { self.flush_input() catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{ "system_clipboard", tp.extract(&text) })) { @@ -55,26 +52,26 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { pub fn add_keybind() void {} -fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) !void { - return switch (evtype) { - event_type.PRESS => self.mapPress(keypress, egc, modifiers), - event_type.REPEAT => self.mapPress(keypress, egc, modifiers), - event_type.RELEASE => self.mapRelease(keypress, egc, modifiers), +fn map_event(self: *Self, event: input.Event, keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { + return switch (event) { + input.event.press => self.map_press(keypress, egc, modifiers), + input.event.repeat => self.map_press(keypress, egc, modifiers), + input.event.release => self.map_release(keypress), else => {}, }; } -fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { +fn map_press(self: *Self, keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { if (self.count > 0 and modifiers == 0 and '0' <= keypress and keypress <= '9') return self.add_count(keypress - '0'); const keynormal = if ('a' <= keypress and keypress <= 'z') keypress - ('a' - 'A') else keypress; if (self.leader) |_| return self.mapFollower(keynormal, egc, modifiers); switch (keypress) { - key.LCTRL, key.RCTRL => return self.cmd("enable_fast_scroll", .{}), - key.LALT, key.RALT => return self.cmd("enable_jump_mode", .{}), + input.key.left_control, input.key.right_control => return self.cmd("enable_fast_scroll", .{}), + input.key.left_alt, input.key.right_alt => return self.cmd("enable_jump_mode", .{}), else => {}, } return switch (modifiers) { - mod.CTRL => switch (keynormal) { + input.mod.ctrl => switch (keynormal) { 'B' => self.cmd("move_scroll_page_up", .{}), 'F' => self.cmd("move_scroll_page_down", .{}), 'U' => self.cmd("page_cursor_half_up", .{}), @@ -91,12 +88,12 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 'X' => self.cmd("decrement", .{}), else => {}, }, - mod.CTRL | mod.SHIFT => switch (keynormal) { + input.mod.ctrl | input.mod.shift => switch (keynormal) { 'P' => self.cmd("open_command_palette", .{}), '6' => self.cmd("open_previous_file", .{}), else => {}, }, - mod.ALT => switch (keynormal) { + input.mod.alt => switch (keynormal) { '.' => self.cmd("repeat_last_motion", .{}), '`' => self.cmd("switch_to_uppercase", .{}), @@ -112,10 +109,10 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { '_' => self.cmd("merge_consecutive_selections", .{}), ';' => self.cmd("flip_selections", .{}), - 'O', key.UP => self.cmd("expand_selection", .{}), - 'I', key.DOWN => self.cmd("shrink_selection", .{}), - 'P', key.LEFT => self.cmd("select_prev_sibling", .{}), - 'N', key.RIGHT => self.cmd("select_next_sibling", .{}), + 'O', input.key.up => self.cmd("expand_selection", .{}), + 'I', input.key.down => self.cmd("shrink_selection", .{}), + 'P', input.key.left => self.cmd("select_prev_sibling", .{}), + 'N', input.key.right => self.cmd("select_next_sibling", .{}), 'E' => self.cmd("move_parent_node_end", .{}), 'B' => self.cmd("move_parent_node_start", .{}), @@ -128,12 +125,12 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { ',' => self.cmd("remove_primary_selection", .{}), else => {}, }, - mod.ALT | mod.SHIFT => switch (keynormal) { + input.mod.alt | input.mod.shift => switch (keynormal) { 'P' => self.cmd("open_command_palette", .{}), 'C' => self.cmd("copy_selection_on_next_line", .{}), - 'I', key.DOWN => self.cmd("select_all_children", .{}), + 'I', input.key.down => self.cmd("select_all_children", .{}), 'U' => self.cmd("redo", .{}), @@ -146,7 +143,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { '1' => self.cmd("shell_append_output", .{}), else => {}, }, - mod.SHIFT => switch (keypress) { + input.mod.shift => switch (keypress) { '`' => self.cmd("switch_case", .{}), 't' => self.cmd("till_prev_char", .{}), @@ -209,11 +206,11 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { else => {}, }, 0 => switch (keypress) { - key.F02 => self.cmd("toggle_input_mode", .{}), - 'h', key.LEFT => self.cmd_count("move_left", .{}), - 'j', key.DOWN => self.cmd_count("move_down", .{}), - 'k', key.UP => self.cmd_count("move_up", .{}), - 'l', key.RIGHT => self.cmd_count("move_right", .{}), + input.key.f2 => self.cmd("toggle_input_mode", .{}), + 'h', input.key.left => self.cmd_count("move_left", .{}), + 'j', input.key.down => self.cmd_count("move_down", .{}), + 'k', input.key.up => self.cmd_count("move_up", .{}), + 'l', input.key.right => self.cmd_count("move_right", .{}), 't' => self.cmd("find_till_char", .{}), 'f' => self.cmd("find_next_char", .{}), @@ -221,8 +218,8 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { '`' => self.cmd("switch_to_lowercase", .{}), - key.HOME => self.cmd("move_begin", .{}), - key.END => self.cmd("move_end", .{}), + input.key.home => self.cmd("move_begin", .{}), + input.key.end => self.cmd("move_end", .{}), 'w' => self.cmd_count("move_next_word_start", .{}), 'b' => self.cmd_count("move_prev_word_start", .{}), @@ -263,10 +260,10 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { ',' => self.cmd("keep_primary_selection", .{}), - key.ESC => self.cmd("cancel", .{}), + input.key.escape => self.cmd("cancel", .{}), - key.PGUP => self.cmd("move_scroll_page_up", .{}), - key.PGDOWN => self.cmd("move_scroll_page_down", .{}), + input.key.page_up => self.cmd("move_scroll_page_up", .{}), + input.key.page_down => self.cmd("move_scroll_page_down", .{}), ' ' => self.leader = .{ .keypress = keynormal, .modifiers = modifiers }, 'z' => self.leader = .{ .keypress = keynormal, .modifiers = modifiers }, @@ -286,15 +283,15 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { }; } -fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) !void { - if (keypress == key.LCTRL or - keypress == key.RCTRL or - keypress == key.LALT or - keypress == key.RALT or - keypress == key.LSHIFT or - keypress == key.RSHIFT or - keypress == key.LSUPER or - keypress == key.RSUPER) return; +fn mapFollower(self: *Self, keypress: input.Key, _: u32, modifiers: input.Mods) !void { + if (keypress == input.key.left_control or + keypress == input.key.right_control or + keypress == input.key.left_alt or + keypress == input.key.right_alt or + keypress == input.key.left_shift or + keypress == input.key.right_shift or + keypress == input.key.left_super or + keypress == input.key.right_super) return; defer self.leader = null; const ldr = if (self.leader) |leader| leader else return; @@ -324,7 +321,7 @@ fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) !void { 'W' => self.cmd("goto_word", .{}), else => {}, }, - mod.SHIFT => switch (keypress) { + input.mod.shift => switch (keypress) { 'D' => self.cmd("goto_declaration", .{}), else => {}, }, @@ -346,7 +343,7 @@ fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) !void { }, '[' => { try switch (modifiers) { - mod.SHIFT => switch (keypress) { + input.mod.shift => switch (keypress) { 'D' => self.cmd("goto_first_diag", .{}), 'G' => self.cmd("goto_first_change", .{}), 'T' => self.cmd("goto_prev_test", .{}), @@ -369,7 +366,7 @@ fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) !void { }, ']' => { try switch (modifiers) { - mod.SHIFT => switch (keypress) { + input.mod.shift => switch (keypress) { 'D' => self.cmd("goto_last_diag", .{}), 'G' => self.cmd("goto_last_change", .{}), 'T' => self.cmd("goto_next_test", .{}), @@ -392,7 +389,7 @@ fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) !void { }, 'W' => switch (modifiers) { // way too much stuff if someone wants they can implement it - mod.SHIFT => switch (keypress) { + input.mod.shift => switch (keypress) { else => {}, }, 0 => switch (keypress) { @@ -401,7 +398,7 @@ fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) !void { else => {}, }, ' ' => switch (modifiers) { - mod.SHIFT => switch (keypress) { + input.mod.shift => switch (keypress) { 'F' => self.cmd("file_picker_in_current_directory", .{}), 'S' => self.cmd("workspace_symbol_picker", .{}), 'D' => self.cmd("workspace_diagnostics_picker", .{}), @@ -436,10 +433,10 @@ fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) !void { }; } -fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) !void { +fn map_release(self: *Self, keypress: input.Key) !void { return switch (keypress) { - key.LCTRL, key.RCTRL => self.cmd("disable_fast_scroll", .{}), - key.LALT, key.RALT => self.cmd("disable_jump_mode", .{}), + input.key.left_control, input.key.right_control => self.cmd("disable_fast_scroll", .{}), + input.key.left_alt, input.key.right_alt => self.cmd("disable_jump_mode", .{}), else => {}, }; } @@ -453,7 +450,7 @@ fn insert_code_point(self: *Self, c: u32) !void { if (self.input.items.len + 4 > input_buffer_size) try self.flush_input(); var buf: [6]u8 = undefined; - const bytes = try ucs32_to_utf8(&[_]u32{c}, &buf); + const bytes = try input.ucs32_to_utf8(&[_]u32{c}, &buf); try self.input.appendSlice(buf[0..bytes]); } diff --git a/src/keybind/static/input/helix/select.zig b/src/keybind/static/input/helix/select.zig index 49b17d3..980f54f 100644 --- a/src/keybind/static/input/helix/select.zig +++ b/src/keybind/static/input/helix/select.zig @@ -1,9 +1,6 @@ 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 input = @import("input"); const command = @import("command"); const EventHandler = @import("EventHandler"); const keybind = @import("../../keybind.zig"); @@ -14,7 +11,7 @@ const input_buffer_size = 1024; allocator: std.mem.Allocator, input: std.ArrayList(u8), last_cmd: []const u8 = "", -leader: ?struct { keypress: u32, modifiers: u32 } = null, +leader: ?struct { keypress: input.Key, modifiers: input.Mods } = null, count: usize = 0, commands: Commands = undefined, @@ -35,14 +32,14 @@ pub fn deinit(self: *Self) void { } pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { - var evtype: u32 = undefined; - var keypress: u32 = undefined; - var egc: u32 = undefined; - var modifiers: u32 = undefined; + var event: input.Event = undefined; + var keypress: input.Key = undefined; + var egc: input.Key = undefined; + var modifiers: input.Mods = undefined; var text: []const u8 = undefined; - if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { - self.mapEvent(evtype, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); + if (try m.match(.{ "I", tp.extract(&event), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { + self.map_event(event, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{"F"})) { self.flush_input() catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{ "system_clipboard", tp.extract(&text) })) { @@ -55,26 +52,26 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { pub fn add_keybind() void {} -fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) !void { - return switch (evtype) { - event_type.PRESS => self.mapPress(keypress, egc, modifiers), - event_type.REPEAT => self.mapPress(keypress, egc, modifiers), - event_type.RELEASE => self.mapRelease(keypress, egc, modifiers), +fn map_event(self: *Self, event: input.Event, keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { + return switch (event) { + input.event.press => self.map_press(keypress, egc, modifiers), + input.event.repeat => self.map_press(keypress, egc, modifiers), + input.event.release => self.map_release(keypress), else => {}, }; } -fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { +fn map_press(self: *Self, keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { if (self.count > 0 and modifiers == 0 and '0' <= keypress and keypress <= '9') return self.add_count(keypress - '0'); const keynormal = if ('a' <= keypress and keypress <= 'z') keypress - ('a' - 'A') else keypress; if (self.leader) |_| return self.mapFollower(keynormal, egc, modifiers); switch (keypress) { - key.LCTRL, key.RCTRL => return self.cmd("enable_fast_scroll", .{}), - key.LALT, key.RALT => return self.cmd("enable_jump_mode", .{}), + input.key.left_control, input.key.right_control => return self.cmd("enable_fast_scroll", .{}), + input.key.left_alt, input.key.right_alt => return self.cmd("enable_jump_mode", .{}), else => {}, } return switch (modifiers) { - mod.CTRL => switch (keynormal) { + input.mod.ctrl => switch (keynormal) { 'B' => self.cmd("move_scroll_page_up", .{}), 'F' => self.cmd("move_scroll_page_down", .{}), 'U' => self.cmd("page_cursor_half_up", .{}), @@ -91,12 +88,12 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 'X' => self.cmd("decrement", .{}), else => {}, }, - mod.CTRL | mod.SHIFT => switch (keynormal) { + input.mod.ctrl | input.mod.shift => switch (keynormal) { 'P' => self.cmd("open_command_palette", .{}), '6' => self.cmd("open_previous_file", .{}), else => {}, }, - mod.ALT => switch (keynormal) { + input.mod.alt => switch (keynormal) { '.' => self.cmd("repeat_last_motion", .{}), '`' => self.cmd("switch_to_uppercase", .{}), @@ -112,10 +109,10 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { '_' => self.cmd("merge_consecutive_selections", .{}), ';' => self.cmd("flip_selections", .{}), - 'O', key.UP => self.cmd("expand_selection", .{}), - 'I', key.DOWN => self.cmd("shrink_selection", .{}), - 'P', key.LEFT => self.cmd("select_prev_sibling", .{}), - 'N', key.RIGHT => self.cmd("select_next_sibling", .{}), + 'O', input.key.up => self.cmd("expand_selection", .{}), + 'I', input.key.down => self.cmd("shrink_selection", .{}), + 'P', input.key.left => self.cmd("select_prev_sibling", .{}), + 'N', input.key.right => self.cmd("select_next_sibling", .{}), 'E' => self.cmd("extend_parent_node_end", .{}), 'B' => self.cmd("extend_parent_node_start", .{}), @@ -128,12 +125,12 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { ',' => self.cmd("remove_primary_selection", .{}), else => {}, }, - mod.ALT | mod.SHIFT => switch (keynormal) { + input.mod.alt | input.mod.shift => switch (keynormal) { 'P' => self.cmd("open_command_palette", .{}), 'C' => self.cmd("copy_selection_on_next_line", .{}), - 'I', key.DOWN => self.cmd("select_all_children", .{}), + 'I', input.key.down => self.cmd("select_all_children", .{}), 'U' => self.cmd("redo", .{}), @@ -146,7 +143,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { '1' => self.cmd("shell_append_output", .{}), else => {}, }, - mod.SHIFT => switch (keypress) { + input.mod.shift => switch (keypress) { '`' => self.cmd("switch_case", .{}), 't' => self.cmd("extend_till_prev_char", .{}), @@ -209,11 +206,11 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { else => {}, }, 0 => switch (keypress) { - key.F02 => self.cmd("toggle_input_mode", .{}), - 'h', key.LEFT => self.cmd_count("select_left", .{}), - 'j', key.DOWN => self.cmd_count("select_down", .{}), - 'k', key.UP => self.cmd_count("select_up", .{}), - 'l', key.RIGHT => self.cmd_count("select_right", .{}), + input.key.f2 => self.cmd("toggle_input_mode", .{}), + 'h', input.key.left => self.cmd_count("select_left", .{}), + 'j', input.key.down => self.cmd_count("select_down", .{}), + 'k', input.key.up => self.cmd_count("select_up", .{}), + 'l', input.key.right => self.cmd_count("select_right", .{}), 't' => self.cmd("extend_till_char", .{}), 'f' => self.cmd("extend_next_char", .{}), @@ -221,8 +218,8 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { '`' => self.cmd("switch_to_lowercase", .{}), - key.HOME => self.cmd("extend_to_line_start", .{}), - key.END => self.cmd("extend_to_line_end", .{}), + input.key.home => self.cmd("extend_to_line_start", .{}), + input.key.end => self.cmd("extend_to_line_end", .{}), 'w' => self.cmd_count("extend_next_word_start", .{}), 'b' => self.cmd_count("extend_pre_word_start", .{}), @@ -263,10 +260,10 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { ',' => self.cmd("keep_primary_selection", .{}), - key.ESC => self.cmd("enter_mode", command.fmt(.{"helix/normal"})), + input.key.escape => self.cmd("enter_mode", command.fmt(.{"helix/normal"})), - key.PGUP => self.cmd("move_scroll_page_up", .{}), - key.PGDOWN => self.cmd("move_scroll_page_down", .{}), + input.key.page_up => self.cmd("move_scroll_page_up", .{}), + input.key.page_down => self.cmd("move_scroll_page_down", .{}), ' ' => self.leader = .{ .keypress = keynormal, .modifiers = modifiers }, 'z' => self.leader = .{ .keypress = keynormal, .modifiers = modifiers }, @@ -286,15 +283,15 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { }; } -fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) !void { - if (keypress == key.LCTRL or - keypress == key.RCTRL or - keypress == key.LALT or - keypress == key.RALT or - keypress == key.LSHIFT or - keypress == key.RSHIFT or - keypress == key.LSUPER or - keypress == key.RSUPER) return; +fn mapFollower(self: *Self, keypress: input.Key, _: u32, modifiers: input.Mods) !void { + if (keypress == input.key.left_control or + keypress == input.key.right_control or + keypress == input.key.left_alt or + keypress == input.key.right_alt or + keypress == input.key.left_shift or + keypress == input.key.right_shift or + keypress == input.key.left_super or + keypress == input.key.right_super) return; defer self.leader = null; const ldr = if (self.leader) |leader| leader else return; @@ -324,7 +321,7 @@ fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) !void { 'W' => self.cmd("goto_word", .{}), else => {}, }, - mod.SHIFT => switch (keypress) { + input.mod.shift => switch (keypress) { 'D' => self.cmd("goto_declaration", .{}), else => {}, }, @@ -346,7 +343,7 @@ fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) !void { }, '[' => { try switch (modifiers) { - mod.SHIFT => switch (keypress) { + input.mod.shift => switch (keypress) { 'D' => self.cmd("goto_first_diag", .{}), 'G' => self.cmd("goto_first_change", .{}), 'T' => self.cmd("goto_prev_test", .{}), @@ -369,7 +366,7 @@ fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) !void { }, ']' => { try switch (modifiers) { - mod.SHIFT => switch (keypress) { + input.mod.shift => switch (keypress) { 'D' => self.cmd("goto_last_diag", .{}), 'G' => self.cmd("goto_last_change", .{}), 'T' => self.cmd("goto_next_test", .{}), @@ -392,7 +389,7 @@ fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) !void { }, 'W' => switch (modifiers) { // way too much stuff if someone wants they can implement it - mod.SHIFT => switch (keypress) { + input.mod.shift => switch (keypress) { else => {}, }, 0 => switch (keypress) { @@ -401,7 +398,7 @@ fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) !void { else => {}, }, ' ' => switch (modifiers) { - mod.SHIFT => switch (keypress) { + input.mod.shift => switch (keypress) { 'F' => self.cmd("file_picker_in_current_directory", .{}), 'S' => self.cmd("workspace_symbol_picker", .{}), 'D' => self.cmd("workspace_diagnostics_picker", .{}), @@ -436,10 +433,10 @@ fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) !void { }; } -fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) !void { +fn map_release(self: *Self, keypress: input.Key) !void { return switch (keypress) { - key.LCTRL, key.RCTRL => self.cmd("disable_fast_scroll", .{}), - key.LALT, key.RALT => self.cmd("disable_jump_mode", .{}), + input.key.left_control, input.key.right_control => self.cmd("disable_fast_scroll", .{}), + input.key.left_alt, input.key.right_alt => self.cmd("disable_jump_mode", .{}), else => {}, }; } @@ -453,7 +450,7 @@ fn insert_code_point(self: *Self, c: u32) !void { if (self.input.items.len + 4 > input_buffer_size) try self.flush_input(); var buf: [6]u8 = undefined; - const bytes = try ucs32_to_utf8(&[_]u32{c}, &buf); + const bytes = try input.ucs32_to_utf8(&[_]u32{c}, &buf); try self.input.appendSlice(buf[0..bytes]); } diff --git a/src/keybind/static/input/home.zig b/src/keybind/static/input/home.zig index c9c6d7f..649c78a 100644 --- a/src/keybind/static/input/home.zig +++ b/src/keybind/static/input/home.zig @@ -1,8 +1,6 @@ const std = @import("std"); const tp = @import("thespian"); -const key = @import("renderer").input.key; -const event_type = @import("renderer").input.event_type; -const mod = @import("renderer").input.modifier; +const input = @import("input"); const command = @import("command"); const EventHandler = @import("EventHandler"); const keybind = @import("../keybind.zig"); @@ -26,20 +24,20 @@ pub fn deinit(self: *Self) void { } 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 event: input.Event = undefined; + var keypress: input.Key = undefined; + var modifiers: input.Mods = undefined; - if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.any, tp.string, tp.extract(&modifiers) })) { - try self.mapEvent(evtype, keypress, modifiers); + if (try m.match(.{ "I", tp.extract(&event), tp.extract(&keypress), tp.any, tp.string, tp.extract(&modifiers) })) { + try self.map_event(event, keypress, modifiers); } return false; } -fn mapEvent(self: *Self, evtype: u32, keypress: u32, modifiers: u32) tp.result { - return switch (evtype) { - event_type.PRESS => self.mapPress(keypress, modifiers), - event_type.REPEAT => self.mapPress(keypress, modifiers), +fn map_event(self: *Self, event: u32, keypress: u32, modifiers: u32) tp.result { + return switch (event) { + input.event.press => self.mapPress(keypress, modifiers), + input.event.repeat => self.mapPress(keypress, modifiers), else => {}, }; } @@ -48,7 +46,7 @@ fn mapPress(self: *Self, keypress: u32, modifiers: u32) tp.result { const keynormal = if ('a' <= keypress and keypress <= 'z') keypress - ('a' - 'A') else keypress; if (self.leader) |_| return self.mapFollower(keynormal, modifiers); return switch (modifiers) { - mod.CTRL => switch (keynormal) { + input.mod.ctrl => switch (keynormal) { 'F' => self.sheeran(), 'J' => self.cmd("toggle_panel", .{}), 'Q' => self.cmd("quit", .{}), @@ -61,7 +59,7 @@ fn mapPress(self: *Self, keypress: u32, modifiers: u32) tp.result { 'K' => self.leader = .{ .keypress = keynormal, .modifiers = modifiers }, else => {}, }, - mod.CTRL | mod.SHIFT => switch (keynormal) { + input.mod.ctrl | input.mod.shift => switch (keynormal) { 'P' => self.cmd("open_command_palette", .{}), 'Q' => self.cmd("quit_without_saving", .{}), 'R' => self.cmd("restart", .{}), @@ -70,22 +68,22 @@ fn mapPress(self: *Self, keypress: u32, modifiers: u32) tp.result { '/' => self.cmd("open_help", .{}), else => {}, }, - mod.ALT | mod.SHIFT => switch (keynormal) { + input.mod.alt | input.mod.shift => switch (keynormal) { 'P' => self.cmd("open_command_palette", .{}), else => {}, }, - mod.ALT => switch (keynormal) { + input.mod.alt => switch (keynormal) { 'N' => self.cmd("goto_next_file_or_diagnostic", .{}), 'P' => self.cmd("goto_prev_file_or_diagnostic", .{}), 'L' => self.cmd("toggle_panel", .{}), 'I' => self.cmd("toggle_inputview", .{}), 'X' => self.cmd("open_command_palette", .{}), - key.LEFT => self.cmd("jump_back", .{}), - key.RIGHT => self.cmd("jump_forward", .{}), + input.key.left => self.cmd("jump_back", .{}), + input.key.right => self.cmd("jump_forward", .{}), else => {}, }, 0 => switch (keypress) { - key.F02 => self.cmd("toggle_input_mode", .{}), + input.key.f2 => self.cmd("toggle_input_mode", .{}), 'h' => self.cmd("open_help", .{}), 'o' => self.cmd("open_file", .{}), 'e' => self.cmd("open_recent", .{}), @@ -95,15 +93,15 @@ fn mapPress(self: *Self, keypress: u32, modifiers: u32) tp.result { 't' => self.cmd("change_theme", .{}), 'q' => self.cmd("quit", .{}), - key.F01 => self.cmd("open_help", .{}), - key.F06 => self.cmd("open_config", .{}), - key.F09 => self.cmd("theme_prev", .{}), - key.F10 => self.cmd("theme_next", .{}), - key.F11 => self.cmd("toggle_panel", .{}), - key.F12 => self.cmd("toggle_inputview", .{}), - key.UP => self.cmd("home_menu_up", .{}), - key.DOWN => self.cmd("home_menu_down", .{}), - key.ENTER => self.cmd("home_menu_activate", .{}), + input.key.f1 => self.cmd("open_help", .{}), + input.key.f6 => self.cmd("open_config", .{}), + input.key.f9 => self.cmd("theme_prev", .{}), + input.key.f10 => self.cmd("theme_next", .{}), + input.key.f11 => self.cmd("toggle_panel", .{}), + input.key.f12 => self.cmd("toggle_inputview", .{}), + input.key.up => self.cmd("home_menu_up", .{}), + input.key.down => self.cmd("home_menu_down", .{}), + input.key.enter => self.cmd("home_menu_activate", .{}), else => {}, }, else => {}, @@ -114,9 +112,9 @@ fn mapFollower(self: *Self, keypress: u32, modifiers: u32) !void { defer self.leader = null; const ldr = if (self.leader) |leader| leader else return; return switch (ldr.modifiers) { - mod.CTRL => switch (ldr.keypress) { + input.mod.ctrl => switch (ldr.keypress) { 'K' => switch (modifiers) { - mod.CTRL => switch (keypress) { + input.mod.ctrl => switch (keypress) { 'T' => self.cmd("change_theme", .{}), else => {}, }, diff --git a/src/keybind/static/input/vim/insert.zig b/src/keybind/static/input/vim/insert.zig index ce4f3cc..e258fa9 100644 --- a/src/keybind/static/input/vim/insert.zig +++ b/src/keybind/static/input/vim/insert.zig @@ -1,9 +1,6 @@ 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 input = @import("input"); const command = @import("command"); const EventHandler = @import("EventHandler"); const keybind = @import("../../keybind.zig"); @@ -14,15 +11,15 @@ const input_buffer_size = 1024; allocator: std.mem.Allocator, input: std.ArrayList(u8), last_cmd: []const u8 = "", -leader: ?struct { keypress: u32, modifiers: u32 } = null, +leader: ?struct { keypress: input.Key, modifiers: input.Mods } = null, commands: Commands = undefined, last_key: KeyPressEvent = .{}, enable_chording: bool, pub const KeyPressEvent = struct { - keypress: u32 = 0, - modifiers: u32 = std.math.maxInt(u32), - egc: u32 = 0, + keypress: input.Key = 0, + modifiers: input.Mods = std.math.maxInt(input.Mods), + egc: input.Key = 0, timestamp_ms: i64 = 0, }; @@ -44,14 +41,14 @@ pub fn deinit(self: *Self) void { } pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { - var evtype: u32 = undefined; - var keypress: u32 = undefined; - var egc: u32 = undefined; - var modifiers: u32 = undefined; + var event: input.Event = undefined; + var keypress: input.Key = undefined; + var egc: input.Key = undefined; + var modifiers: input.Mods = undefined; var text: []const u8 = undefined; - if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { - self.mapEvent(evtype, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); + if (try m.match(.{ "I", tp.extract(&event), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { + self.map_event(event, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{"F"})) { self.flush_input() catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{ "system_clipboard", tp.extract(&text) })) { @@ -64,21 +61,21 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { pub fn add_keybind() void {} -fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) !void { - return switch (evtype) { - event_type.PRESS => self.mapPress(keypress, egc, modifiers), - event_type.REPEAT => self.mapPress(keypress, egc, modifiers), - event_type.RELEASE => self.mapRelease(keypress, egc, modifiers), +fn map_event(self: *Self, event: input.Event, keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { + return switch (event) { + input.event.press => self.map_press(keypress, egc, modifiers), + input.event.repeat => self.map_press(keypress, egc, modifiers), + input.event.release => self.map_release(keypress), else => {}, }; } -fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { +fn map_press(self: *Self, keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { const keynormal = if ('a' <= keypress and keypress <= 'z') keypress - ('a' - 'A') else keypress; - if (self.leader) |_| return self.mapFollower(keynormal, egc, modifiers); + if (self.leader) |_| return self.map_follower(keynormal, egc, modifiers); switch (keypress) { - key.LCTRL, key.RCTRL => return self.cmd("enable_fast_scroll", .{}), - key.LALT, key.RALT => return self.cmd("enable_jump_mode", .{}), + input.key.left_control, input.key.right_control => return self.cmd("enable_fast_scroll", .{}), + input.key.left_alt, input.key.right_alt => return self.cmd("enable_jump_mode", .{}), else => {}, } @@ -122,7 +119,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { } return switch (modifiers) { - mod.CTRL => switch (keynormal) { + input.mod.ctrl => switch (keynormal) { 'E' => self.cmd("open_recent", .{}), 'U' => self.cmd("move_scroll_page_up", .{}), 'D' => self.cmd("move_scroll_page_down", .{}), @@ -147,23 +144,23 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 'A' => self.cmd("select_all", .{}), 'I' => self.insert_bytes("\t"), '/' => self.cmd("toggle_comment", .{}), - key.ENTER => self.cmd("smart_insert_line_after", .{}), - key.SPACE => self.cmd("selections_reverse", .{}), - key.END => self.cmd("move_buffer_end", .{}), - key.HOME => self.cmd("move_buffer_begin", .{}), - key.UP => self.cmd("move_scroll_up", .{}), - key.DOWN => self.cmd("move_scroll_down", .{}), - key.PGUP => self.cmd("move_scroll_page_up", .{}), - key.PGDOWN => self.cmd("move_scroll_page_down", .{}), - key.LEFT => self.cmd("move_word_left", .{}), - key.RIGHT => self.cmd("move_word_right", .{}), - key.BACKSPACE => self.cmd("delete_word_left", .{}), - key.DEL => self.cmd("delete_word_right", .{}), - key.F05 => self.cmd("toggle_inspector_view", .{}), - key.F10 => self.cmd("toggle_whitespace_mode", .{}), // aka F34 + input.key.enter => self.cmd("smart_insert_line_after", .{}), + input.key.space => self.cmd("selections_reverse", .{}), + input.key.end => self.cmd("move_buffer_end", .{}), + input.key.home => self.cmd("move_buffer_begin", .{}), + input.key.up => self.cmd("move_scroll_up", .{}), + input.key.down => self.cmd("move_scroll_down", .{}), + input.key.page_up => self.cmd("move_scroll_page_up", .{}), + input.key.page_down => self.cmd("move_scroll_page_down", .{}), + input.key.left => self.cmd("move_word_left", .{}), + input.key.right => self.cmd("move_word_right", .{}), + input.key.backspace => self.cmd("delete_word_left", .{}), + input.key.delete => self.cmd("delete_word_right", .{}), + input.key.f5 => self.cmd("toggle_inspector_view", .{}), + input.key.f10 => self.cmd("toggle_whitespace_mode", .{}), // aka F34 else => {}, }, - mod.CTRL | mod.SHIFT => switch (keynormal) { + input.mod.ctrl | input.mod.shift => switch (keynormal) { 'P' => self.cmd("open_command_palette", .{}), 'D' => self.cmd("dupe_down", .{}), 'Z' => self.cmd("redo", .{}), @@ -172,16 +169,16 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 'F' => self.cmd("find_in_files", .{}), 'L' => self.cmd_async("add_cursor_all_matches"), 'I' => self.cmd_async("toggle_inspector_view"), - key.ENTER => self.cmd("smart_insert_line_before", .{}), - key.END => self.cmd("select_buffer_end", .{}), - key.HOME => self.cmd("select_buffer_begin", .{}), - key.UP => self.cmd("select_scroll_up", .{}), - key.DOWN => self.cmd("select_scroll_down", .{}), - key.LEFT => self.cmd("select_word_left", .{}), - key.RIGHT => self.cmd("select_word_right", .{}), + input.key.enter => self.cmd("smart_insert_line_before", .{}), + input.key.end => self.cmd("select_buffer_end", .{}), + input.key.home => self.cmd("select_buffer_begin", .{}), + input.key.up => self.cmd("select_scroll_up", .{}), + input.key.down => self.cmd("select_scroll_down", .{}), + input.key.left => self.cmd("select_word_left", .{}), + input.key.right => self.cmd("select_word_right", .{}), else => {}, }, - mod.ALT => switch (keynormal) { + input.mod.alt => switch (keynormal) { 'J' => self.cmd("join_next_line", .{}), 'N' => self.cmd("goto_next_match", .{}), 'P' => self.cmd("goto_prev_match", .{}), @@ -192,72 +189,71 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 'F' => self.cmd("move_word_right", .{}), 'S' => self.cmd("filter", command.fmt(.{"sort"})), 'V' => self.cmd("paste", .{}), - key.LEFT => self.cmd("jump_back", .{}), - key.RIGHT => self.cmd("jump_forward", .{}), - key.UP => self.cmd("pull_up", .{}), - key.DOWN => self.cmd("pull_down", .{}), - key.ENTER => self.cmd("insert_line", .{}), - key.F10 => self.cmd("gutter_mode_next", .{}), // aka F58 + input.key.left => self.cmd("jump_back", .{}), + input.key.right => self.cmd("jump_forward", .{}), + input.key.up => self.cmd("pull_up", .{}), + input.key.down => self.cmd("pull_down", .{}), + input.key.enter => self.cmd("insert_line", .{}), + input.key.f10 => self.cmd("gutter_mode_next", .{}), // aka F58 else => {}, }, - mod.ALT | mod.SHIFT => switch (keynormal) { + input.mod.alt | input.mod.shift => switch (keynormal) { 'P' => self.cmd("open_command_palette", .{}), 'D' => self.cmd("dupe_up", .{}), 'F' => self.cmd("filter", command.fmt(.{ "zig", "fmt", "--stdin" })), 'S' => self.cmd("filter", command.fmt(.{ "sort", "-u" })), 'V' => self.cmd("paste", .{}), 'I' => self.cmd("add_cursors_to_line_ends", .{}), - key.LEFT => self.cmd("move_scroll_left", .{}), - key.RIGHT => self.cmd("move_scroll_right", .{}), - key.UP => self.cmd("add_cursor_up", .{}), - key.DOWN => self.cmd("add_cursor_down", .{}), + input.key.left => self.cmd("move_scroll_left", .{}), + input.key.right => self.cmd("move_scroll_right", .{}), + input.key.up => self.cmd("add_cursor_up", .{}), + input.key.down => self.cmd("add_cursor_down", .{}), else => {}, }, - mod.SHIFT => switch (keypress) { - key.F03 => self.cmd("goto_prev_match", .{}), - key.F10 => self.cmd("toggle_syntax_highlighting", .{}), - key.LEFT => self.cmd("select_left", .{}), - key.RIGHT => self.cmd("select_right", .{}), - key.UP => self.cmd("select_up", .{}), - key.DOWN => self.cmd("select_down", .{}), - key.HOME => self.cmd("smart_select_begin", .{}), - key.END => self.cmd("select_end", .{}), - key.PGUP => self.cmd("select_page_up", .{}), - key.PGDOWN => self.cmd("select_page_down", .{}), - key.ENTER => self.cmd("smart_insert_line_before", .{}), - key.BACKSPACE => self.cmd("delete_backward", .{}), - key.TAB => self.cmd("unindent", .{}), - else => if (!key.synthesized_p(keypress)) + input.mod.shift => switch (keypress) { + input.key.f3 => self.cmd("goto_prev_match", .{}), + input.key.f10 => self.cmd("toggle_syntax_highlighting", .{}), + input.key.left => self.cmd("select_left", .{}), + input.key.right => self.cmd("select_right", .{}), + input.key.up => self.cmd("select_up", .{}), + input.key.down => self.cmd("select_down", .{}), + input.key.home => self.cmd("smart_select_begin", .{}), + input.key.end => self.cmd("select_end", .{}), + input.key.page_up => self.cmd("select_page_up", .{}), + input.key.page_down => self.cmd("select_page_down", .{}), + input.key.enter => self.cmd("smart_insert_line_before", .{}), + input.key.backspace => self.cmd("delete_backward", .{}), + input.key.tab => self.cmd("unindent", .{}), + else => if (!input.is_non_input_key(keypress)) self.insert_code_point(egc) else {}, }, 0 => switch (keypress) { - key.F02 => self.cmd("toggle_input_mode", .{}), - key.F03 => self.cmd("goto_next_match", .{}), - key.F15 => self.cmd("goto_prev_match", .{}), // S-F3 - key.F05 => self.cmd("toggle_inspector_view", .{}), // C-F5 - key.F06 => self.cmd("dump_current_line_tree", .{}), - key.F07 => self.cmd("dump_current_line", .{}), - key.F09 => self.cmd("theme_prev", .{}), - key.F10 => self.cmd("theme_next", .{}), - key.F11 => self.cmd("toggle_panel", .{}), - key.F12 => self.cmd("goto_definition", .{}), - key.F34 => self.cmd("toggle_whitespace_mode", .{}), // C-F10 - key.F58 => self.cmd("gutter_mode_next", .{}), // A-F10 - key.ESC => self.cmd("enter_mode", command.fmt(.{"vim/normal"})), - key.ENTER => self.cmd("smart_insert_line", .{}), - key.DEL => self.cmd("delete_forward", .{}), - key.BACKSPACE => self.cmd("delete_backward", .{}), - key.LEFT => self.cmd("move_left", .{}), - key.RIGHT => self.cmd("move_right", .{}), - key.UP => self.cmd("move_up", .{}), - key.DOWN => self.cmd("move_down", .{}), - key.HOME => self.cmd("smart_move_begin", .{}), - key.END => self.cmd("move_end", .{}), - key.PGUP => self.cmd("move_page_up", .{}), - key.PGDOWN => self.cmd("move_page_down", .{}), - key.TAB => self.cmd("indent", .{}), - else => if (!key.synthesized_p(keypress)) + input.key.f2 => self.cmd("toggle_input_mode", .{}), + input.key.f3 => self.cmd("goto_next_match", .{}), + input.key.f15 => self.cmd("goto_prev_match", .{}), // S-F3 + input.key.f5 => self.cmd("toggle_inspector_view", .{}), // C-F5 + input.key.f6 => self.cmd("dump_current_line_tree", .{}), + input.key.f7 => self.cmd("dump_current_line", .{}), + input.key.f9 => self.cmd("theme_prev", .{}), + input.key.f10 => self.cmd("theme_next", .{}), + input.key.f11 => self.cmd("toggle_panel", .{}), + input.key.f12 => self.cmd("goto_definition", .{}), + input.key.f34 => self.cmd("toggle_whitespace_mode", .{}), // C-F10 + input.key.escape => self.cmd("enter_mode", command.fmt(.{"vim/normal"})), + input.key.enter => self.cmd("smart_insert_line", .{}), + input.key.delete => self.cmd("delete_forward", .{}), + input.key.backspace => self.cmd("delete_backward", .{}), + input.key.left => self.cmd("move_left", .{}), + input.key.right => self.cmd("move_right", .{}), + input.key.up => self.cmd("move_up", .{}), + input.key.down => self.cmd("move_down", .{}), + input.key.home => self.cmd("smart_move_begin", .{}), + input.key.end => self.cmd("move_end", .{}), + input.key.page_up => self.cmd("move_page_up", .{}), + input.key.page_down => self.cmd("move_page_down", .{}), + input.key.tab => self.cmd("indent", .{}), + else => if (!input.is_non_input_key(keypress)) self.insert_code_point(egc) else {}, }, @@ -265,13 +261,13 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { }; } -fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) !void { +fn map_follower(self: *Self, keypress: input.Key, _: u32, modifiers: input.Mods) !void { defer self.leader = null; const ldr = if (self.leader) |leader| leader else return; return switch (ldr.modifiers) { - mod.CTRL => switch (ldr.keypress) { + input.mod.ctrl => switch (ldr.keypress) { 'K' => switch (modifiers) { - mod.CTRL => switch (keypress) { + input.mod.ctrl => switch (keypress) { 'U' => self.cmd("delete_to_begin", .{}), 'K' => self.cmd("delete_to_end", .{}), 'D' => self.cmd("move_cursor_next_match", .{}), @@ -286,10 +282,10 @@ fn mapFollower(self: *Self, keypress: u32, _: u32, modifiers: u32) !void { }; } -fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) !void { +fn map_release(self: *Self, keypress: input.Key) !void { return switch (keypress) { - key.LCTRL, key.RCTRL => self.cmd("disable_fast_scroll", .{}), - key.LALT, key.RALT => self.cmd("disable_jump_mode", .{}), + input.key.left_control, input.key.right_control => self.cmd("disable_fast_scroll", .{}), + input.key.left_alt, input.key.right_alt => self.cmd("disable_jump_mode", .{}), else => {}, }; } @@ -298,7 +294,7 @@ fn insert_code_point(self: *Self, c: u32) !void { if (self.input.items.len + 4 > input_buffer_size) try self.flush_input(); var buf: [6]u8 = undefined; - const bytes = try ucs32_to_utf8(&[_]u32{c}, &buf); + const bytes = try input.ucs32_to_utf8(&[_]u32{c}, &buf); try self.input.appendSlice(buf[0..bytes]); } diff --git a/src/keybind/static/input/vim/normal.zig b/src/keybind/static/input/vim/normal.zig index 2c62b87..d0a455b 100644 --- a/src/keybind/static/input/vim/normal.zig +++ b/src/keybind/static/input/vim/normal.zig @@ -1,9 +1,6 @@ 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 input = @import("input"); const command = @import("command"); const EventHandler = @import("EventHandler"); const keybind = @import("../../keybind.zig"); @@ -14,7 +11,7 @@ const input_buffer_size = 1024; allocator: std.mem.Allocator, input: std.ArrayList(u8), last_cmd: []const u8 = "", -leader: ?struct { keypress: u32, modifiers: u32 } = null, +leader: ?struct { keypress: input.Key, modifiers: input.Mods } = null, count: usize = 0, commands: Commands = undefined, @@ -35,14 +32,14 @@ pub fn deinit(self: *Self) void { } pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { - var evtype: u32 = undefined; - var keypress: u32 = undefined; - var egc: u32 = undefined; - var modifiers: u32 = undefined; + var event: input.Event = undefined; + var keypress: input.Key = undefined; + var egc: input.Key = undefined; + var modifiers: input.Mods = undefined; var text: []const u8 = undefined; - if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { - self.mapEvent(evtype, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); + if (try m.match(.{ "I", tp.extract(&event), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { + self.mapEvent(event, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{"F"})) { self.flush_input() catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{ "system_clipboard", tp.extract(&text) })) { @@ -55,26 +52,26 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { pub fn add_keybind() void {} -fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) !void { - return switch (evtype) { - event_type.PRESS => self.mapPress(keypress, egc, modifiers), - event_type.REPEAT => self.mapPress(keypress, egc, modifiers), - event_type.RELEASE => self.mapRelease(keypress, egc, modifiers), +fn mapEvent(self: *Self, event: input.Event, keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { + return switch (event) { + input.event.press => self.mapPress(keypress, egc, modifiers), + input.event.repeat => self.mapPress(keypress, egc, modifiers), + input.event.release => self.mapRelease(keypress, egc, modifiers), else => {}, }; } -fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { +fn mapPress(self: *Self, keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { if (self.count > 0 and modifiers == 0 and '0' <= keypress and keypress <= '9') return self.add_count(keypress - '0'); const keynormal = if ('a' <= keypress and keypress <= 'z') keypress - ('a' - 'A') else keypress; if (self.leader) |_| return self.mapFollower(keynormal, egc, modifiers); switch (keypress) { - key.LCTRL, key.RCTRL => return self.cmd("enable_fast_scroll", .{}), - key.LALT, key.RALT => return self.cmd("enable_jump_mode", .{}), + input.key.left_control, input.key.right_control => return self.cmd("enable_fast_scroll", .{}), + input.key.left_alt, input.key.right_alt => return self.cmd("enable_jump_mode", .{}), else => {}, } return switch (modifiers) { - mod.CTRL => switch (keynormal) { + input.mod.ctrl => switch (keynormal) { 'E' => self.cmd("open_recent", .{}), 'U' => self.cmd("move_scroll_page_up", .{}), 'D' => self.cmd("move_scroll_page_down", .{}), @@ -101,23 +98,23 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 'G' => self.cmd("goto", .{}), 'A' => self.cmd("select_all", .{}), '/' => self.cmd("toggle_comment", .{}), - key.ENTER => self.cmd("smart_insert_line_after", .{}), - key.SPACE => self.cmd("selections_reverse", .{}), - key.END => self.cmd("move_buffer_end", .{}), - key.HOME => self.cmd("move_buffer_begin", .{}), - key.UP => self.cmd("move_scroll_up", .{}), - key.DOWN => self.cmd("move_scroll_down", .{}), - key.PGUP => self.cmd("move_scroll_page_up", .{}), - key.PGDOWN => self.cmd("move_scroll_page_down", .{}), - key.LEFT => self.cmd("move_word_left", .{}), - key.RIGHT => self.cmd("move_word_right", .{}), - key.BACKSPACE => self.cmd("delete_word_left", .{}), - key.DEL => self.cmd("delete_word_right", .{}), - key.F05 => self.cmd("toggle_inspector_view", .{}), - key.F10 => self.cmd("toggle_whitespace_mode", .{}), // aka F34 + input.key.enter => self.cmd("smart_insert_line_after", .{}), + input.key.space => self.cmd("selections_reverse", .{}), + input.key.end => self.cmd("move_buffer_end", .{}), + input.key.home => self.cmd("move_buffer_begin", .{}), + input.key.up => self.cmd("move_scroll_up", .{}), + input.key.down => self.cmd("move_scroll_down", .{}), + input.key.page_up => self.cmd("move_scroll_page_up", .{}), + input.key.page_down => self.cmd("move_scroll_page_down", .{}), + input.key.left => self.cmd("move_word_left", .{}), + input.key.right => self.cmd("move_word_right", .{}), + input.key.backspace => self.cmd("delete_word_left", .{}), + input.key.delete => self.cmd("delete_word_right", .{}), + input.key.f5 => self.cmd("toggle_inspector_view", .{}), + input.key.f10 => self.cmd("toggle_whitespace_mode", .{}), // aka F34 else => {}, }, - mod.CTRL | mod.SHIFT => switch (keynormal) { + input.mod.ctrl | input.mod.shift => switch (keynormal) { 'P' => self.cmd("open_command_palette", .{}), 'D' => self.cmd("dupe_down", .{}), 'Z' => self.cmd("redo", .{}), @@ -127,16 +124,16 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 'L' => self.cmd_async("add_cursor_all_matches"), 'I' => self.cmd_async("toggle_inspector_view"), '6' => self.cmd("open_previous_file", .{}), - key.ENTER => self.cmd("smart_insert_line_before", .{}), - key.END => self.cmd("select_buffer_end", .{}), - key.HOME => self.cmd("select_buffer_begin", .{}), - key.UP => self.cmd("select_scroll_up", .{}), - key.DOWN => self.cmd("select_scroll_down", .{}), - key.LEFT => self.cmd("select_word_left", .{}), - key.RIGHT => self.cmd("select_word_right", .{}), + input.key.enter => self.cmd("smart_insert_line_before", .{}), + input.key.end => self.cmd("select_buffer_end", .{}), + input.key.home => self.cmd("select_buffer_begin", .{}), + input.key.up => self.cmd("select_scroll_up", .{}), + input.key.down => self.cmd("select_scroll_down", .{}), + input.key.left => self.cmd("select_word_left", .{}), + input.key.right => self.cmd("select_word_right", .{}), else => {}, }, - mod.ALT => switch (keynormal) { + input.mod.alt => switch (keynormal) { 'J' => self.cmd("join_next_line", .{}), 'N' => self.cmd("goto_next_match", .{}), 'P' => self.cmd("goto_prev_match", .{}), @@ -147,41 +144,41 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 'F' => self.cmd("move_word_right", .{}), 'S' => self.cmd("filter", command.fmt(.{"sort"})), 'V' => self.cmd("paste", .{}), - key.LEFT => self.cmd("jump_back", .{}), - key.RIGHT => self.cmd("jump_forward", .{}), - key.UP => self.cmd("pull_up", .{}), - key.DOWN => self.cmd("pull_down", .{}), - key.ENTER => self.cmd("insert_line", .{}), - key.F10 => self.cmd("gutter_mode_next", .{}), // aka F58 + input.key.left => self.cmd("jump_back", .{}), + input.key.right => self.cmd("jump_forward", .{}), + input.key.up => self.cmd("pull_up", .{}), + input.key.down => self.cmd("pull_down", .{}), + input.key.enter => self.cmd("insert_line", .{}), + input.key.f10 => self.cmd("gutter_mode_next", .{}), // aka F58 else => {}, }, - mod.ALT | mod.SHIFT => switch (keynormal) { + input.mod.alt | input.mod.shift => switch (keynormal) { 'P' => self.cmd("open_command_palette", .{}), 'D' => self.cmd("dupe_up", .{}), 'F' => self.cmd("filter", command.fmt(.{ "zig", "fmt", "--stdin" })), 'S' => self.cmd("filter", command.fmt(.{ "sort", "-u" })), 'V' => self.cmd("paste", .{}), 'I' => self.cmd("add_cursors_to_line_ends", .{}), - key.LEFT => self.cmd("move_scroll_left", .{}), - key.RIGHT => self.cmd("move_scroll_right", .{}), - key.UP => self.cmd("add_cursor_up", .{}), - key.DOWN => self.cmd("add_cursor_down", .{}), + input.key.left => self.cmd("move_scroll_left", .{}), + input.key.right => self.cmd("move_scroll_right", .{}), + input.key.up => self.cmd("add_cursor_up", .{}), + input.key.down => self.cmd("add_cursor_down", .{}), else => {}, }, - mod.SHIFT => switch (keypress) { - key.F03 => self.cmd("goto_prev_match", .{}), - key.F10 => self.cmd("toggle_syntax_highlighting", .{}), - key.LEFT => self.cmd("select_left", .{}), - key.RIGHT => self.cmd("select_right", .{}), - key.UP => self.cmd("select_up", .{}), - key.DOWN => self.cmd("select_down", .{}), - key.HOME => self.cmd("smart_select_begin", .{}), - key.END => self.cmd("select_end", .{}), - key.PGUP => self.cmd("select_page_up", .{}), - key.PGDOWN => self.cmd("select_page_down", .{}), - key.ENTER => self.cmd("smart_insert_line_before", .{}), - key.BACKSPACE => self.cmd("delete_backward", .{}), - key.TAB => self.cmd("unindent", .{}), + input.mod.shift => switch (keypress) { + input.key.f3 => self.cmd("goto_prev_match", .{}), + input.key.f10 => self.cmd("toggle_syntax_highlighting", .{}), + input.key.left => self.cmd("select_left", .{}), + input.key.right => self.cmd("select_right", .{}), + input.key.up => self.cmd("select_up", .{}), + input.key.down => self.cmd("select_down", .{}), + input.key.home => self.cmd("smart_select_begin", .{}), + input.key.end => self.cmd("select_end", .{}), + input.key.page_up => self.cmd("select_page_up", .{}), + input.key.page_down => self.cmd("select_page_down", .{}), + input.key.enter => self.cmd("smart_insert_line_before", .{}), + input.key.backspace => self.cmd("delete_backward", .{}), + input.key.tab => self.cmd("unindent", .{}), ';' => self.cmd("open_command_palette", .{}), 'n' => self.cmd("goto_prev_match", .{}), @@ -205,22 +202,21 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { else => {}, }, 0 => switch (keypress) { - key.F02 => self.cmd("toggle_input_mode", .{}), - key.F03 => self.cmd("goto_next_match", .{}), - key.F15 => self.cmd("goto_prev_match", .{}), // S-F3 - key.F05 => self.cmd("toggle_inspector_view", .{}), // C-F5 - key.F06 => self.cmd("dump_current_line_tree", .{}), - key.F07 => self.cmd("dump_current_line", .{}), - key.F09 => self.cmd("theme_prev", .{}), - key.F10 => self.cmd("theme_next", .{}), - key.F11 => self.cmd("toggle_panel", .{}), - key.F12 => self.cmd("goto_definition", .{}), - key.F34 => self.cmd("toggle_whitespace_mode", .{}), // C-F10 - key.F58 => self.cmd("gutter_mode_next", .{}), // A-F10 - key.ESC => self.cmd("cancel", .{}), - key.ENTER => self.cmd("smart_insert_line", .{}), - key.DEL => self.cmd("delete_forward", .{}), - key.BACKSPACE => self.cmd("delete_backward", .{}), + input.key.f2 => self.cmd("toggle_input_mode", .{}), + input.key.f3 => self.cmd("goto_next_match", .{}), + input.key.f15 => self.cmd("goto_prev_match", .{}), // S-F3 + input.key.f5 => self.cmd("toggle_inspector_view", .{}), // C-F5 + input.key.f6 => self.cmd("dump_current_line_tree", .{}), + input.key.f7 => self.cmd("dump_current_line", .{}), + input.key.f9 => self.cmd("theme_prev", .{}), + input.key.f10 => self.cmd("theme_next", .{}), + input.key.f11 => self.cmd("toggle_panel", .{}), + input.key.f12 => self.cmd("goto_definition", .{}), + input.key.f34 => self.cmd("toggle_whitespace_mode", .{}), // C-F10 + input.key.escape => self.cmd("cancel", .{}), + input.key.enter => self.cmd("smart_insert_line", .{}), + input.key.delete => self.cmd("delete_forward", .{}), + input.key.backspace => self.cmd("delete_backward", .{}), ':' => self.cmd("open_command_palette", .{}), 'i' => self.cmd("enter_mode", command.fmt(.{"vim/insert"})), @@ -266,37 +262,37 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 'p' => self.cmd("paste", .{}), 'o' => self.seq(.{ "smart_insert_line_after", "enter_mode" }, command.fmt(.{"vim/insert"})), - key.LEFT => self.cmd("move_left_vim", .{}), - key.RIGHT => self.cmd("move_right_vim", .{}), - key.UP => self.cmd("move_up", .{}), - key.DOWN => self.cmd("move_down", .{}), - key.HOME => self.cmd("smart_move_begin", .{}), - key.END => self.cmd("move_end", .{}), - key.PGUP => self.cmd("move_page_up", .{}), - key.PGDOWN => self.cmd("move_page_down", .{}), - key.TAB => self.cmd("indent", .{}), + input.key.left => self.cmd("move_left_vim", .{}), + input.key.right => self.cmd("move_right_vim", .{}), + input.key.up => self.cmd("move_up", .{}), + input.key.down => self.cmd("move_down", .{}), + input.key.home => self.cmd("smart_move_begin", .{}), + input.key.end => self.cmd("move_end", .{}), + input.key.page_up => self.cmd("move_page_up", .{}), + input.key.page_down => self.cmd("move_page_down", .{}), + input.key.tab => self.cmd("indent", .{}), else => {}, }, else => {}, }; } -fn mapFollower(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { - if (keypress == key.LCTRL or - keypress == key.RCTRL or - keypress == key.LALT or - keypress == key.RALT or - keypress == key.LSHIFT or - keypress == key.RSHIFT or - keypress == key.LSUPER or - keypress == key.RSUPER) return; +fn mapFollower(self: *Self, keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { + if (keypress == input.key.left_control or + keypress == input.key.right_control or + keypress == input.key.left_alt or + keypress == input.key.right_alt or + keypress == input.key.left_shift or + keypress == input.key.right_shift or + keypress == input.key.left_super or + keypress == input.key.right_super) return; defer self.leader = null; const ldr = if (self.leader) |leader| leader else return; return switch (ldr.modifiers) { - mod.CTRL => switch (ldr.keypress) { + input.mod.ctrl => switch (ldr.keypress) { 'K' => switch (modifiers) { - mod.CTRL => switch (keypress) { + input.mod.ctrl => switch (keypress) { 'U' => self.cmd("delete_to_begin", .{}), 'K' => self.cmd("delete_to_end", .{}), 'D' => self.cmd("move_cursor_next_match", .{}), @@ -311,7 +307,7 @@ fn mapFollower(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 0 => switch (ldr.keypress) { 'C' => { try switch (modifiers) { - mod.SHIFT => switch (egc) { + input.mod.shift => switch (egc) { '$' => self.cmd("delete_to_end", .{}), else => {}, }, @@ -329,7 +325,7 @@ fn mapFollower(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { }, 'D' => { try switch (modifiers) { - mod.SHIFT => switch (egc) { + input.mod.shift => switch (egc) { '$' => self.cmd("delete_to_end", .{}), else => {}, }, @@ -348,7 +344,7 @@ fn mapFollower(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { try self.cmd("enter_mode", command.fmt(.{"vim/insert"})); }, 'R' => switch (modifiers) { - mod.SHIFT, 0 => if (!key.synthesized_p(keypress)) { + input.mod.shift, 0 => if (!input.is_non_input_key(keypress)) { var count = self.count; try self.cmd_count("delete_forward", .{}); while (count > 0) : (count -= 1) @@ -371,7 +367,7 @@ fn mapFollower(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 'Y' => self.cmd("goto_type_definition", .{}), else => {}, }, - mod.SHIFT => switch (keypress) { + input.mod.shift => switch (keypress) { 'D' => self.cmd("goto_declaration", .{}), else => {}, }, @@ -379,7 +375,7 @@ fn mapFollower(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { }, 'Y' => { try switch (modifiers) { - mod.SHIFT => switch (keypress) { + input.mod.shift => switch (keypress) { '4' => self.seq(.{ "select_to_end", "copy" }, .{}), else => {}, }, @@ -403,10 +399,10 @@ fn mapFollower(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { }; } -fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) !void { +fn mapRelease(self: *Self, keypress: input.Key, _: u32, _: u32) !void { return switch (keypress) { - key.LCTRL, key.RCTRL => self.cmd("disable_fast_scroll", .{}), - key.LALT, key.RALT => self.cmd("disable_jump_mode", .{}), + input.key.left_control, input.key.right_control => self.cmd("disable_fast_scroll", .{}), + input.key.left_alt, input.key.right_alt => self.cmd("disable_jump_mode", .{}), else => {}, }; } @@ -420,7 +416,7 @@ fn insert_code_point(self: *Self, c: u32) !void { if (self.input.items.len + 4 > input_buffer_size) try self.flush_input(); var buf: [6]u8 = undefined; - const bytes = try ucs32_to_utf8(&[_]u32{c}, &buf); + const bytes = try input.ucs32_to_utf8(&[_]u32{c}, &buf); try self.input.appendSlice(buf[0..bytes]); } diff --git a/src/keybind/static/input/vim/visual.zig b/src/keybind/static/input/vim/visual.zig index 09faae1..4a62969 100644 --- a/src/keybind/static/input/vim/visual.zig +++ b/src/keybind/static/input/vim/visual.zig @@ -1,9 +1,6 @@ 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 input = @import("input"); const command = @import("command"); const EventHandler = @import("EventHandler"); const keybind = @import("../../keybind.zig"); @@ -14,7 +11,7 @@ const input_buffer_size = 1024; allocator: std.mem.Allocator, input: std.ArrayList(u8), last_cmd: []const u8 = "", -leader: ?struct { keypress: u32, modifiers: u32 } = null, +leader: ?struct { keypress: input.Key, modifiers: input.Mods } = null, count: usize = 0, commands: Commands = undefined, @@ -35,14 +32,14 @@ pub fn deinit(self: *Self) void { } pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { - var evtype: u32 = undefined; - var keypress: u32 = undefined; - var egc: u32 = undefined; - var modifiers: u32 = undefined; + var event: input.Event = undefined; + var keypress: input.Key = undefined; + var egc: input.Key = undefined; + var modifiers: input.Mods = undefined; var text: []const u8 = undefined; - if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { - self.mapEvent(evtype, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); + if (try m.match(.{ "I", tp.extract(&event), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { + self.map_event(event, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{"F"})) { self.flush_input() catch |e| return tp.exit_error(e, @errorReturnTrace()); } else if (try m.match(.{ "system_clipboard", tp.extract(&text) })) { @@ -55,26 +52,26 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { pub fn add_keybind() void {} -fn mapEvent(self: *Self, evtype: u32, keypress: u32, egc: u32, modifiers: u32) !void { - return switch (evtype) { - event_type.PRESS => self.mapPress(keypress, egc, modifiers), - event_type.REPEAT => self.mapPress(keypress, egc, modifiers), - event_type.RELEASE => self.mapRelease(keypress, egc, modifiers), +fn map_event(self: *Self, event: input.Event, keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { + return switch (event) { + input.event.press => self.map_press(keypress, egc, modifiers), + input.event.repeat => self.map_press(keypress, egc, modifiers), + input.event.release => self.map_release(keypress), else => {}, }; } -fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { +fn map_press(self: *Self, keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { if (self.count > 0 and modifiers == 0 and '0' <= keypress and keypress <= '9') return self.add_count(keypress - '0'); const keynormal = if ('a' <= keypress and keypress <= 'z') keypress - ('a' - 'A') else keypress; if (self.leader) |_| return self.mapFollower(keynormal, egc, modifiers); switch (keypress) { - key.LCTRL, key.RCTRL => return self.cmd("enable_fast_scroll", .{}), - key.LALT, key.RALT => return self.cmd("enable_jump_mode", .{}), + input.key.left_control, input.key.right_control => return self.cmd("enable_fast_scroll", .{}), + input.key.left_alt, input.key.right_alt => return self.cmd("enable_jump_mode", .{}), else => {}, } return switch (modifiers) { - mod.CTRL => switch (keynormal) { + input.mod.ctrl => switch (keynormal) { 'E' => self.cmd("open_recent", .{}), 'U' => self.cmd("move_scroll_page_up", .{}), 'D' => self.cmd("move_scroll_page_down", .{}), @@ -101,23 +98,23 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 'G' => self.cmd("goto", .{}), 'A' => self.cmd("select_all", .{}), '/' => self.cmd("toggle_comment", .{}), - key.ENTER => self.cmd("smart_insert_line_after", .{}), - key.SPACE => self.cmd("selections_reverse", .{}), - key.END => self.cmd("select_buffer_end", .{}), - key.HOME => self.cmd("select_buffer_begin", .{}), - key.UP => self.cmd("select_scroll_up", .{}), - key.DOWN => self.cmd("select_scroll_down", .{}), - key.PGUP => self.cmd("select_scroll_page_up", .{}), - key.PGDOWN => self.cmd("select_scroll_page_down", .{}), - key.LEFT => self.cmd("select_word_left", .{}), - key.RIGHT => self.cmd("select_word_right", .{}), - key.BACKSPACE => self.cmd("delete_word_left", .{}), - key.DEL => self.cmd("delete_word_right", .{}), - key.F05 => self.cmd("toggle_inspector_view", .{}), - key.F10 => self.cmd("toggle_whitespace_mode", .{}), // aka F34 + input.key.enter => self.cmd("smart_insert_line_after", .{}), + input.key.space => self.cmd("selections_reverse", .{}), + input.key.end => self.cmd("select_buffer_end", .{}), + input.key.home => self.cmd("select_buffer_begin", .{}), + input.key.up => self.cmd("select_scroll_up", .{}), + input.key.down => self.cmd("select_scroll_down", .{}), + input.key.page_up => self.cmd("select_scroll_page_up", .{}), + input.key.page_down => self.cmd("select_scroll_page_down", .{}), + input.key.left => self.cmd("select_word_left", .{}), + input.key.right => self.cmd("select_word_right", .{}), + input.key.backspace => self.cmd("delete_word_left", .{}), + input.key.delete => self.cmd("delete_word_right", .{}), + input.key.f5 => self.cmd("toggle_inspector_view", .{}), + input.key.f10 => self.cmd("toggle_whitespace_mode", .{}), // aka F34 else => {}, }, - mod.CTRL | mod.SHIFT => switch (keynormal) { + input.mod.ctrl | input.mod.shift => switch (keynormal) { 'P' => self.cmd("open_command_palette", .{}), 'D' => self.cmd("dupe_down", .{}), 'Z' => self.cmd("redo", .{}), @@ -127,16 +124,16 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 'L' => self.cmd_async("add_cursor_all_matches"), 'I' => self.cmd_async("toggle_inspector_view"), '6' => self.cmd("open_previous_file", .{}), - key.ENTER => self.cmd("smart_insert_line_before", .{}), - key.END => self.cmd("select_buffer_end", .{}), - key.HOME => self.cmd("select_buffer_begin", .{}), - key.UP => self.cmd("select_scroll_up", .{}), - key.DOWN => self.cmd("select_scroll_down", .{}), - key.LEFT => self.cmd("select_word_left", .{}), - key.RIGHT => self.cmd("select_word_right", .{}), + input.key.enter => self.cmd("smart_insert_line_before", .{}), + input.key.end => self.cmd("select_buffer_end", .{}), + input.key.home => self.cmd("select_buffer_begin", .{}), + input.key.up => self.cmd("select_scroll_up", .{}), + input.key.down => self.cmd("select_scroll_down", .{}), + input.key.left => self.cmd("select_word_left", .{}), + input.key.right => self.cmd("select_word_right", .{}), else => {}, }, - mod.ALT => switch (keynormal) { + input.mod.alt => switch (keynormal) { 'J' => self.cmd("join_next_line", .{}), 'N' => self.cmd("goto_next_match", .{}), 'P' => self.cmd("goto_prev_match", .{}), @@ -147,39 +144,39 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 'F' => self.cmd("select_word_right", .{}), 'S' => self.cmd("filter", command.fmt(.{"sort"})), 'V' => self.cmd("paste", .{}), - key.LEFT => self.cmd("jump_back", .{}), - key.RIGHT => self.cmd("jump_forward", .{}), - key.UP => self.cmd("pull_up", .{}), - key.DOWN => self.cmd("pull_down", .{}), - key.ENTER => self.cmd("insert_line", .{}), - key.F10 => self.cmd("gutter_mode_next", .{}), // aka F58 + input.key.left => self.cmd("jump_back", .{}), + input.key.right => self.cmd("jump_forward", .{}), + input.key.up => self.cmd("pull_up", .{}), + input.key.down => self.cmd("pull_down", .{}), + input.key.enter => self.cmd("insert_line", .{}), + input.key.f10 => self.cmd("gutter_mode_next", .{}), // aka F58 else => {}, }, - mod.ALT | mod.SHIFT => switch (keynormal) { + input.mod.alt | input.mod.shift => switch (keynormal) { 'P' => self.cmd("open_command_palette", .{}), 'D' => self.cmd("dupe_up", .{}), 'F' => self.cmd("filter", command.fmt(.{ "zig", "fmt", "--stdin" })), 'S' => self.cmd("filter", command.fmt(.{ "sort", "-u" })), 'V' => self.cmd("paste", .{}), 'I' => self.cmd("add_cursors_to_line_ends", .{}), - key.LEFT => self.cmd("move_scroll_left", .{}), - key.RIGHT => self.cmd("move_scroll_right", .{}), + input.key.left => self.cmd("move_scroll_left", .{}), + input.key.right => self.cmd("move_scroll_right", .{}), else => {}, }, - mod.SHIFT => switch (keypress) { - key.F03 => self.cmd("goto_prev_match", .{}), - key.F10 => self.cmd("toggle_syntax_highlighting", .{}), - key.LEFT => self.cmd("select_left", .{}), - key.RIGHT => self.cmd("select_right", .{}), - key.UP => self.cmd("select_up", .{}), - key.DOWN => self.cmd("select_down", .{}), - key.HOME => self.cmd("smart_select_begin", .{}), - key.END => self.cmd("select_end", .{}), - key.PGUP => self.cmd("select_page_up", .{}), - key.PGDOWN => self.cmd("select_page_down", .{}), - key.ENTER => self.cmd("smart_insert_line_before", .{}), - key.BACKSPACE => self.cmd("delete_backward", .{}), - key.TAB => self.cmd("unindent", .{}), + input.mod.shift => switch (keypress) { + input.key.f3 => self.cmd("goto_prev_match", .{}), + input.key.f10 => self.cmd("toggle_syntax_highlighting", .{}), + input.key.left => self.cmd("select_left", .{}), + input.key.right => self.cmd("select_right", .{}), + input.key.up => self.cmd("select_up", .{}), + input.key.down => self.cmd("select_down", .{}), + input.key.home => self.cmd("smart_select_begin", .{}), + input.key.end => self.cmd("select_end", .{}), + input.key.page_up => self.cmd("select_page_up", .{}), + input.key.page_down => self.cmd("select_page_down", .{}), + input.key.enter => self.cmd("smart_insert_line_before", .{}), + input.key.backspace => self.cmd("delete_backward", .{}), + input.key.tab => self.cmd("unindent", .{}), ';' => self.cmd("open_command_palette", .{}), 'n' => self.cmd("goto_prev_match", .{}), @@ -201,22 +198,21 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { else => {}, }, 0 => switch (keypress) { - key.F02 => self.cmd("toggle_input_mode", .{}), - key.F03 => self.cmd("goto_next_match", .{}), - key.F15 => self.cmd("goto_prev_match", .{}), // S-F3 - key.F05 => self.cmd("toggle_inspector_view", .{}), // C-F5 - key.F06 => self.cmd("dump_current_line_tree", .{}), - key.F07 => self.cmd("dump_current_line", .{}), - key.F09 => self.cmd("theme_prev", .{}), - key.F10 => self.cmd("theme_next", .{}), - key.F11 => self.cmd("toggle_panel", .{}), - key.F12 => self.cmd("goto_definition", .{}), - key.F34 => self.cmd("toggle_whitespace_mode", .{}), // C-F10 - key.F58 => self.cmd("gutter_mode_next", .{}), // A-F10 - key.ESC => self.seq(.{ "cancel", "enter_mode" }, command.fmt(.{"vim/normal"})), - key.ENTER => self.cmd("smart_insert_line", .{}), - key.DEL => self.cmd("delete_forward", .{}), - key.BACKSPACE => self.cmd("delete_backward", .{}), + input.key.f2 => self.cmd("toggle_input_mode", .{}), + input.key.f3 => self.cmd("goto_next_match", .{}), + input.key.f15 => self.cmd("goto_prev_match", .{}), // S-F3 + input.key.f5 => self.cmd("toggle_inspector_view", .{}), // C-F5 + input.key.f6 => self.cmd("dump_current_line_tree", .{}), + input.key.f7 => self.cmd("dump_current_line", .{}), + input.key.f9 => self.cmd("theme_prev", .{}), + input.key.f10 => self.cmd("theme_next", .{}), + input.key.f11 => self.cmd("toggle_panel", .{}), + input.key.f12 => self.cmd("goto_definition", .{}), + input.key.f34 => self.cmd("toggle_whitespace_mode", .{}), // C-F10 + input.key.escape => self.seq(.{ "cancel", "enter_mode" }, command.fmt(.{"vim/normal"})), + input.key.enter => self.cmd("smart_insert_line", .{}), + input.key.delete => self.cmd("delete_forward", .{}), + input.key.backspace => self.cmd("delete_backward", .{}), ':' => self.cmd("open_command_palette", .{}), 'i' => self.cmd("enter_mode", command.fmt(.{"vim/insert"})), @@ -262,37 +258,37 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 'p' => self.cmd("paste", .{}), 'o' => self.seq(.{ "insert_line_after", "enter_mode" }, command.fmt(.{"vim/insert"})), - key.LEFT => self.cmd("select_left", .{}), - key.RIGHT => self.cmd("select_right", .{}), - key.UP => self.cmd("select_up", .{}), - key.DOWN => self.cmd("select_down", .{}), - key.HOME => self.cmd("smart_select_begin", .{}), - key.END => self.cmd("select_end", .{}), - key.PGUP => self.cmd("select_page_up", .{}), - key.PGDOWN => self.cmd("select_page_down", .{}), - key.TAB => self.cmd("indent", .{}), + input.key.left => self.cmd("select_left", .{}), + input.key.right => self.cmd("select_right", .{}), + input.key.up => self.cmd("select_up", .{}), + input.key.down => self.cmd("select_down", .{}), + input.key.home => self.cmd("smart_select_begin", .{}), + input.key.end => self.cmd("select_end", .{}), + input.key.page_up => self.cmd("select_page_up", .{}), + input.key.page_down => self.cmd("select_page_down", .{}), + input.key.tab => self.cmd("indent", .{}), else => {}, }, else => {}, }; } -fn mapFollower(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { - if (keypress == key.LCTRL or - keypress == key.RCTRL or - keypress == key.LALT or - keypress == key.RALT or - keypress == key.LSHIFT or - keypress == key.RSHIFT or - keypress == key.LSUPER or - keypress == key.RSUPER) return; +fn mapFollower(self: *Self, keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { + if (keypress == input.key.left_control or + keypress == input.key.right_control or + keypress == input.key.left_alt or + keypress == input.key.right_alt or + keypress == input.key.left_shift or + keypress == input.key.right_shift or + keypress == input.key.left_super or + keypress == input.key.right_super) return; defer self.leader = null; const ldr = if (self.leader) |leader| leader else return; return switch (ldr.modifiers) { - mod.CTRL => switch (ldr.keypress) { + input.mod.ctrl => switch (ldr.keypress) { 'K' => switch (modifiers) { - mod.CTRL => switch (keypress) { + input.mod.ctrl => switch (keypress) { 'U' => self.cmd("delete_to_begin", .{}), 'K' => self.cmd("delete_to_end", .{}), 'D' => self.cmd("move_cursor_next_match", .{}), @@ -307,7 +303,7 @@ fn mapFollower(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { 0 => switch (ldr.keypress) { 'D', 'C' => { try switch (modifiers) { - mod.SHIFT => switch (keypress) { + input.mod.shift => switch (keypress) { '4' => self.cmd("delete_to_end", .{}), else => {}, }, @@ -326,7 +322,7 @@ fn mapFollower(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { try self.cmd("enter_mode", command.fmt(.{"vim/insert"})); }, 'R' => switch (modifiers) { - mod.SHIFT, 0 => if (!key.synthesized_p(keypress)) { + input.mod.shift, 0 => if (!input.is_non_input_key(keypress)) { var count = self.count; try self.cmd_count("delete_forward", .{}); while (count > 0) : (count -= 1) @@ -354,10 +350,10 @@ fn mapFollower(self: *Self, keypress: u32, egc: u32, modifiers: u32) !void { }; } -fn mapRelease(self: *Self, keypress: u32, _: u32, _: u32) !void { +fn map_release(self: *Self, keypress: input.Key) !void { return switch (keypress) { - key.LCTRL, key.RCTRL => self.cmd("disable_fast_scroll", .{}), - key.LALT, key.RALT => self.cmd("disable_jump_mode", .{}), + input.key.left_control, input.key.right_control => self.cmd("disable_fast_scroll", .{}), + input.key.left_alt, input.key.right_alt => self.cmd("disable_jump_mode", .{}), else => {}, }; } @@ -371,7 +367,7 @@ fn insert_code_point(self: *Self, c: u32) !void { if (self.input.items.len + 4 > input_buffer_size) try self.flush_input(); var buf: [6]u8 = undefined; - const bytes = try ucs32_to_utf8(&[_]u32{c}, &buf); + const bytes = try input.ucs32_to_utf8(&[_]u32{c}, &buf); try self.input.appendSlice(buf[0..bytes]); } diff --git a/src/keybind/static/keybind.zig b/src/keybind/static/keybind.zig index 6c00c39..d828521 100644 --- a/src/keybind/static/keybind.zig +++ b/src/keybind/static/keybind.zig @@ -32,7 +32,7 @@ pub const Mode = struct { name: []const u8 = "", line_numbers: enum { absolute, relative } = .absolute, keybind_hints: ?*const KeybindHints = null, - cursor_shape: renderer.CursorShape = .block, + cursor_shape: CursorShape = .block, pub fn deinit(self: *Mode) void { self.input_handler.deinit(); @@ -42,6 +42,15 @@ pub const Mode = struct { pub const KeybindHints = std.static_string_map.StaticStringMap([]const u8); -const renderer = @import("renderer"); +pub const CursorShape = enum { + default, + block_blink, + block, + underline_blink, + underline, + beam_blink, + beam, +}; + const EventHandler = @import("EventHandler"); const std = @import("std"); diff --git a/src/keybind/static/mini/file_browser.zig b/src/keybind/static/mini/file_browser.zig index a9017b9..a0d138a 100644 --- a/src/keybind/static/mini/file_browser.zig +++ b/src/keybind/static/mini/file_browser.zig @@ -1,7 +1,5 @@ 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 input = @import("input"); const command = @import("command"); const EventHandler = @import("EventHandler"); @@ -10,29 +8,29 @@ pub fn create(_: @import("std").mem.Allocator, _: anytype) !EventHandler { } pub fn receive(_: tp.pid_ref, m: tp.message) error{Exit}!bool { - var evtype: u32 = undefined; - var keypress: u32 = undefined; - var egc: u32 = undefined; - var modifiers: u32 = undefined; + var event: input.Event = undefined; + var keypress: input.Key = undefined; + var egc: input.Key = undefined; + var modifiers: input.Mods = undefined; - if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { - mapEvent(evtype, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); + if (try m.match(.{ "I", tp.extract(&event), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { + map_event(event, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); } return false; } -fn mapEvent(evtype: u32, keypress: u32, egc: u32, modifiers: u32) !void { - switch (evtype) { - event_type.PRESS => try mapPress(keypress, egc, modifiers), - event_type.REPEAT => try mapPress(keypress, egc, modifiers), +fn map_event(event: input.Event, keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { + switch (event) { + input.event.press => try map_press(keypress, egc, modifiers), + input.event.repeat => try map_press(keypress, egc, modifiers), else => {}, } } -fn mapPress(keypress: u32, egc: u32, modifiers: u32) !void { +fn map_press(keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { const keynormal = if ('a' <= keypress and keypress <= 'z') keypress - ('a' - 'A') else keypress; return switch (modifiers) { - mod.CTRL => switch (keynormal) { + input.mod.ctrl => switch (keynormal) { 'Q' => command.executeName("quit", .{}), 'V' => command.executeName("system_paste", .{}), 'U' => command.executeName("mini_mode_reset", .{}), @@ -40,34 +38,34 @@ fn mapPress(keypress: u32, egc: u32, modifiers: u32) !void { 'C' => command.executeName("mini_mode_cancel", .{}), 'L' => command.executeName("scroll_view_center", .{}), 'I' => command.executeName("mini_mode_insert_bytes", command.fmt(.{"\t"})), - key.SPACE => command.executeName("mini_mode_cancel", .{}), - key.BACKSPACE => command.executeName("mini_mode_delete_to_previous_path_segment", .{}), + input.key.space => command.executeName("mini_mode_cancel", .{}), + input.key.backspace => command.executeName("mini_mode_delete_to_previous_path_segment", .{}), else => {}, }, - mod.ALT => switch (keynormal) { + input.mod.alt => switch (keynormal) { 'V' => command.executeName("system_paste", .{}), else => {}, }, - mod.ALT | mod.SHIFT => switch (keynormal) { + input.mod.alt | input.mod.shift => switch (keynormal) { 'V' => command.executeName("system_paste", .{}), else => {}, }, - mod.SHIFT => switch (keypress) { - key.TAB => command.executeName("mini_mode_reverse_complete_file", .{}), - else => if (!key.synthesized_p(keypress)) + input.mod.shift => switch (keypress) { + input.key.tab => command.executeName("mini_mode_reverse_complete_file", .{}), + else => if (!input.is_non_input_key(keypress)) command.executeName("mini_mode_insert_code_point", command.fmt(.{egc})) else {}, }, 0 => switch (keypress) { - key.UP => command.executeName("mini_mode_reverse_complete_file", .{}), - key.DOWN => command.executeName("mini_mode_try_complete_file", .{}), - key.RIGHT => command.executeName("mini_mode_try_complete_file_forward", .{}), - key.LEFT => command.executeName("mini_mode_delete_to_previous_path_segment", .{}), - key.TAB => command.executeName("mini_mode_try_complete_file", .{}), - key.ESC => command.executeName("mini_mode_cancel", .{}), - key.ENTER => command.executeName("mini_mode_select", .{}), - key.BACKSPACE => command.executeName("mini_mode_delete_backwards", .{}), - else => if (!key.synthesized_p(keypress)) + input.key.up => command.executeName("mini_mode_reverse_complete_file", .{}), + input.key.down => command.executeName("mini_mode_try_complete_file", .{}), + input.key.right => command.executeName("mini_mode_try_complete_file_forward", .{}), + input.key.left => command.executeName("mini_mode_delete_to_previous_path_segment", .{}), + input.key.tab => command.executeName("mini_mode_try_complete_file", .{}), + input.key.escape => command.executeName("mini_mode_cancel", .{}), + input.key.enter => command.executeName("mini_mode_select", .{}), + input.key.backspace => command.executeName("mini_mode_delete_backwards", .{}), + else => if (!input.is_non_input_key(keypress)) command.executeName("mini_mode_insert_code_point", command.fmt(.{egc})) else {}, }, diff --git a/src/keybind/static/mini/find.zig b/src/keybind/static/mini/find.zig index 20b7d77..67ab2b4 100644 --- a/src/keybind/static/mini/find.zig +++ b/src/keybind/static/mini/find.zig @@ -1,7 +1,5 @@ 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 input = @import("input"); const command = @import("command"); const EventHandler = @import("EventHandler"); @@ -10,29 +8,29 @@ pub fn create(_: @import("std").mem.Allocator, _: anytype) !EventHandler { } pub fn receive(_: tp.pid_ref, m: tp.message) error{Exit}!bool { - var evtype: u32 = undefined; - var keypress: u32 = undefined; - var egc: u32 = undefined; - var modifiers: u32 = undefined; + var event: input.Event = undefined; + var keypress: input.Key = undefined; + var egc: input.Key = undefined; + var modifiers: input.Mods = undefined; - if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { - mapEvent(evtype, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); + if (try m.match(.{ "I", tp.extract(&event), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { + map_event(event, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); } return false; } -fn mapEvent(evtype: u32, keypress: u32, egc: u32, modifiers: u32) !void { - switch (evtype) { - event_type.PRESS => try mapPress(keypress, egc, modifiers), - event_type.REPEAT => try mapPress(keypress, egc, modifiers), +fn map_event(event: input.Event, keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { + switch (event) { + input.event.press => try map_press(keypress, egc, modifiers), + input.event.repeat => try map_press(keypress, egc, modifiers), else => {}, } } -fn mapPress(keypress: u32, egc: u32, modifiers: u32) !void { +fn map_press(keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { const keynormal = if ('a' <= keypress and keypress <= 'z') keypress - ('a' - 'A') else keypress; return switch (modifiers) { - mod.CTRL => switch (keynormal) { + input.mod.ctrl => switch (keynormal) { 'Q' => command.executeName("quit", .{}), 'V' => command.executeName("system_paste", .{}), 'U' => command.executeName("mini_mode_reset", .{}), @@ -43,41 +41,41 @@ fn mapPress(keypress: u32, egc: u32, modifiers: u32) !void { 'N' => command.executeName("goto_next_match", .{}), 'P' => command.executeName("goto_prev_match", .{}), 'I' => command.executeName("mini_mode_insert_bytes", command.fmt(.{"\t"})), - key.SPACE => command.executeName("mini_mode_cancel", .{}), - key.ENTER => command.executeName("mini_mode_insert_bytes", command.fmt(.{"\n"})), - key.BACKSPACE => command.executeName("mini_mode_reset", .{}), + input.key.space => command.executeName("mini_mode_cancel", .{}), + input.key.enter => command.executeName("mini_mode_insert_bytes", command.fmt(.{"\n"})), + input.key.backspace => command.executeName("mini_mode_reset", .{}), else => {}, }, - mod.ALT => switch (keynormal) { + input.mod.alt => switch (keynormal) { 'V' => command.executeName("system_paste", .{}), 'N' => command.executeName("goto_next_match", .{}), 'P' => command.executeName("goto_prev_match", .{}), else => {}, }, - mod.ALT | mod.SHIFT => switch (keynormal) { + input.mod.alt | input.mod.shift => switch (keynormal) { 'V' => command.executeName("system_paste", .{}), else => {}, }, - mod.SHIFT => switch (keypress) { - key.ENTER => command.executeName("goto_prev_match", .{}), - key.F03 => command.executeName("goto_prev_match", .{}), - else => if (!key.synthesized_p(keypress)) + input.mod.shift => switch (keypress) { + input.key.enter => command.executeName("goto_prev_match", .{}), + input.key.f3 => command.executeName("goto_prev_match", .{}), + else => if (!input.is_non_input_key(keypress)) command.executeName("mini_mode_insert_code_point", command.fmt(.{egc})) else {}, }, 0 => switch (keypress) { - key.UP => command.executeName("mini_mode_history_prev", .{}), - key.DOWN => command.executeName("mini_mode_history_next", .{}), - key.F03 => command.executeName("goto_next_match", .{}), - key.F15 => command.executeName("goto_prev_match", .{}), - key.F09 => command.executeName("theme_prev", .{}), - key.F10 => command.executeName("theme_next", .{}), - key.ESC => command.executeName("mini_mode_cancel", .{}), - key.ENTER => command.executeName("mini_mode_select", .{}), - key.BACKSPACE => command.executeName("mini_mode_delete_backwards", .{}), - key.LCTRL, key.RCTRL => command.executeName("enable_fast_scroll", .{}), - key.LALT, key.RALT => command.executeName("enable_fast_scroll", .{}), - else => if (!key.synthesized_p(keypress)) + input.key.up => command.executeName("mini_mode_history_prev", .{}), + input.key.down => command.executeName("mini_mode_history_next", .{}), + input.key.f3 => command.executeName("goto_next_match", .{}), + input.key.f15 => command.executeName("goto_prev_match", .{}), + input.key.f9 => command.executeName("theme_prev", .{}), + input.key.f10 => command.executeName("theme_next", .{}), + input.key.escape => command.executeName("mini_mode_cancel", .{}), + input.key.enter => command.executeName("mini_mode_select", .{}), + input.key.backspace => command.executeName("mini_mode_delete_backwards", .{}), + input.key.left_control, input.key.right_control => command.executeName("enable_fast_scroll", .{}), + input.key.left_alt, input.key.right_alt => command.executeName("enable_fast_scroll", .{}), + else => if (!input.is_non_input_key(keypress)) command.executeName("mini_mode_insert_code_point", command.fmt(.{egc})) else {}, }, diff --git a/src/keybind/static/mini/find_in_files.zig b/src/keybind/static/mini/find_in_files.zig index 23d5ce3..b0483aa 100644 --- a/src/keybind/static/mini/find_in_files.zig +++ b/src/keybind/static/mini/find_in_files.zig @@ -1,7 +1,5 @@ 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 input = @import("input"); const command = @import("command"); const EventHandler = @import("EventHandler"); @@ -10,30 +8,30 @@ pub fn create(_: @import("std").mem.Allocator, _: anytype) !EventHandler { } pub fn receive(_: tp.pid_ref, m: tp.message) error{Exit}!bool { - var evtype: u32 = undefined; - var keypress: u32 = undefined; - var egc: u32 = undefined; - var modifiers: u32 = undefined; + var event: input.Event = undefined; + var keypress: input.Key = undefined; + var egc: input.Key = undefined; + var modifiers: input.Mods = undefined; - if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { - mapEvent(evtype, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); + if (try m.match(.{ "I", tp.extract(&event), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { + map_event(event, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); } return false; } -fn mapEvent(evtype: u32, keypress: u32, egc: u32, modifiers: u32) !void { - switch (evtype) { - event_type.PRESS => try mapPress(keypress, egc, modifiers), - event_type.REPEAT => try mapPress(keypress, egc, modifiers), - event_type.RELEASE => try mapRelease(keypress, egc, modifiers), +fn map_event(event: input.Event, keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { + switch (event) { + input.event.press => try map_press(keypress, egc, modifiers), + input.event.repeat => try map_press(keypress, egc, modifiers), + input.event.release => try map_release(keypress, egc, modifiers), else => {}, } } -fn mapPress(keypress: u32, egc: u32, modifiers: u32) !void { +fn map_press(keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { const keynormal = if ('a' <= keypress and keypress <= 'z') keypress - ('a' - 'A') else keypress; return switch (modifiers) { - mod.CTRL => switch (keynormal) { + input.mod.ctrl => switch (keynormal) { 'Q' => command.executeName("quit", .{}), 'V' => command.executeName("system_paste", .{}), 'U' => command.executeName("mini_mode_reset", .{}), @@ -44,41 +42,41 @@ fn mapPress(keypress: u32, egc: u32, modifiers: u32) !void { 'N' => command.executeName("goto_next_match", .{}), 'P' => command.executeName("goto_prev_match", .{}), 'I' => command.executeName("mini_mode_insert_bytes", command.fmt(.{"\t"})), - key.SPACE => command.executeName("exit_mini_mode", .{}), - key.ENTER => command.executeName("mini_mode_insert_bytes", command.fmt(.{"\n"})), - key.BACKSPACE => command.executeName("mini_mode_reset", .{}), + input.key.space => command.executeName("exit_mini_mode", .{}), + input.key.enter => command.executeName("mini_mode_insert_bytes", command.fmt(.{"\n"})), + input.key.backspace => command.executeName("mini_mode_reset", .{}), else => {}, }, - mod.ALT => switch (keynormal) { + input.mod.alt => switch (keynormal) { 'V' => command.executeName("system_paste", .{}), 'N' => command.executeName("goto_next_file", .{}), 'P' => command.executeName("goto_prev_file", .{}), else => {}, }, - mod.ALT | mod.SHIFT => switch (keynormal) { + input.mod.alt | input.mod.shift => switch (keynormal) { 'V' => command.executeName("system_paste", .{}), else => {}, }, - mod.SHIFT => switch (keypress) { - key.ENTER => command.executeName("goto_prev_match", .{}), - key.F03 => command.executeName("goto_prev_match", .{}), - else => if (!key.synthesized_p(keypress)) + input.mod.shift => switch (keypress) { + input.key.enter => command.executeName("goto_prev_match", .{}), + input.key.f3 => command.executeName("goto_prev_match", .{}), + else => if (!input.is_non_input_key(keypress)) command.executeName("mini_mode_insert_code_point", command.fmt(.{egc})) else {}, }, 0 => switch (keypress) { - key.UP => command.executeName("select_prev_file", .{}), - key.DOWN => command.executeName("select_next_file", .{}), - key.F03 => command.executeName("goto_next_match", .{}), - key.F15 => command.executeName("goto_prev_match", .{}), - key.F09 => command.executeName("theme_prev", .{}), - key.F10 => command.executeName("theme_next", .{}), - key.ESC => command.executeName("exit_mini_mode", .{}), - key.ENTER => command.executeName("mini_mode_select", .{}), - key.BACKSPACE => command.executeName("mini_mode_delete_backwards", .{}), - key.LCTRL, key.RCTRL => command.executeName("enable_fast_scroll", .{}), - key.LALT, key.RALT => command.executeName("enable_fast_scroll", .{}), - else => if (!key.synthesized_p(keypress)) + input.key.up => command.executeName("select_prev_file", .{}), + input.key.down => command.executeName("select_next_file", .{}), + input.key.f3 => command.executeName("goto_next_match", .{}), + input.key.f15 => command.executeName("goto_prev_match", .{}), + input.key.f9 => command.executeName("theme_prev", .{}), + input.key.f10 => command.executeName("theme_next", .{}), + input.key.escape => command.executeName("exit_mini_mode", .{}), + input.key.enter => command.executeName("mini_mode_select", .{}), + input.key.backspace => command.executeName("mini_mode_delete_backwards", .{}), + input.key.left_control, input.key.right_control => command.executeName("enable_fast_scroll", .{}), + input.key.left_alt, input.key.right_alt => command.executeName("enable_fast_scroll", .{}), + else => if (!input.is_non_input_key(keypress)) command.executeName("mini_mode_insert_code_point", command.fmt(.{egc})) else {}, }, @@ -86,10 +84,10 @@ fn mapPress(keypress: u32, egc: u32, modifiers: u32) !void { }; } -fn mapRelease(keypress: u32, _: u32, _: u32) !void { +fn map_release(keypress: input.Key, _: input.Key, _: input.Mods) !void { return switch (keypress) { - key.LCTRL, key.RCTRL => command.executeName("disable_fast_scroll", .{}), - key.LALT, key.RALT => command.executeName("disable_fast_scroll", .{}), + input.key.left_control, input.key.right_control => command.executeName("disable_fast_scroll", .{}), + input.key.left_alt, input.key.right_alt => command.executeName("disable_fast_scroll", .{}), else => {}, }; } diff --git a/src/keybind/static/mini/goto.zig b/src/keybind/static/mini/goto.zig index 0d85852..f9f202e 100644 --- a/src/keybind/static/mini/goto.zig +++ b/src/keybind/static/mini/goto.zig @@ -1,7 +1,5 @@ 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 input = @import("input"); const command = @import("command"); const EventHandler = @import("EventHandler"); @@ -10,41 +8,41 @@ pub fn create(_: @import("std").mem.Allocator, _: anytype) !EventHandler { } pub fn receive(_: tp.pid_ref, m: tp.message) error{Exit}!bool { - var evtype: u32 = undefined; - var keypress: u32 = undefined; - var modifiers: u32 = undefined; - if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.any, tp.string, tp.extract(&modifiers) })) - try mapEvent(evtype, keypress, modifiers); + var event: input.Event = undefined; + var keypress: input.Key = undefined; + var modifiers: input.Mods = undefined; + if (try m.match(.{ "I", tp.extract(&event), tp.extract(&keypress), tp.any, tp.string, tp.extract(&modifiers) })) + try map_event(event, keypress, modifiers); return false; } -fn mapEvent(evtype: u32, keypress: u32, modifiers: u32) tp.result { - switch (evtype) { - event_type.PRESS => try mapPress(keypress, modifiers), - event_type.REPEAT => try mapPress(keypress, modifiers), - event_type.RELEASE => try mapRelease(keypress, modifiers), +fn map_event(event: input.Event, keypress: input.Key, modifiers: input.Mods) tp.result { + switch (event) { + input.event.press => try map_press(keypress, modifiers), + input.event.repeat => try map_press(keypress, modifiers), + input.event.release => try map_release(keypress), else => {}, } } -fn mapPress(keypress: u32, modifiers: u32) tp.result { +fn map_press(keypress: input.Key, modifiers: input.Mods) tp.result { const keynormal = if ('a' <= keypress and keypress <= 'z') keypress - ('a' - 'A') else keypress; return switch (modifiers) { - mod.CTRL => switch (keynormal) { + input.mod.ctrl => switch (keynormal) { 'Q' => command.executeName("quit", .{}), 'U' => command.executeName("mini_mode_reset", .{}), 'G' => command.executeName("mini_mode_cancel", .{}), 'C' => command.executeName("mini_mode_cancel", .{}), 'L' => command.executeName("scroll_view_center", .{}), - key.SPACE => command.executeName("mini_mode_cancel", .{}), + input.key.space => command.executeName("mini_mode_cancel", .{}), else => {}, }, 0 => switch (keypress) { - key.LCTRL, key.RCTRL => command.executeName("enable_fast_scroll", .{}), - key.LALT, key.RALT => command.executeName("enable_fast_scroll", .{}), - key.ESC => command.executeName("mini_mode_cancel", .{}), - key.ENTER => command.executeName("exit_mini_mode", .{}), - key.BACKSPACE => command.executeName("mini_mode_delete_backwards", .{}), + input.key.left_control, input.key.right_control => command.executeName("enable_fast_scroll", .{}), + input.key.left_alt, input.key.right_alt => command.executeName("enable_fast_scroll", .{}), + input.key.escape => command.executeName("mini_mode_cancel", .{}), + input.key.enter => command.executeName("exit_mini_mode", .{}), + input.key.backspace => command.executeName("mini_mode_delete_backwards", .{}), '0'...'9' => command.executeName("mini_mode_insert_code_point", command.fmt(.{keypress})), else => {}, }, @@ -52,10 +50,10 @@ fn mapPress(keypress: u32, modifiers: u32) tp.result { }; } -fn mapRelease(keypress: u32, _: u32) tp.result { +fn map_release(keypress: input.Key) tp.result { return switch (keypress) { - key.LCTRL, key.RCTRL => command.executeName("disable_fast_scroll", .{}), - key.LALT, key.RALT => command.executeName("disable_fast_scroll", .{}), + input.key.left_control, input.key.right_control => command.executeName("disable_fast_scroll", .{}), + input.key.left_alt, input.key.right_alt => command.executeName("disable_fast_scroll", .{}), else => {}, }; } diff --git a/src/keybind/static/mini/move_to_char.zig b/src/keybind/static/mini/move_to_char.zig index 12e9530..443c871 100644 --- a/src/keybind/static/mini/move_to_char.zig +++ b/src/keybind/static/mini/move_to_char.zig @@ -1,7 +1,5 @@ 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 input = @import("input"); const command = @import("command"); const EventHandler = @import("EventHandler"); @@ -10,39 +8,39 @@ pub fn create(_: @import("std").mem.Allocator, _: anytype) !EventHandler { } 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); + var event: input.Event = undefined; + var keypress: input.Key = undefined; + var egc: input.Key = undefined; + var modifiers: input.Mods = undefined; + if (try m.match(.{ "I", tp.extract(&event), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) + try map_event(event, 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), +fn map_event(event: input.Event, keypress: input.Key, egc: input.Key, modifiers: input.Mods) tp.result { + switch (event) { + input.event.press => try map_press(keypress, egc, modifiers), else => {}, } } -fn mapPress(keypress: u32, egc: u32, modifiers: u32) tp.result { +fn map_press(keypress: input.Key, egc: input.Key, modifiers: input.Mods) tp.result { switch (keypress) { - key.LSUPER, key.RSUPER => return, - key.LSHIFT, key.RSHIFT => return, - key.LCTRL, key.RCTRL => return, - key.LALT, key.RALT => return, + input.key.left_super, input.key.right_super => return, + input.key.left_shift, input.key.right_shift => return, + input.key.left_control, input.key.right_control => return, + input.key.left_alt, input.key.right_alt => return, else => {}, } return switch (modifiers) { - mod.SHIFT => if (!key.synthesized_p(keypress)) + input.mod.shift => if (!input.is_non_input_key(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)) + input.key.escape => command.executeName("mini_mode_cancel", .{}), + input.key.enter => command.executeName("mini_mode_cancel", .{}), + else => if (!input.is_non_input_key(keypress)) command.executeName("mini_mode_insert_code_point", command.fmt(.{egc})) else command.executeName("mini_mode_cancel", .{}), diff --git a/src/keybind/static/overlay/palette.zig b/src/keybind/static/overlay/palette.zig index 9819775..8a6ef69 100644 --- a/src/keybind/static/overlay/palette.zig +++ b/src/keybind/static/overlay/palette.zig @@ -1,7 +1,5 @@ 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 input = @import("input"); const command = @import("command"); const EventHandler = @import("EventHandler"); @@ -10,30 +8,30 @@ pub fn create(_: @import("std").mem.Allocator, _: anytype) !EventHandler { } pub fn receive(_: tp.pid_ref, m: tp.message) error{Exit}!bool { - var evtype: u32 = undefined; - var keypress: u32 = undefined; - var egc: u32 = undefined; - var modifiers: u32 = undefined; + var event: input.Event = undefined; + var keypress: input.Key = undefined; + var egc: input.Key = undefined; + var modifiers: input.Mods = undefined; - if (try m.match(.{ "I", tp.extract(&evtype), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { - mapEvent(evtype, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); + if (try m.match(.{ "I", tp.extract(&event), tp.extract(&keypress), tp.extract(&egc), tp.string, tp.extract(&modifiers) })) { + map_event(event, keypress, egc, modifiers) catch |e| return tp.exit_error(e, @errorReturnTrace()); } return false; } -fn mapEvent(evtype: u32, keypress: u32, egc: u32, modifiers: u32) !void { - return switch (evtype) { - event_type.PRESS => mapPress(keypress, egc, modifiers), - event_type.REPEAT => mapPress(keypress, egc, modifiers), - event_type.RELEASE => mapRelease(keypress, modifiers), +fn map_event(event: input.Event, keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { + return switch (event) { + input.event.press => map_press(keypress, egc, modifiers), + input.event.repeat => map_press(keypress, egc, modifiers), + input.event.release => map_release(keypress), else => {}, }; } -fn mapPress(keypress: u32, egc: u32, modifiers: u32) !void { +fn map_press(keypress: input.Key, egc: input.Key, modifiers: input.Mods) !void { const keynormal = if ('a' <= keypress and keypress <= 'z') keypress - ('a' - 'A') else keypress; return switch (modifiers) { - mod.CTRL => switch (keynormal) { + input.mod.ctrl => switch (keynormal) { 'J' => command.executeName("toggle_panel", .{}), 'Q' => command.executeName("quit", .{}), 'W' => command.executeName("close_file", .{}), @@ -45,16 +43,16 @@ fn mapPress(keypress: u32, egc: u32, modifiers: u32) !void { 'V' => command.executeName("system_paste", .{}), 'C' => command.executeName("palette_menu_cancel", .{}), 'G' => command.executeName("palette_menu_cancel", .{}), - key.ESC => command.executeName("palette_menu_cancel", .{}), - key.UP => command.executeName("palette_menu_up", .{}), - key.DOWN => command.executeName("palette_menu_down", .{}), - key.PGUP => command.executeName("palette_menu_pageup", .{}), - key.PGDOWN => command.executeName("palette_menu_pagedown", .{}), - key.ENTER => command.executeName("palette_menu_activate", .{}), - key.BACKSPACE => command.executeName("overlay_delete_word_left", .{}), + input.key.escape => command.executeName("palette_menu_cancel", .{}), + input.key.up => command.executeName("palette_menu_up", .{}), + input.key.down => command.executeName("palette_menu_down", .{}), + input.key.page_up => command.executeName("palette_menu_pageup", .{}), + input.key.page_down => command.executeName("palette_menu_pagedown", .{}), + input.key.enter => command.executeName("palette_menu_activate", .{}), + input.key.backspace => command.executeName("overlay_delete_word_left", .{}), else => {}, }, - mod.CTRL | mod.SHIFT => switch (keynormal) { + input.mod.ctrl | input.mod.shift => switch (keynormal) { 'E' => command.executeName("palette_menu_up", .{}), // open recent repeat key 'R' => command.executeName("palette_menu_up", .{}), // open recent project repeat key 'P' => command.executeName("palette_menu_down", .{}), // command palette repeat key @@ -64,34 +62,34 @@ fn mapPress(keypress: u32, egc: u32, modifiers: u32) !void { 'I' => command.executeName("overlay_toggle_inputview", .{}), else => {}, }, - mod.ALT | mod.SHIFT => switch (keynormal) { + input.mod.alt | input.mod.shift => switch (keynormal) { 'P' => command.executeName("palette_menu_down", .{}), else => {}, }, - mod.ALT => switch (keynormal) { + input.mod.alt => switch (keynormal) { 'P' => command.executeName("palette_menu_up", .{}), 'L' => command.executeName("toggle_panel", .{}), 'I' => command.executeName("toggle_inputview", .{}), else => {}, }, - mod.SHIFT => switch (keypress) { - else => if (!key.synthesized_p(keypress)) + input.mod.shift => switch (keypress) { + else => if (!input.is_non_input_key(keypress)) command.executeName("overlay_insert_code_point", command.fmt(.{egc})) else {}, }, 0 => switch (keypress) { - key.F09 => command.executeName("theme_prev", .{}), - key.F10 => command.executeName("theme_next", .{}), - key.F11 => command.executeName("toggle_panel", .{}), - key.F12 => command.executeName("toggle_inputview", .{}), - key.ESC => command.executeName("palette_menu_cancel", .{}), - key.UP => command.executeName("palette_menu_up", .{}), - key.DOWN => command.executeName("palette_menu_down", .{}), - key.PGUP => command.executeName("palette_menu_pageup", .{}), - key.PGDOWN => command.executeName("palette_menu_pagedown", .{}), - key.ENTER => command.executeName("palette_menu_activate", .{}), - key.BACKSPACE => command.executeName("overlay_delete_backwards", .{}), - else => if (!key.synthesized_p(keypress)) + input.key.f9 => command.executeName("theme_prev", .{}), + input.key.f10 => command.executeName("theme_next", .{}), + input.key.f11 => command.executeName("toggle_panel", .{}), + input.key.f12 => command.executeName("toggle_inputview", .{}), + input.key.escape => command.executeName("palette_menu_cancel", .{}), + input.key.up => command.executeName("palette_menu_up", .{}), + input.key.down => command.executeName("palette_menu_down", .{}), + input.key.page_up => command.executeName("palette_menu_pageup", .{}), + input.key.page_down => command.executeName("palette_menu_pagedown", .{}), + input.key.enter => command.executeName("palette_menu_activate", .{}), + input.key.backspace => command.executeName("overlay_delete_backwards", .{}), + else => if (!input.is_non_input_key(keypress)) command.executeName("overlay_insert_code_point", command.fmt(.{egc})) else {}, }, @@ -99,9 +97,9 @@ fn mapPress(keypress: u32, egc: u32, modifiers: u32) !void { }; } -fn mapRelease(keypress: u32, _: u32) !void { +fn map_release(keypress: input.Key) !void { return switch (keypress) { - key.LCTRL, key.RCTRL => command.executeName("overlay_release_control", .{}), + input.key.left_control, input.key.right_control => command.executeName("overlay_release_control", .{}), else => {}, }; } diff --git a/src/renderer/vaxis/input.zig b/src/renderer/vaxis/input.zig index 2a0b7cd..e6f52e5 100644 --- a/src/renderer/vaxis/input.zig +++ b/src/renderer/vaxis/input.zig @@ -1,265 +1,167 @@ -const Key = @import("vaxis").Key; -const Mouse = @import("vaxis").Mouse; +const vaxis = @import("vaxis"); -pub const key = struct { - pub const ENTER: key_type = Key.enter; - pub const TAB: key_type = Key.tab; - pub const ESC: key_type = Key.escape; - pub const SPACE: key_type = Key.space; - pub const BACKSPACE: key_type = Key.backspace; +const utf8Encode = @import("std").unicode.utf8Encode; - pub const INS: key_type = Key.insert; - pub const DEL: key_type = Key.delete; - pub const LEFT: key_type = Key.left; - pub const RIGHT: key_type = Key.right; - pub const UP: key_type = Key.up; - pub const DOWN: key_type = Key.down; - pub const PGDOWN: key_type = Key.page_down; - pub const PGUP: key_type = Key.page_up; - pub const HOME: key_type = Key.home; - pub const END: key_type = Key.end; - pub const CAPS_LOCK: key_type = Key.caps_lock; - pub const SCROLL_LOCK: key_type = Key.scroll_lock; - pub const NUM_LOCK: key_type = Key.num_lock; - pub const PRINT_SCREEN: key_type = Key.print_screen; - pub const PAUSE: key_type = Key.pause; - pub const MENU: key_type = Key.menu; - pub const F01: key_type = Key.f1; - pub const F02: key_type = Key.f2; - pub const F03: key_type = Key.f3; - pub const F04: key_type = Key.f4; - pub const F05: key_type = Key.f5; - pub const F06: key_type = Key.f6; - pub const F07: key_type = Key.f7; - pub const F08: key_type = Key.f8; - pub const F09: key_type = Key.f9; - pub const F10: key_type = Key.f10; - pub const F11: key_type = Key.f11; - pub const F12: key_type = Key.f12; - pub const F13: key_type = Key.f13; - pub const F14: key_type = Key.f14; - pub const F15: key_type = Key.f15; - pub const F16: key_type = Key.f16; - pub const F17: key_type = Key.f17; - pub const F18: key_type = Key.f18; - pub const F19: key_type = Key.f19; - pub const F20: key_type = Key.f20; - pub const F21: key_type = Key.f21; - pub const F22: key_type = Key.f22; - pub const F23: key_type = Key.f23; - pub const F24: key_type = Key.f24; - pub const F25: key_type = Key.f25; - pub const F26: key_type = Key.f26; - pub const F27: key_type = Key.f27; - pub const F28: key_type = Key.f28; - pub const F29: key_type = Key.f29; - pub const F30: key_type = Key.f30; - pub const F31: key_type = Key.f31; - pub const F32: key_type = Key.f32; - pub const F33: key_type = Key.f33; - pub const F34: key_type = Key.f34; - pub const F35: key_type = Key.f35; +pub const key = vaxis.Key; +pub const Key = u21; - pub const F58: key_type = Key.iso_level_5_shift + 1; // FIXME bogus +pub const Mouse = vaxis.Mouse.Button; +pub const MouseType = @typeInfo(Mouse).Enum.tag_type; - pub const MEDIA_PLAY: key_type = Key.media_play; - pub const MEDIA_PAUSE: key_type = Key.media_pause; - pub const MEDIA_PPAUSE: key_type = Key.media_play_pause; - pub const MEDIA_REV: key_type = Key.media_reverse; - pub const MEDIA_STOP: key_type = Key.media_stop; - pub const MEDIA_FF: key_type = Key.media_fast_forward; - pub const MEDIA_REWIND: key_type = Key.media_rewind; - pub const MEDIA_NEXT: key_type = Key.media_track_next; - pub const MEDIA_PREV: key_type = Key.media_track_previous; - pub const MEDIA_RECORD: key_type = Key.media_record; - pub const MEDIA_LVOL: key_type = Key.lower_volume; - pub const MEDIA_RVOL: key_type = Key.raise_volume; - pub const MEDIA_MUTE: key_type = Key.mute_volume; - pub const LSHIFT: key_type = Key.left_shift; - pub const LCTRL: key_type = Key.left_control; - pub const LALT: key_type = Key.left_alt; - pub const LSUPER: key_type = Key.left_super; - pub const LHYPER: key_type = Key.left_hyper; - pub const LMETA: key_type = Key.left_meta; - pub const RSHIFT: key_type = Key.right_shift; - pub const RCTRL: key_type = Key.right_control; - pub const RALT: key_type = Key.right_alt; - pub const RSUPER: key_type = Key.right_super; - pub const RHYPER: key_type = Key.right_hyper; - pub const RMETA: key_type = Key.right_meta; - pub const L3SHIFT: key_type = Key.iso_level_3_shift; - pub const L5SHIFT: key_type = Key.iso_level_5_shift; - - pub const MOTION: key_type = @intCast(@intFromEnum(Mouse.Button.none)); - pub const BUTTON1: key_type = @intCast(@intFromEnum(Mouse.Button.left)); - pub const BUTTON2: key_type = @intCast(@intFromEnum(Mouse.Button.middle)); - pub const BUTTON3: key_type = @intCast(@intFromEnum(Mouse.Button.right)); - pub const BUTTON4: key_type = @intCast(@intFromEnum(Mouse.Button.wheel_up)); - pub const BUTTON5: key_type = @intCast(@intFromEnum(Mouse.Button.wheel_down)); - // pub const BUTTON6: key_type = @intCast(@intFromEnum(Mouse.Button.button_6)); - // pub const BUTTON7: key_type = @intCast(@intFromEnum(Mouse.Button.button_7)); - pub const BUTTON8: key_type = @intCast(@intFromEnum(Mouse.Button.button_8)); - pub const BUTTON9: key_type = @intCast(@intFromEnum(Mouse.Button.button_9)); - pub const BUTTON10: key_type = @intCast(@intFromEnum(Mouse.Button.button_10)); - pub const BUTTON11: key_type = @intCast(@intFromEnum(Mouse.Button.button_11)); - - // pub const SIGNAL: key_type = Key.SIGNAL; - // pub const EOF: key_type = Key.EOF; - // pub const SCROLL_UP: key_type = Key.SCROLL_UP; - // pub const SCROLL_DOWN: key_type = Key.SCROLL_DOWN; - - /// Is this uint32_t a synthesized event? - pub fn synthesized_p(w: u32) bool { - return switch (w) { - Key.insert...Key.iso_level_5_shift => true, - Key.enter => true, - Key.tab => true, - Key.escape => true, - Key.backspace => true, - else => false, - }; - } +pub const mouse = struct { + pub const MOTION: Mouse = vaxis.Mouse.Button.none; + pub const BUTTON1: Mouse = vaxis.Mouse.Button.left; + pub const BUTTON2: Mouse = vaxis.Mouse.Button.middle; + pub const BUTTON3: Mouse = vaxis.Mouse.Button.right; + pub const BUTTON4: Mouse = vaxis.Mouse.Button.wheel_up; + pub const BUTTON5: Mouse = vaxis.Mouse.Button.wheel_down; + // pub const BUTTON6: Mouse = vaxis.Mouse.Button.button_6; + // pub const BUTTON7: Mouse = vaxis.Mouse.Button.button_7; + pub const BUTTON8: Mouse = vaxis.Mouse.Button.button_8; + pub const BUTTON9: Mouse = vaxis.Mouse.Button.button_9; + pub const BUTTON10: Mouse = vaxis.Mouse.Button.button_10; + pub const BUTTON11: Mouse = vaxis.Mouse.Button.button_11; }; -pub const key_type = u21; -pub const modifier = struct { - pub const SHIFT: modifier_type = 1; - pub const ALT: modifier_type = 2; - pub const CTRL: modifier_type = 4; - pub const SUPER: modifier_type = 8; - pub const HYPER: modifier_type = 16; - pub const META: modifier_type = 32; - pub const CAPSLOCK: modifier_type = 64; - pub const NUMLOCK: modifier_type = 128; -}; -pub const modifier_type = u32; +/// Does this key represent input? +pub fn is_non_input_key(w: Key) bool { + return switch (w) { + vaxis.Key.insert...vaxis.Key.iso_level_5_shift => true, + vaxis.Key.enter => true, + vaxis.Key.tab => true, + vaxis.Key.escape => true, + vaxis.Key.backspace => true, + else => false, + }; +} -pub const event_type = struct { - pub const PRESS: usize = 1; - pub const REPEAT: usize = 2; - pub const RELEASE: usize = 3; +pub const ModSet = vaxis.Key.Modifiers; +pub const Mods = u8; + +pub const mod = struct { + pub const shift: u8 = @bitCast(ModSet{ .shift = true }); + pub const alt: u8 = @bitCast(ModSet{ .alt = true }); + pub const ctrl: u8 = @bitCast(ModSet{ .ctrl = true }); + pub const super: u8 = @bitCast(ModSet{ .super = true }); + pub const caps_lock: u8 = @bitCast(ModSet{ .caps_lock = true }); + pub const num_lock: u8 = @bitCast(ModSet{ .num_lock = true }); }; +pub const Event = u8; +pub const event = struct { + pub const press: Event = 1; + pub const repeat: Event = 2; + pub const release: Event = 3; +}; + +pub fn ucs32_to_utf8(ucs32: []const u32, utf8: []u8) !usize { + return @intCast(try utf8Encode(@intCast(ucs32[0]), utf8)); +} + pub const utils = struct { - pub fn isSuper(modifiers: u32) bool { - return modifiers & modifier.SUPER != 0; - } - - pub fn isCtrl(modifiers: u32) bool { - return modifiers & modifier.CTRL != 0; - } - - pub fn isShift(modifiers: u32) bool { - return modifiers & modifier.SHIFT != 0; - } - - pub fn isAlt(modifiers: u32) bool { - return modifiers & modifier.ALT != 0; - } - - pub fn key_id_string(k: u32) []const u8 { + pub fn key_id_string(k: Key) []const u8 { return switch (k) { - key.ENTER => "enter", - key.TAB => "tab", - key.ESC => "esc", - key.SPACE => "space", - key.BACKSPACE => "backspace", - key.INS => "ins", - key.DEL => "del", - key.LEFT => "left", - key.RIGHT => "right", - key.UP => "up", - key.DOWN => "down", - key.PGDOWN => "pgdown", - key.PGUP => "pgup", - key.HOME => "home", - key.END => "end", - key.CAPS_LOCK => "caps_lock", - key.SCROLL_LOCK => "scroll_lock", - key.NUM_LOCK => "num_lock", - key.PRINT_SCREEN => "print_screen", - key.PAUSE => "pause", - key.MENU => "menu", - key.F01 => "f01", - key.F02 => "f02", - key.F03 => "f03", - key.F04 => "f04", - key.F05 => "f05", - key.F06 => "f06", - key.F07 => "f07", - key.F08 => "f08", - key.F09 => "f09", - key.F10 => "f10", - key.F11 => "f11", - key.F12 => "f12", - key.F13 => "f13", - key.F14 => "f14", - key.F15 => "f15", - key.F16 => "f16", - key.F17 => "f17", - key.F18 => "f18", - key.F19 => "f19", - key.F20 => "f20", - key.F21 => "f21", - key.F22 => "f22", - key.F23 => "f23", - key.F24 => "f24", - key.F25 => "f25", - key.F26 => "f26", - key.F27 => "f27", - key.F28 => "f28", - key.F29 => "f29", - key.F30 => "f30", - key.F31 => "f31", - key.F32 => "f32", - key.F33 => "f33", - key.F34 => "f34", - key.F35 => "f35", - key.MEDIA_PLAY => "media_play", - key.MEDIA_PAUSE => "media_pause", - key.MEDIA_PPAUSE => "media_ppause", - key.MEDIA_REV => "media_rev", - key.MEDIA_STOP => "media_stop", - key.MEDIA_FF => "media_ff", - key.MEDIA_REWIND => "media_rewind", - key.MEDIA_NEXT => "media_next", - key.MEDIA_PREV => "media_prev", - key.MEDIA_RECORD => "media_record", - key.MEDIA_LVOL => "media_lvol", - key.MEDIA_RVOL => "media_rvol", - key.MEDIA_MUTE => "media_mute", - key.LSHIFT => "lshift", - key.LCTRL => "lctrl", - key.LALT => "lalt", - key.LSUPER => "lsuper", - key.LHYPER => "lhyper", - key.LMETA => "lmeta", - key.RSHIFT => "rshift", - key.RCTRL => "rctrl", - key.RALT => "ralt", - key.RSUPER => "rsuper", - key.RHYPER => "rhyper", - key.RMETA => "rmeta", - key.L3SHIFT => "l3shift", - key.L5SHIFT => "l5shift", + vaxis.Key.enter => "enter", + vaxis.Key.tab => "tab", + vaxis.Key.escape => "escape", + vaxis.Key.space => "space", + vaxis.Key.backspace => "backspace", + vaxis.Key.insert => "insert", + vaxis.Key.delete => "delete", + vaxis.Key.left => "left", + vaxis.Key.right => "right", + vaxis.Key.up => "up", + vaxis.Key.down => "down", + vaxis.Key.page_down => "page_down", + vaxis.Key.page_up => "page_up", + vaxis.Key.home => "home", + vaxis.Key.end => "end", + vaxis.Key.caps_lock => "caps_lock", + vaxis.Key.scroll_lock => "scroll_lock", + vaxis.Key.num_lock => "num_lock", + vaxis.Key.print_screen => "print_screen", + vaxis.Key.pause => "pause", + vaxis.Key.menu => "menu", + vaxis.Key.f1 => "f1", + vaxis.Key.f2 => "f2", + vaxis.Key.f3 => "f3", + vaxis.Key.f4 => "f4", + vaxis.Key.f5 => "f5", + vaxis.Key.f6 => "f6", + vaxis.Key.f7 => "f7", + vaxis.Key.f8 => "f8", + vaxis.Key.f9 => "f9", + vaxis.Key.f10 => "f10", + vaxis.Key.f11 => "f11", + vaxis.Key.f12 => "f12", + vaxis.Key.f13 => "f13", + vaxis.Key.f14 => "f14", + vaxis.Key.f15 => "f15", + vaxis.Key.f16 => "f16", + vaxis.Key.f17 => "f17", + vaxis.Key.f18 => "f18", + vaxis.Key.f19 => "f19", + vaxis.Key.f20 => "f20", + vaxis.Key.f21 => "f21", + vaxis.Key.f22 => "f22", + vaxis.Key.f23 => "f23", + vaxis.Key.f24 => "f24", + vaxis.Key.f25 => "f25", + vaxis.Key.f26 => "f26", + vaxis.Key.f27 => "f27", + vaxis.Key.f28 => "f28", + vaxis.Key.f29 => "f29", + vaxis.Key.f30 => "f30", + vaxis.Key.f31 => "f31", + vaxis.Key.f32 => "f32", + vaxis.Key.f33 => "f33", + vaxis.Key.f34 => "f34", + vaxis.Key.f35 => "f35", + vaxis.Key.media_play => "media_play", + vaxis.Key.media_pause => "media_pause", + vaxis.Key.media_play_pause => "media_play_pause", + vaxis.Key.media_reverse => "media_reverse", + vaxis.Key.media_stop => "media_stop", + vaxis.Key.media_fast_forward => "media_fast_forward", + vaxis.Key.media_rewind => "media_rewind", + vaxis.Key.media_track_next => "media_track_next", + vaxis.Key.media_track_previous => "media_track_previous", + vaxis.Key.media_record => "media_record", + vaxis.Key.lower_volume => "lower_volume", + vaxis.Key.raise_volume => "raise_volume", + vaxis.Key.mute_volume => "mute_volume", + vaxis.Key.left_shift => "left_shift", + vaxis.Key.left_control => "left_control", + vaxis.Key.left_alt => "left_alt", + vaxis.Key.left_super => "left_super", + vaxis.Key.left_hyper => "left_hyper", + vaxis.Key.left_meta => "left_meta", + vaxis.Key.right_shift => "right_shift", + vaxis.Key.right_control => "right_control", + vaxis.Key.right_alt => "right_alt", + vaxis.Key.right_super => "right_super", + vaxis.Key.right_hyper => "right_hyper", + vaxis.Key.right_meta => "right_meta", + vaxis.Key.iso_level_3_shift => "iso_level_3_shift", + vaxis.Key.iso_level_5_shift => "iso_level_5_shift", else => "", }; } - pub fn button_id_string(k: u32) []const u8 { - return switch (k) { - key.MOTION => "motion", - key.BUTTON1 => "button1", - key.BUTTON2 => "button2", - key.BUTTON3 => "button3", - key.BUTTON4 => "button4", - key.BUTTON5 => "button5", - // key.BUTTON6 => "button6", - // key.BUTTON7 => "button7", - key.BUTTON8 => "button8", - key.BUTTON9 => "button9", - key.BUTTON10 => "button10", - key.BUTTON11 => "button11", + pub fn button_id_string(m: Mouse) []const u8 { + return switch (m) { + mouse.MOTION => "motion", + mouse.BUTTON1 => "button1", + mouse.BUTTON2 => "button2", + mouse.BUTTON3 => "button3", + mouse.BUTTON4 => "button4", + mouse.BUTTON5 => "button5", + // mouse.BUTTON6 => "button6", + // mouse.BUTTON7 => "button7", + mouse.BUTTON8 => "button8", + mouse.BUTTON9 => "button9", + mouse.BUTTON10 => "button10", + mouse.BUTTON11 => "button11", else => "", }; } diff --git a/src/renderer/vaxis/renderer.zig b/src/renderer/vaxis/renderer.zig index 0f30a00..dd37e8c 100644 --- a/src/renderer/vaxis/renderer.zig +++ b/src/renderer/vaxis/renderer.zig @@ -4,19 +4,15 @@ const log = @import("log"); const Style = @import("theme").Style; const Color = @import("theme").Color; const vaxis = @import("vaxis"); +const input = @import("input"); const builtin = @import("builtin"); -pub const input = @import("input.zig"); - pub const Plane = @import("Plane.zig"); pub const Cell = @import("Cell.zig"); pub const CursorShape = vaxis.Cell.CursorShape; pub const style = @import("style.zig").StyleBits; -const key = input.key; -const event_type = input.event_type; - const Self = @This(); pub const log_name = "vaxis"; @@ -158,7 +154,7 @@ pub fn process_input_event(self: *Self, input_: []const u8, text: ?[]const u8) ! try self.sync_mod_state(key_.codepoint, key_.mods); const cbor_msg = try self.fmtmsg(.{ "I", - event_type.PRESS, + input.event.press, key_.codepoint, key_.shifted_codepoint orelse key_.codepoint, text orelse input.utils.key_id_string(key_.base_layout_codepoint orelse key_.codepoint), @@ -172,7 +168,7 @@ pub fn process_input_event(self: *Self, input_: []const u8, text: ?[]const u8) ! const key_ = filter_mods(key__); const cbor_msg = try self.fmtmsg(.{ "I", - event_type.RELEASE, + input.event.release, key_.codepoint, key_.shifted_codepoint orelse key_.codepoint, text orelse input.utils.key_id_string(key_.base_layout_codepoint orelse key_.codepoint), @@ -193,9 +189,9 @@ pub fn process_input_event(self: *Self, input_: []const u8, text: ?[]const u8) ! })), .press => f(self.handler_ctx, @intCast(mouse.row), @intCast(mouse.col), try self.fmtmsg(.{ "B", - event_type.PRESS, + input.event.press, @intFromEnum(mouse.button), - input.utils.button_id_string(@intFromEnum(mouse.button)), + input.utils.button_id_string(mouse.button), mouse.col, mouse.row, mouse.xoffset, @@ -203,9 +199,9 @@ pub fn process_input_event(self: *Self, input_: []const u8, text: ?[]const u8) ! })), .release => f(self.handler_ctx, @intCast(mouse.row), @intCast(mouse.col), try self.fmtmsg(.{ "B", - event_type.RELEASE, + input.event.release, @intFromEnum(mouse.button), - input.utils.button_id_string(@intFromEnum(mouse.button)), + input.utils.button_id_string(mouse.button), mouse.col, mouse.row, mouse.xoffset, @@ -214,9 +210,9 @@ pub fn process_input_event(self: *Self, input_: []const u8, text: ?[]const u8) ! .drag => if (self.dispatch_mouse_drag) |f_| f_(self.handler_ctx, @intCast(mouse.row), @intCast(mouse.col), try self.fmtmsg(.{ "D", - event_type.PRESS, + input.event.press, @intFromEnum(mouse.button), - input.utils.button_id_string(@intFromEnum(mouse.button)), + input.utils.button_id_string(mouse.button), mouse.col, mouse.row, mouse.xoffset, @@ -282,19 +278,19 @@ fn fmtmsg(self: *Self, value: anytype) ![]const u8 { } fn handle_bracketed_paste_input(self: *Self, cbor_msg: []const u8) !bool { - var keypress: u32 = undefined; - var egc_: u32 = undefined; + var keypress: input.Key = undefined; + var egc_: input.Key = undefined; if (try cbor.match(cbor_msg, .{ "I", cbor.number, cbor.extract(&keypress), cbor.extract(&egc_), cbor.string, 0 })) { switch (keypress) { - key.ENTER => try self.bracketed_paste_buffer.appendSlice("\n"), - key.TAB => try self.bracketed_paste_buffer.appendSlice("\t"), - else => if (!key.synthesized_p(keypress)) { + input.key.enter => try self.bracketed_paste_buffer.appendSlice("\n"), + input.key.tab => try self.bracketed_paste_buffer.appendSlice("\t"), + else => if (!input.is_non_input_key(keypress)) { var buf: [6]u8 = undefined; - const bytes = try ucs32_to_utf8(&[_]u32{egc_}, &buf); + const bytes = try input.ucs32_to_utf8(&[_]u32{egc_}, &buf); try self.bracketed_paste_buffer.appendSlice(buf[0..bytes]); } else { var buf: [6]u8 = undefined; - const bytes = try ucs32_to_utf8(&[_]u32{egc_}, &buf); + const bytes = try input.ucs32_to_utf8(&[_]u32{egc_}, &buf); self.logger.print("unexpected codepoint in paste: {d} {s}", .{ keypress, buf[0..bytes] }); }, } @@ -336,7 +332,7 @@ pub fn set_terminal_style(self: *Self, style_: Style) void { } pub fn set_terminal_cursor_color(self: *Self, color: Color) void { - self.vx.setTerminalCursorColor(self.tty.anyWriter(), vaxis.Cell.Color.rgbFromUint(@intCast(color.color)).rgb) catch {}; + self.vx.setTerminalCursorColor(self.tty.anyWriter(), vaxis.Cell.Color.rgbFromUint(@intCast(color.color)).rgb) catch {}; } pub fn set_terminal_working_directory(self: *Self, absolute_path: []const u8) void { @@ -376,32 +372,28 @@ pub fn cursor_disable(self: *Self) void { self.vx.screen.cursor_vis = false; } -pub fn ucs32_to_utf8(ucs32: []const u32, utf8: []u8) !usize { - return @intCast(try std.unicode.utf8Encode(@intCast(ucs32[0]), utf8)); -} - fn sync_mod_state(self: *Self, keypress: u32, modifiers: vaxis.Key.Modifiers) !void { - if (modifiers.ctrl and !self.mods.ctrl and !(keypress == key.LCTRL or keypress == key.RCTRL)) - try self.send_sync_key(event_type.PRESS, key.LCTRL, "lctrl", modifiers); - if (!modifiers.ctrl and self.mods.ctrl and !(keypress == key.LCTRL or keypress == key.RCTRL)) - try self.send_sync_key(event_type.RELEASE, key.LCTRL, "lctrl", modifiers); - if (modifiers.alt and !self.mods.alt and !(keypress == key.LALT or keypress == key.RALT)) - try self.send_sync_key(event_type.PRESS, key.LALT, "lalt", modifiers); - if (!modifiers.alt and self.mods.alt and !(keypress == key.LALT or keypress == key.RALT)) - try self.send_sync_key(event_type.RELEASE, key.LALT, "lalt", modifiers); - if (modifiers.shift and !self.mods.shift and !(keypress == key.LSHIFT or keypress == key.RSHIFT)) - try self.send_sync_key(event_type.PRESS, key.LSHIFT, "lshift", modifiers); - if (!modifiers.shift and self.mods.shift and !(keypress == key.LSHIFT or keypress == key.RSHIFT)) - try self.send_sync_key(event_type.RELEASE, key.LSHIFT, "lshift", modifiers); + if (modifiers.ctrl and !self.mods.ctrl and !(keypress == input.key.left_control or keypress == input.key.right_control)) + try self.send_sync_key(input.event.press, input.key.left_control, "lctrl", modifiers); + if (!modifiers.ctrl and self.mods.ctrl and !(keypress == input.key.left_control or keypress == input.key.right_control)) + try self.send_sync_key(input.event.release, input.key.left_control, "lctrl", modifiers); + if (modifiers.alt and !self.mods.alt and !(keypress == input.key.left_alt or keypress == input.key.right_alt)) + try self.send_sync_key(input.event.press, input.key.left_alt, "lalt", modifiers); + if (!modifiers.alt and self.mods.alt and !(keypress == input.key.left_alt or keypress == input.key.right_alt)) + try self.send_sync_key(input.event.release, input.key.left_alt, "lalt", modifiers); + if (modifiers.shift and !self.mods.shift and !(keypress == input.key.left_shift or keypress == input.key.right_shift)) + try self.send_sync_key(input.event.press, input.key.left_shift, "lshift", modifiers); + if (!modifiers.shift and self.mods.shift and !(keypress == input.key.left_shift or keypress == input.key.right_shift)) + try self.send_sync_key(input.event.release, input.key.left_shift, "lshift", modifiers); self.mods = modifiers; } -fn send_sync_key(self: *Self, event_type_: usize, keypress: u32, key_string: []const u8, modifiers: vaxis.Key.Modifiers) !void { +fn send_sync_key(self: *Self, event: input.Event, keypress: u32, key_string: []const u8, modifiers: vaxis.Key.Modifiers) !void { if (self.dispatch_input) |f| f( self.handler_ctx, try self.fmtmsg(.{ "I", - event_type_, + event, keypress, keypress, key_string, diff --git a/src/tui/Button.zig b/src/tui/Button.zig index e662fb3..54089f8 100644 --- a/src/tui/Button.zig +++ b/src/tui/Button.zig @@ -3,8 +3,7 @@ const tp = @import("thespian"); const EventHandler = @import("EventHandler"); const Plane = @import("renderer").Plane; -const key = @import("renderer").input.key; -const event_type = @import("renderer").input.event_type; +const input = @import("input"); const Widget = @import("Widget.zig"); const tui = @import("tui.zig"); @@ -92,36 +91,37 @@ pub fn State(ctx_type: type) type { } pub fn receive(self: *Self, from: tp.pid_ref, m: tp.message) error{Exit}!bool { - var btn: u32 = 0; - if (try m.match(.{ "B", event_type.PRESS, tp.extract(&btn), tp.more })) { - switch (btn) { - key.BUTTON1 => { + var btn: input.MouseType = 0; + if (try m.match(.{ "B", input.event.press, tp.extract(&btn), tp.more })) { + const btn_enum: input.Mouse = @enumFromInt(btn); + switch (btn_enum) { + input.mouse.BUTTON1 => { self.active = true; tui.need_render(); }, - key.BUTTON4, key.BUTTON5 => { - self.call_click_handler(btn); + input.mouse.BUTTON4, input.mouse.BUTTON5 => { + self.call_click_handler(btn_enum); return true; }, else => {}, } return true; - } else if (try m.match(.{ "B", event_type.RELEASE, tp.extract(&btn), tp.more })) { - self.call_click_handler(btn); + } else if (try m.match(.{ "B", input.event.release, tp.extract(&btn), tp.more })) { + self.call_click_handler(@enumFromInt(btn)); tui.need_render(); return true; - } else if (try m.match(.{ "D", event_type.PRESS, tp.extract(&btn), tp.more })) { + } else if (try m.match(.{ "D", input.event.press, tp.extract(&btn), tp.more })) { if (self.opts.on_event) |h| { self.active = false; h.send(from, m) catch {}; } return true; - } else if (try m.match(.{ "D", event_type.RELEASE, tp.extract(&btn), tp.more })) { + } else if (try m.match(.{ "D", input.event.release, tp.extract(&btn), tp.more })) { if (self.opts.on_event) |h| { self.active = false; h.send(from, m) catch {}; } - self.call_click_handler(btn); + self.call_click_handler(@enumFromInt(btn)); tui.need_render(); return true; } else if (try m.match(.{ "H", tp.extract(&self.hover) })) { @@ -132,18 +132,18 @@ pub fn State(ctx_type: type) type { return self.opts.on_receive(&self.opts.ctx, self, from, m); } - fn call_click_handler(self: *Self, btn: u32) void { - if (btn == key.BUTTON1) { + fn call_click_handler(self: *Self, btn: input.Mouse) void { + if (btn == input.mouse.BUTTON1) { if (!self.active) return; self.active = false; } if (!self.hover) return; switch (btn) { - key.BUTTON1 => self.opts.on_click(&self.opts.ctx, self), - key.BUTTON2 => self.opts.on_click2(&self.opts.ctx, self), - key.BUTTON3 => self.opts.on_click3(&self.opts.ctx, self), - key.BUTTON4 => self.opts.on_click4(&self.opts.ctx, self), - key.BUTTON5 => self.opts.on_click5(&self.opts.ctx, self), + input.mouse.BUTTON1 => self.opts.on_click(&self.opts.ctx, self), + input.mouse.BUTTON2 => self.opts.on_click2(&self.opts.ctx, self), + input.mouse.BUTTON3 => self.opts.on_click3(&self.opts.ctx, self), + input.mouse.BUTTON4 => self.opts.on_click4(&self.opts.ctx, self), + input.mouse.BUTTON5 => self.opts.on_click5(&self.opts.ctx, self), else => {}, } } diff --git a/src/tui/InputBox.zig b/src/tui/InputBox.zig index 93186d2..1957969 100644 --- a/src/tui/InputBox.zig +++ b/src/tui/InputBox.zig @@ -2,8 +2,7 @@ const std = @import("std"); const tp = @import("thespian"); const Plane = @import("renderer").Plane; -const key = @import("renderer").input.key; -const event_type = @import("renderer").input.event_type; +const input = @import("input"); const Widget = @import("Widget.zig"); const tui = @import("tui.zig"); @@ -99,16 +98,16 @@ pub fn State(ctx_type: type) type { } pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { - if (try m.match(.{ "B", event_type.PRESS, key.BUTTON1, tp.any, tp.any, tp.any, tp.any, tp.any })) { + if (try m.match(.{ "B", input.event.press, @intFromEnum(input.mouse.BUTTON1), tp.any, tp.any, tp.any, tp.any, tp.any })) { self.active = true; tui.need_render(); return true; - } else if (try m.match(.{ "B", event_type.RELEASE, key.BUTTON1, tp.any, tp.any, tp.any, tp.any, tp.any })) { + } else if (try m.match(.{ "B", input.event.release, @intFromEnum(input.mouse.BUTTON1), tp.any, tp.any, tp.any, tp.any, tp.any })) { self.opts.on_click(self.opts.ctx, self); self.active = false; tui.need_render(); return true; - } else if (try m.match(.{ "D", event_type.RELEASE, key.BUTTON1, tp.any, tp.any, tp.any, tp.any, tp.any })) { + } else if (try m.match(.{ "D", input.event.release, @intFromEnum(input.mouse.BUTTON1), tp.any, tp.any, tp.any, tp.any, tp.any })) { self.opts.on_click(self.opts.ctx, self); self.active = false; tui.need_render(); diff --git a/src/tui/ModalBackground.zig b/src/tui/ModalBackground.zig index 31f9cfb..c6c8ac9 100644 --- a/src/tui/ModalBackground.zig +++ b/src/tui/ModalBackground.zig @@ -5,8 +5,7 @@ const EventHandler = @import("EventHandler"); const tui = @import("tui.zig"); const Widget = @import("Widget.zig"); const Plane = @import("renderer").Plane; -const key = @import("renderer").input.key; -const event_type = @import("renderer").input.event_type; +const input = @import("input"); pub fn Options(context: type) type { return struct { @@ -95,16 +94,16 @@ pub fn State(ctx_type: type) type { } pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { - var btn: u32 = 0; - if (try m.match(.{ "B", event_type.PRESS, tp.more })) { + var btn: input.MouseType = 0; + if (try m.match(.{ "B", input.event.press, tp.more })) { return true; - } else if (try m.match(.{ "B", event_type.RELEASE, tp.extract(&btn), tp.more })) { - self.call_click_handler(btn); + } else if (try m.match(.{ "B", input.event.release, tp.extract(&btn), tp.more })) { + self.call_click_handler(@enumFromInt(btn)); return true; - } else if (try m.match(.{ "D", event_type.PRESS, tp.extract(&btn), tp.more })) { + } else if (try m.match(.{ "D", input.event.press, tp.extract(&btn), tp.more })) { return true; - } else if (try m.match(.{ "D", event_type.RELEASE, tp.extract(&btn), tp.more })) { - self.call_click_handler(btn); + } else if (try m.match(.{ "D", input.event.release, tp.extract(&btn), tp.more })) { + self.call_click_handler(@enumFromInt(btn)); return true; } else if (try m.match(.{ "H", tp.extract(&self.hover) })) { tui.current().rdr.request_mouse_cursor_default(self.hover); @@ -113,14 +112,14 @@ pub fn State(ctx_type: type) type { return false; } - fn call_click_handler(self: *Self, btn: u32) void { + fn call_click_handler(self: *Self, btn: input.Mouse) void { if (!self.hover) return; switch (btn) { - key.BUTTON1 => self.opts.on_click(self.opts.ctx, self), - key.BUTTON2 => self.opts.on_click2(self.opts.ctx, self), - key.BUTTON3 => self.opts.on_click3(self.opts.ctx, self), - key.BUTTON4 => self.opts.on_click4(self.opts.ctx, self), - key.BUTTON5 => self.opts.on_click5(self.opts.ctx, self), + input.mouse.BUTTON1 => self.opts.on_click(self.opts.ctx, self), + input.mouse.BUTTON2 => self.opts.on_click2(self.opts.ctx, self), + input.mouse.BUTTON3 => self.opts.on_click3(self.opts.ctx, self), + input.mouse.BUTTON4 => self.opts.on_click4(self.opts.ctx, self), + input.mouse.BUTTON5 => self.opts.on_click5(self.opts.ctx, self), else => {}, } } diff --git a/src/tui/editor.zig b/src/tui/editor.zig index c38ed6f..d27fa49 100644 --- a/src/tui/editor.zig +++ b/src/tui/editor.zig @@ -14,8 +14,7 @@ const root_mod = @import("root"); const Plane = @import("renderer").Plane; const Cell = @import("renderer").Cell; -const key = @import("renderer").input.key; -const event_type = @import("renderer").input.event_type; +const input = @import("input"); const command = @import("command"); const EventHandler = @import("EventHandler"); @@ -834,7 +833,7 @@ pub const Editor = struct { mode.cursor_shape else .block; - tui.current().rdr.cursor_enable(y, x, shape) catch {}; + tui.current().rdr.cursor_enable(y, x, tui.translate_cursor_shape(shape)) catch {}; } else { tui.current().rdr.cursor_disable(); } @@ -4104,7 +4103,7 @@ pub const EditorWidget = struct { editor: Editor, commands: Commands = undefined, - last_btn: c_int = -1, + last_btn: input.Mouse = .none, last_btn_time_ms: i64 = 0, last_btn_count: usize = 0, @@ -4163,8 +4162,8 @@ pub const EditorWidget = struct { } fn receive_safe(self: *Self, m: tp.message) !bool { - var evtype: c_int = undefined; - var btn: c_int = undefined; + var event: input.Event = undefined; + var btn: input.MouseType = undefined; var x: c_int = undefined; var y: c_int = undefined; var xpx: c_int = undefined; @@ -4179,10 +4178,10 @@ pub const EditorWidget = struct { if (self.editor.jump_mode) self.update_hover_timer(.init); } - } else if (try m.match(.{ "B", tp.extract(&evtype), tp.extract(&btn), tp.any, tp.extract(&x), tp.extract(&y), tp.extract(&xpx), tp.extract(&ypx) })) { - try self.mouse_click_event(evtype, btn, y, x, ypx, xpx); - } else if (try m.match(.{ "D", tp.extract(&evtype), tp.extract(&btn), tp.any, tp.extract(&x), tp.extract(&y), tp.extract(&xpx), tp.extract(&ypx) })) { - try self.mouse_drag_event(evtype, btn, y, x, ypx, xpx); + } else if (try m.match(.{ "B", tp.extract(&event), tp.extract(&btn), tp.any, tp.extract(&x), tp.extract(&y), tp.extract(&xpx), tp.extract(&ypx) })) { + try self.mouse_click_event(event, @enumFromInt(btn), y, x, ypx, xpx); + } else if (try m.match(.{ "D", tp.extract(&event), tp.extract(&btn), tp.any, tp.extract(&x), tp.extract(&y), tp.extract(&xpx), tp.extract(&ypx) })) { + try self.mouse_drag_event(event, @enumFromInt(btn), y, x, ypx, xpx); } else if (try m.match(.{ "scroll_to", tp.extract(&pos) })) { self.editor.scroll_to(pos); } else if (try m.match(.{ "filter", "stdout", tp.extract(&bytes) })) { @@ -4227,16 +4226,16 @@ pub const EditorWidget = struct { const Result = command.Result; - fn mouse_click_event(self: *Self, evtype: c_int, btn: c_int, y: c_int, x: c_int, ypx: c_int, xpx: c_int) Result { - if (evtype != event_type.PRESS) return; + fn mouse_click_event(self: *Self, event: input.Event, btn: input.Mouse, y: c_int, x: c_int, ypx: c_int, xpx: c_int) Result { + if (event != input.event.press) return; const ret = (switch (btn) { - key.BUTTON1 => &mouse_click_button1, - key.BUTTON2 => &mouse_click_button2, - key.BUTTON3 => &mouse_click_button3, - key.BUTTON4 => &mouse_click_button4, - key.BUTTON5 => &mouse_click_button5, - key.BUTTON8 => &mouse_click_button8, //back - key.BUTTON9 => &mouse_click_button9, //forward + input.mouse.BUTTON1 => &mouse_click_button1, + input.mouse.BUTTON2 => &mouse_click_button2, + input.mouse.BUTTON3 => &mouse_click_button3, + input.mouse.BUTTON4 => &mouse_click_button4, + input.mouse.BUTTON5 => &mouse_click_button5, + input.mouse.BUTTON8 => &mouse_click_button8, //back + input.mouse.BUTTON9 => &mouse_click_button9, //forward else => return, })(self, y, x, ypx, xpx); self.last_btn = btn; @@ -4244,19 +4243,19 @@ pub const EditorWidget = struct { return ret; } - fn mouse_drag_event(self: *Self, evtype: c_int, btn: c_int, y: c_int, x: c_int, ypx: c_int, xpx: c_int) Result { - if (evtype != event_type.PRESS) return; + fn mouse_drag_event(self: *Self, event: input.Event, btn: input.Mouse, y: c_int, x: c_int, ypx: c_int, xpx: c_int) Result { + if (event != input.event.press) return; return (switch (btn) { - key.BUTTON1 => &mouse_drag_button1, - key.BUTTON2 => &mouse_drag_button2, - key.BUTTON3 => &mouse_drag_button3, + input.mouse.BUTTON1 => &mouse_drag_button1, + input.mouse.BUTTON2 => &mouse_drag_button2, + input.mouse.BUTTON3 => &mouse_drag_button3, else => return, })(self, y, x, ypx, xpx); } fn mouse_click_button1(self: *Self, y: c_int, x: c_int, _: c_int, _: c_int) Result { const y_, const x_ = self.editor.plane.abs_yx_to_rel(y, x); - if (self.last_btn == key.BUTTON1) { + if (self.last_btn == input.mouse.BUTTON1) { const click_time_ms = time.milliTimestamp() - self.last_btn_time_ms; if (click_time_ms <= double_click_time_ms) { if (self.last_btn_count == 2) { diff --git a/src/tui/editor_gutter.zig b/src/tui/editor_gutter.zig index 2a668e2..a7a0e86 100644 --- a/src/tui/editor_gutter.zig +++ b/src/tui/editor_gutter.zig @@ -8,8 +8,7 @@ const root = @import("root"); const Plane = @import("renderer").Plane; const style = @import("renderer").style; -const key = @import("renderer").input.key; -const event_type = @import("renderer").input.event_type; +const input = @import("input"); const command = @import("command"); const EventHandler = @import("EventHandler"); @@ -90,15 +89,15 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { var y: i32 = undefined; var ypx: i32 = undefined; - if (try m.match(.{ "B", event_type.PRESS, key.BUTTON1, tp.any, tp.any, tp.extract(&y), tp.any, tp.extract(&ypx) })) + if (try m.match(.{ "B", input.event.press, @intFromEnum(input.mouse.BUTTON1), tp.any, tp.any, tp.extract(&y), tp.any, tp.extract(&ypx) })) return self.primary_click(y); - if (try m.match(.{ "B", event_type.PRESS, key.BUTTON3, tp.any, tp.any, tp.extract(&y), tp.any, tp.extract(&ypx) })) + if (try m.match(.{ "B", input.event.press, @intFromEnum(input.mouse.BUTTON3), tp.any, tp.any, tp.extract(&y), tp.any, tp.extract(&ypx) })) return self.secondary_click(); - if (try m.match(.{ "D", event_type.PRESS, key.BUTTON1, tp.any, tp.any, tp.extract(&y), tp.any, tp.extract(&ypx) })) + if (try m.match(.{ "D", input.event.press, @intFromEnum(input.mouse.BUTTON1), tp.any, tp.any, tp.extract(&y), tp.any, tp.extract(&ypx) })) return self.primary_drag(y); - if (try m.match(.{ "B", event_type.PRESS, key.BUTTON4, tp.more })) + if (try m.match(.{ "B", input.event.press, @intFromEnum(input.mouse.BUTTON4), tp.more })) return self.mouse_click_button4(); - if (try m.match(.{ "B", event_type.PRESS, key.BUTTON5, tp.more })) + if (try m.match(.{ "B", input.event.press, @intFromEnum(input.mouse.BUTTON5), tp.more })) return self.mouse_click_button5(); return false; diff --git a/src/tui/mainview.zig b/src/tui/mainview.zig index 3c80b8b..664f5f8 100644 --- a/src/tui/mainview.zig +++ b/src/tui/mainview.zig @@ -9,8 +9,7 @@ const project_manager = @import("project_manager"); const log = @import("log"); const Plane = @import("renderer").Plane; -const key = @import("renderer").input.key; -const event_type = @import("renderer").input.event_type; +const input = @import("input"); const command = @import("command"); const tui = @import("tui.zig"); @@ -150,7 +149,7 @@ pub fn box(self: *const Self) Box { fn handle_bottom_bar_event(self: *Self, _: tp.pid_ref, m: tp.message) tp.result { var y: usize = undefined; - if (try m.match(.{ "D", event_type.PRESS, key.BUTTON1, tp.any, tp.any, tp.extract(&y), tp.any, tp.any })) + if (try m.match(.{ "D", input.event.press, @intFromEnum(input.mouse.BUTTON1), tp.any, tp.any, tp.extract(&y), tp.any, tp.any })) return self.bottom_bar_primary_drag(y); } diff --git a/src/tui/mode/mini/file_browser.zig b/src/tui/mode/mini/file_browser.zig index 1df1d5e..57daef3 100644 --- a/src/tui/mode/mini/file_browser.zig +++ b/src/tui/mode/mini/file_browser.zig @@ -4,11 +4,8 @@ const cbor = @import("cbor"); const log = @import("log"); const root = @import("root"); -const key = @import("renderer").input.key; -const mod = @import("renderer").input.modifier; -const event_type = @import("renderer").input.event_type; +const input = @import("input"); const keybind = @import("keybind"); -const ucs32_to_utf8 = @import("renderer").ucs32_to_utf8; const project_manager = @import("project_manager"); const command = @import("command"); const EventHandler = @import("EventHandler"); @@ -310,7 +307,7 @@ pub fn Create(options: type) type { return error.InvalidArgument; self.complete_trigger_count = 0; var buf: [32]u8 = undefined; - const bytes = try ucs32_to_utf8(&[_]u32{egc}, &buf); + const bytes = try input.ucs32_to_utf8(&[_]u32{egc}, &buf); try self.file_path.appendSlice(buf[0..bytes]); self.update_mini_mode_text(); } diff --git a/src/tui/mode/mini/find.zig b/src/tui/mode/mini/find.zig index 635d821..596c628 100644 --- a/src/tui/mode/mini/find.zig +++ b/src/tui/mode/mini/find.zig @@ -1,10 +1,7 @@ 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 input = @import("input"); const keybind = @import("keybind"); -const ucs32_to_utf8 = @import("renderer").ucs32_to_utf8; const command = @import("command"); const EventHandler = @import("EventHandler"); @@ -82,7 +79,7 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { fn insert_code_point(self: *Self, c: u32) !void { var buf: [16]u8 = undefined; - const bytes = ucs32_to_utf8(&[_]u32{c}, &buf) catch |e| return tp.exit_error(e, @errorReturnTrace()); + const bytes = input.ucs32_to_utf8(&[_]u32{c}, &buf) catch |e| return tp.exit_error(e, @errorReturnTrace()); try self.input.appendSlice(buf[0..bytes]); } diff --git a/src/tui/mode/mini/find_in_files.zig b/src/tui/mode/mini/find_in_files.zig index f35eceb..321fc50 100644 --- a/src/tui/mode/mini/find_in_files.zig +++ b/src/tui/mode/mini/find_in_files.zig @@ -1,10 +1,7 @@ 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 input = @import("input"); const keybind = @import("keybind"); -const ucs32_to_utf8 = @import("renderer").ucs32_to_utf8; const command = @import("command"); const EventHandler = @import("EventHandler"); @@ -75,7 +72,7 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { fn insert_code_point(self: *Self, c: u32) !void { if (self.input.len + 16 > self.buf.len) try self.flush_input(); - const bytes = try ucs32_to_utf8(&[_]u32{c}, self.buf[self.input.len..]); + const bytes = try input.ucs32_to_utf8(&[_]u32{c}, self.buf[self.input.len..]); self.input = self.buf[0 .. self.input.len + bytes]; } diff --git a/src/tui/mode/mini/move_to_char.zig b/src/tui/mode/mini/move_to_char.zig index fcb573c..da7dee4 100644 --- a/src/tui/mode/mini/move_to_char.zig +++ b/src/tui/mode/mini/move_to_char.zig @@ -1,9 +1,6 @@ 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 input = @import("input"); const keybind = @import("keybind"); const command = @import("command"); const EventHandler = @import("EventHandler"); @@ -89,7 +86,7 @@ fn execute_operation(self: *Self, c: u32) void { }, }; var buf: [6]u8 = undefined; - const bytes = ucs32_to_utf8(&[_]u32{c}, &buf) catch return; + const bytes = input.ucs32_to_utf8(&[_]u32{c}, &buf) catch return; command.executeName(cmd, command.fmt(.{buf[0..bytes]})) catch {}; command.executeName("exit_mini_mode", .{}) catch {}; } @@ -104,7 +101,7 @@ const cmds = struct { 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 bytes = input.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", diff --git a/src/tui/mode/overlay/open_recent.zig b/src/tui/mode/overlay/open_recent.zig index 8b71ee8..233b349 100644 --- a/src/tui/mode/overlay/open_recent.zig +++ b/src/tui/mode/overlay/open_recent.zig @@ -5,11 +5,8 @@ const cbor = @import("cbor"); const root = @import("root"); const Plane = @import("renderer").Plane; -const key = @import("renderer").input.key; -const mod = @import("renderer").input.modifier; -const event_type = @import("renderer").input.event_type; +const input = @import("input"); const keybind = @import("keybind"); -const ucs32_to_utf8 = @import("renderer").ucs32_to_utf8; const project_manager = @import("project_manager"); const command = @import("command"); const EventHandler = @import("EventHandler"); @@ -243,7 +240,7 @@ fn delete_code_point(self: *Self) !void { fn insert_code_point(self: *Self, c: u32) !void { var buf: [6]u8 = undefined; - const bytes = try ucs32_to_utf8(&[_]u32{c}, &buf); + const bytes = try input.ucs32_to_utf8(&[_]u32{c}, &buf); try self.inputbox.text.appendSlice(buf[0..bytes]); self.inputbox.cursor = self.inputbox.text.items.len; return self.start_query(); diff --git a/src/tui/mode/overlay/palette.zig b/src/tui/mode/overlay/palette.zig index 1d40834..a2f58bb 100644 --- a/src/tui/mode/overlay/palette.zig +++ b/src/tui/mode/overlay/palette.zig @@ -5,11 +5,8 @@ const cbor = @import("cbor"); const fuzzig = @import("fuzzig"); const Plane = @import("renderer").Plane; -const key = @import("renderer").input.key; -const mod = @import("renderer").input.modifier; -const event_type = @import("renderer").input.event_type; +const input = @import("input"); const keybind = @import("keybind"); -const ucs32_to_utf8 = @import("renderer").ucs32_to_utf8; const command = @import("command"); const EventHandler = @import("EventHandler"); @@ -315,7 +312,7 @@ pub fn Create(options: type) type { fn insert_code_point(self: *Self, c: u32) !void { var buf: [6]u8 = undefined; - const bytes = try ucs32_to_utf8(&[_]u32{c}, &buf); + const bytes = try input.ucs32_to_utf8(&[_]u32{c}, &buf); try self.inputbox.text.appendSlice(buf[0..bytes]); self.inputbox.cursor = self.inputbox.text.items.len; self.view_pos = 0; diff --git a/src/tui/scrollbar_v.zig b/src/tui/scrollbar_v.zig index 619dde7..f279bcb 100644 --- a/src/tui/scrollbar_v.zig +++ b/src/tui/scrollbar_v.zig @@ -3,8 +3,7 @@ const tp = @import("thespian"); const tracy = @import("tracy"); const Plane = @import("renderer").Plane; -const key = @import("renderer").input.key; -const event_type = @import("renderer").input.event_type; +const input = @import("input"); const EventHandler = @import("EventHandler"); const Widget = @import("Widget.zig"); @@ -64,21 +63,21 @@ pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { var y: i32 = undefined; var ypx: i32 = undefined; - if (try m.match(.{ "B", event_type.PRESS, key.BUTTON1, tp.any, tp.any, tp.extract(&y), tp.any, tp.extract(&ypx) })) { + if (try m.match(.{ "B", input.event.press, @intFromEnum(input.mouse.BUTTON1), tp.any, tp.any, tp.extract(&y), tp.any, tp.extract(&ypx) })) { self.active = true; self.move_to(y, ypx); return true; - } else if (try m.match(.{ "B", event_type.RELEASE, tp.more })) { + } else if (try m.match(.{ "B", input.event.release, tp.more })) { self.active = false; return true; - } else if (try m.match(.{ "D", event_type.PRESS, key.BUTTON1, tp.any, tp.any, tp.extract(&y), tp.any, tp.extract(&ypx) })) { + } else if (try m.match(.{ "D", input.event.press, @intFromEnum(input.mouse.BUTTON1), tp.any, tp.any, tp.extract(&y), tp.any, tp.extract(&ypx) })) { self.active = true; self.move_to(y, ypx); return true; - } else if (try m.match(.{ "B", event_type.RELEASE, tp.more })) { + } else if (try m.match(.{ "B", input.event.release, tp.more })) { self.active = false; return true; - } else if (try m.match(.{ "D", event_type.RELEASE, tp.more })) { + } else if (try m.match(.{ "D", input.event.release, tp.more })) { self.active = false; return true; } else if (try m.match(.{ "H", tp.extract(&self.hover) })) { diff --git a/src/tui/status/keystate.zig b/src/tui/status/keystate.zig index 209b0f3..2afcd2b 100644 --- a/src/tui/status/keystate.zig +++ b/src/tui/status/keystate.zig @@ -4,9 +4,7 @@ const tp = @import("thespian"); const tracy = @import("tracy"); const Plane = @import("renderer").Plane; -const utils = @import("renderer").input.utils; -const key_ = @import("renderer").input.key; -const event_type = @import("renderer").input.event_type; +const input = @import("input"); const command = @import("command"); const EventHandler = @import("EventHandler"); @@ -24,7 +22,7 @@ hover: bool = false, keys: [history]Key = [_]Key{.{}} ** history, -const Key = struct { id: u32 = 0, mod: u32 = 0 }; +const Key = struct { id: input.Key = 0, mod: input.ModSet = .{} }; const Self = @This(); @@ -63,15 +61,15 @@ fn render_active(self: *Self) bool { return true; if (c > 0) _ = self.plane.putstr(" ") catch {}; - if (utils.isSuper(k.mod)) + if (k.mod.super) _ = self.plane.putstr("H-") catch {}; - if (utils.isCtrl(k.mod)) + if (k.mod.ctrl) _ = self.plane.putstr("C-") catch {}; - if (utils.isShift(k.mod)) + if (k.mod.shift) _ = self.plane.putstr("S-") catch {}; - if (utils.isAlt(k.mod)) + if (k.mod.alt) _ = self.plane.putstr("A-") catch {}; - _ = self.plane.print("{s}", .{utils.key_id_string(k.id)}) catch {}; + _ = self.plane.print("{s}", .{input.utils.key_id_string(k.id)}) catch {}; c += 1; } return true; @@ -144,7 +142,7 @@ fn unset_nkey(self: *Self, key: Key) void { fn unset_key_all(self: *Self) void { for (0..self.keys.len) |i| { self.keys[i].id = 0; - self.keys[i].mod = 0; + self.keys[i].mod = .{}; } } @@ -155,17 +153,17 @@ fn set_key(self: *Self, key: Key, val: bool) void { } pub fn listen(self: *Self, _: tp.pid_ref, m: tp.message) tp.result { - var key: u32 = 0; - var mod: u32 = 0; - if (try m.match(.{ "I", event_type.PRESS, tp.extract(&key), tp.any, tp.any, tp.extract(&mod), tp.more })) { - self.set_key(.{ .id = key, .mod = mod }, true); - } else if (try m.match(.{ "I", event_type.RELEASE, tp.extract(&key), tp.any, tp.any, tp.extract(&mod), tp.more })) { - self.set_key(.{ .id = key, .mod = mod }, false); + var key: input.Key = 0; + var mod: input.Mods = 0; + if (try m.match(.{ "I", input.event.press, tp.extract(&key), tp.any, tp.any, tp.extract(&mod), tp.more })) { + self.set_key(.{ .id = key, .mod = @bitCast(mod) }, true); + } else if (try m.match(.{ "I", input.event.release, tp.extract(&key), tp.any, tp.any, tp.extract(&mod), tp.more })) { + self.set_key(.{ .id = key, .mod = @bitCast(mod) }, false); } } pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { - if (try m.match(.{ "B", event_type.PRESS, key_.BUTTON1, tp.any, tp.any, tp.any, tp.any, tp.any })) { + if (try m.match(.{ "B", input.event.press, @intFromEnum(input.mouse.BUTTON1), tp.any, tp.any, tp.any, tp.any, tp.any })) { command.executeName("toggle_inputview", .{}) catch {}; return true; } diff --git a/src/tui/status/modstate.zig b/src/tui/status/modstate.zig index 25adef1..59d0a46 100644 --- a/src/tui/status/modstate.zig +++ b/src/tui/status/modstate.zig @@ -4,9 +4,7 @@ const tp = @import("thespian"); const tracy = @import("tracy"); const Plane = @import("renderer").Plane; -const key = @import("renderer").input.key; -const event_type = @import("renderer").input.event_type; -const utils = @import("renderer").input.utils; +const input = @import("input"); const command = @import("command"); const EventHandler = @import("EventHandler"); @@ -14,9 +12,7 @@ const Widget = @import("../Widget.zig"); const tui = @import("../tui.zig"); plane: Plane, -ctrl: bool = false, -shift: bool = false, -alt: bool = false, +mods: input.ModSet = .{}, hover: bool = false, const Self = @This(); @@ -54,9 +50,9 @@ pub fn render(self: *Self, theme: *const Widget.Theme) bool { self.plane.home(); _ = self.plane.print(" {s}{s}{s} ", .{ - mode(self.ctrl, "Ⓒ ", "🅒 "), - mode(self.shift, "Ⓢ ", "🅢 "), - mode(self.alt, "Ⓐ ", "🅐 "), + mode(self.mods.ctrl, "Ⓒ ", "🅒 "), + mode(self.mods.shift, "Ⓢ ", "🅢 "), + mode(self.mods.alt, "Ⓐ ", "🅐 "), }) catch {}; return false; } @@ -70,16 +66,14 @@ fn render_modifier(self: *Self, state: bool, off: [:0]const u8, on: [:0]const u8 } pub fn listen(self: *Self, _: tp.pid_ref, m: tp.message) tp.result { - var mod: u32 = 0; - if (try m.match(.{ "I", tp.any, tp.any, tp.any, tp.any, tp.extract(&mod), tp.more })) { - self.ctrl = utils.isCtrl(mod); - self.shift = utils.isShift(mod); - self.alt = utils.isAlt(mod); + var mods: input.Mods = 0; + if (try m.match(.{ "I", tp.any, tp.any, tp.any, tp.any, tp.extract(&mods), tp.more })) { + self.mods = @bitCast(mods); } } pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { - if (try m.match(.{ "B", event_type.PRESS, key.BUTTON1, tp.any, tp.any, tp.any, tp.any, tp.any })) { + if (try m.match(.{ "B", input.event.press, @intFromEnum(input.mouse.BUTTON1), tp.any, tp.any, tp.any, tp.any, tp.any })) { command.executeName("toggle_inputview", .{}) catch {}; return true; } diff --git a/src/tui/tui.zig b/src/tui/tui.zig index 5531424..3f386df 100644 --- a/src/tui/tui.zig +++ b/src/tui/tui.zig @@ -971,3 +971,15 @@ fn set_terminal_style(self: *Self) void { self.rdr.set_terminal_cursor_color(self.theme.editor_cursor.bg.?); } } + +pub fn translate_cursor_shape(in: keybind.CursorShape) renderer.CursorShape { + return switch (in) { + .default => .default, + .block_blink => .block_blink, + .block => .block, + .underline_blink => .underline_blink, + .underline => .underline, + .beam_blink => .beam_blink, + .beam => .beam, + }; +}