refactor: move input types to new module and use directly use libvaxis types

This commit is contained in:
CJ van den Berg 2024-11-15 21:01:50 +01:00
parent e08c2aa3ba
commit 18f321bf41
Signed by: neurocyte
GPG key ID: 8EB1E1BB660E3FB9
36 changed files with 1224 additions and 1363 deletions

View file

@ -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);
}

View file

@ -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' } } },
.{ "<Space>", &.{KeyEvent{ .key = key.SPACE }} },
.{ "<C-x><C-c>", &.{ KeyEvent{ .key = 'x', .modifiers = mod.CTRL }, KeyEvent{ .key = 'c', .modifiers = mod.CTRL } } },
.{ "<A-x><Tab>", &.{ KeyEvent{ .key = 'x', .modifiers = mod.ALT }, KeyEvent{ .key = key.TAB } } },
.{ "<S-A-x><D-Del>", &.{ KeyEvent{ .key = 'x', .modifiers = mod.ALT | mod.SHIFT }, KeyEvent{ .key = key.DEL, .modifiers = mod.SUPER } } },
.{ "<Space>", &.{KeyEvent{ .key = input.key.space }} },
.{ "<C-x><C-c>", &.{ KeyEvent{ .key = 'x', .modifiers = input.mod.ctrl }, KeyEvent{ .key = 'c', .modifiers = input.mod.ctrl } } },
.{ "<A-x><Tab>", &.{ KeyEvent{ .key = 'x', .modifiers = input.mod.alt }, KeyEvent{ .key = input.key.tab } } },
.{ "<S-A-x><D-Del>", &.{ 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 });
}

View file

@ -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]);
}

View file

@ -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]);
}

View file

@ -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]);
}

View file

@ -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]);
}

View file

@ -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 => {},
},

View file

@ -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]);
}

View file

@ -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]);
}

View file

@ -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]);
}

View file

@ -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");

View file

@ -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 {},
},

View file

@ -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 {},
},

View file

@ -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 => {},
};
}

View file

@ -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 => {},
};
}

View file

@ -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", .{}),

View file

@ -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 => {},
};
}