feat: move all keybind mode related options to keybind config
This commit is contained in:
parent
cf1befe3fa
commit
3b8982ac26
12 changed files with 85 additions and 140 deletions
|
@ -5,9 +5,6 @@ theme: []const u8 = "default",
|
|||
input_mode: []const u8 = "flow",
|
||||
gutter_line_numbers: bool = true,
|
||||
gutter_line_numbers_relative: bool = false,
|
||||
vim_normal_gutter_line_numbers_relative: bool = true,
|
||||
vim_visual_gutter_line_numbers_relative: bool = true,
|
||||
vim_insert_gutter_line_numbers_relative: bool = false,
|
||||
enable_terminal_cursor: bool = true,
|
||||
enable_terminal_color_scheme: bool = builtin.os.tag != .windows,
|
||||
highlight_current_line: bool = true,
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
},
|
||||
"normal": {
|
||||
"on_match_failure": "ignore",
|
||||
"name": "NOR",
|
||||
"line_numbers": "relative",
|
||||
"cursor": "block",
|
||||
"press": [
|
||||
["ctrl+b", "move_scroll_page_up"],
|
||||
["ctrl+f", "move_scroll_page_down"],
|
||||
|
@ -232,6 +235,9 @@
|
|||
]
|
||||
},
|
||||
"insert": {
|
||||
"name": "INS",
|
||||
"line_numbers": "absolute",
|
||||
"cursor": "beam",
|
||||
"press": [
|
||||
["ctrl+u", "move_scroll_page_up"],
|
||||
["ctrl+d", "move_scroll_page_down"],
|
||||
|
@ -242,6 +248,9 @@
|
|||
]
|
||||
},
|
||||
"select": {
|
||||
"name": "SEL",
|
||||
"line_numbers": "relative",
|
||||
"cursor": "block",
|
||||
"press": [
|
||||
["ctrl+b", "move_scroll_page_up"],
|
||||
["ctrl+f", "move_scroll_page_down"],
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
"normal": {
|
||||
"syntax": "vim",
|
||||
"on_match_failure": "ignore",
|
||||
"name": "NORMAL",
|
||||
"line_numbers": "relative",
|
||||
"cursor": "block",
|
||||
"press": [
|
||||
["b", "move_word_left"],
|
||||
["w", "move_word_right_vim"],
|
||||
|
@ -63,8 +66,21 @@
|
|||
["<CR>", "smart_insert_line"]
|
||||
]
|
||||
},
|
||||
"visual": {
|
||||
"syntax": "vim",
|
||||
"on_match_failure": "ignore",
|
||||
"name": "VISUAL",
|
||||
"line_numbers": "relative",
|
||||
"cursor": "underline",
|
||||
"press": [
|
||||
["<Esc>", "enter_mode", "normal"],
|
||||
]
|
||||
},
|
||||
"insert": {
|
||||
"syntax": "vim",
|
||||
"name": "INSERT",
|
||||
"line_numbers": "absolute",
|
||||
"cursor": "beam",
|
||||
"press": [
|
||||
["jk", "enter_mode", "normal"],
|
||||
["<Esc>", "enter_mode", "normal"],
|
||||
|
|
|
@ -24,8 +24,11 @@ const builtin_keybinds = std.static_string_map.StaticStringMap([]const u8).initC
|
|||
.{ "emacs", @embedFile("builtin/emacs.json") },
|
||||
});
|
||||
|
||||
pub fn mode(mode_name: []const u8, allocator: std.mem.Allocator, opts: anytype) !struct { EventHandler, *const KeybindHints } {
|
||||
return Handler.create(mode_name, allocator, opts);
|
||||
pub fn mode(mode_name: []const u8, allocator: std.mem.Allocator, opts: anytype) !Mode {
|
||||
return Handler.create(mode_name, allocator, opts) catch |e| switch (e) {
|
||||
error.NotFound => return error.Stop,
|
||||
else => return e,
|
||||
};
|
||||
}
|
||||
|
||||
pub const default_mode = "normal";
|
||||
|
@ -35,7 +38,7 @@ const Handler = struct {
|
|||
allocator: std.mem.Allocator,
|
||||
bindings: *const BindingSet,
|
||||
|
||||
fn create(mode_name: []const u8, allocator: std.mem.Allocator, opts: anytype) !struct { EventHandler, *const KeybindHints } {
|
||||
fn create(mode_name: []const u8, allocator: std.mem.Allocator, opts: anytype) !Mode {
|
||||
const self: *@This() = try allocator.create(@This());
|
||||
errdefer allocator.destroy(self);
|
||||
self.* = .{
|
||||
|
@ -48,7 +51,13 @@ const Handler = struct {
|
|||
"insert_chars",
|
||||
),
|
||||
};
|
||||
return .{ EventHandler.to_owned(self), self.bindings.hints() };
|
||||
return .{
|
||||
.input_handler = EventHandler.to_owned(self),
|
||||
.keybind_hints = self.bindings.hints(),
|
||||
.name = self.bindings.name,
|
||||
.line_numbers = self.bindings.line_numbers,
|
||||
.cursor_shape = self.bindings.cursor_shape,
|
||||
};
|
||||
}
|
||||
pub fn deinit(self: *@This()) void {
|
||||
self.allocator.destroy(self);
|
||||
|
@ -63,7 +72,7 @@ pub const Mode = struct {
|
|||
event_handler: ?EventHandler = null,
|
||||
|
||||
name: []const u8 = "",
|
||||
line_numbers: enum { absolute, relative } = .absolute,
|
||||
line_numbers: LineNumbers = .absolute,
|
||||
keybind_hints: *const KeybindHints,
|
||||
cursor_shape: CursorShape = .block,
|
||||
|
||||
|
@ -110,9 +119,6 @@ fn current_namespace() *const Namespace {
|
|||
fn get_or_load_namespace(namespace_name: []const u8) LoadError!*const Namespace {
|
||||
const allocator = globals_allocator;
|
||||
return globals.namespaces.getPtr(namespace_name) orelse blk: {
|
||||
const logger = log.logger("keybind");
|
||||
logger.print("loading namespace '{s}'", .{namespace_name});
|
||||
defer logger.deinit();
|
||||
const namespace = try Namespace.load(allocator, namespace_name);
|
||||
const result = try globals.namespaces.getOrPut(allocator, try allocator.dupe(u8, namespace_name));
|
||||
std.debug.assert(result.found_existing == false);
|
||||
|
@ -222,7 +228,7 @@ const Namespace = struct {
|
|||
|
||||
fn load_mode(self: *@This(), allocator: std.mem.Allocator, mode_name: []const u8, mode_value: std.json.Value) !void {
|
||||
const fallback_mode = if (self.fallback) |fallback| fallback.get_mode(mode_name) orelse fallback.get_mode(default_mode) else null;
|
||||
try self.modes.put(allocator, try allocator.dupe(u8, mode_name), try BindingSet.load(allocator, mode_value, fallback_mode));
|
||||
try self.modes.put(allocator, try allocator.dupe(u8, mode_name), try BindingSet.load(allocator, self.name, mode_value, fallback_mode));
|
||||
}
|
||||
|
||||
fn copy_mode(self: *@This(), allocator: std.mem.Allocator, mode_name: []const u8, fallback_mode: *const BindingSet) !void {
|
||||
|
@ -349,20 +355,26 @@ const BindingSet = struct {
|
|||
release: std.ArrayListUnmanaged(Binding) = .{},
|
||||
syntax: KeySyntax = .flow,
|
||||
on_match_failure: OnMatchFailure = .ignore,
|
||||
name: []const u8,
|
||||
line_numbers: LineNumbers = .absolute,
|
||||
cursor_shape: CursorShape = .block,
|
||||
insert_command: []const u8 = "",
|
||||
hints_map: KeybindHints = .{},
|
||||
|
||||
const KeySyntax = enum { flow, vim };
|
||||
const OnMatchFailure = enum { insert, ignore };
|
||||
|
||||
fn load(allocator: std.mem.Allocator, mode_bindings: std.json.Value, fallback: ?*const BindingSet) (error{OutOfMemory} || parse_flow.ParseError || parse_vim.ParseError || std.json.ParseFromValueError)!@This() {
|
||||
var self: @This() = .{};
|
||||
fn load(allocator: std.mem.Allocator, namespace_name: []const u8, mode_bindings: std.json.Value, fallback: ?*const BindingSet) (error{OutOfMemory} || parse_flow.ParseError || parse_vim.ParseError || std.json.ParseFromValueError)!@This() {
|
||||
var self: @This() = .{ .name = undefined };
|
||||
|
||||
const JsonConfig = struct {
|
||||
press: []const []const std.json.Value = &[_][]std.json.Value{},
|
||||
release: []const []const std.json.Value = &[_][]std.json.Value{},
|
||||
syntax: KeySyntax = .flow,
|
||||
on_match_failure: OnMatchFailure = .insert,
|
||||
name: ?[]const u8 = null,
|
||||
line_numbers: LineNumbers = .absolute,
|
||||
cursor: CursorShape = .block,
|
||||
};
|
||||
const parsed = try std.json.parseFromValue(JsonConfig, allocator, mode_bindings, .{
|
||||
.ignore_unknown_fields = true,
|
||||
|
@ -370,6 +382,9 @@ const BindingSet = struct {
|
|||
defer parsed.deinit();
|
||||
self.syntax = parsed.value.syntax;
|
||||
self.on_match_failure = parsed.value.on_match_failure;
|
||||
self.name = try allocator.dupe(u8, parsed.value.name orelse namespace_name);
|
||||
self.line_numbers = parsed.value.line_numbers;
|
||||
self.cursor_shape = parsed.value.cursor;
|
||||
try self.load_event(allocator, &self.press, input.event.press, parsed.value.press);
|
||||
try self.load_event(allocator, &self.release, input.event.release, parsed.value.release);
|
||||
if (fallback) |fallback_| {
|
||||
|
@ -439,7 +454,7 @@ const BindingSet = struct {
|
|||
}
|
||||
|
||||
fn copy(allocator: std.mem.Allocator, fallback: *const BindingSet) error{OutOfMemory}!@This() {
|
||||
var self: @This() = .{};
|
||||
var self: @This() = .{ .name = fallback.name };
|
||||
self.on_match_failure = fallback.on_match_failure;
|
||||
for (fallback.press.items) |binding| try self.press.append(allocator, binding);
|
||||
for (fallback.release.items) |binding| try self.release.append(allocator, binding);
|
||||
|
@ -624,6 +639,11 @@ const BindingSet = struct {
|
|||
}
|
||||
};
|
||||
|
||||
pub const LineNumbers = enum {
|
||||
absolute,
|
||||
relative,
|
||||
};
|
||||
|
||||
pub const CursorShape = enum {
|
||||
default,
|
||||
block_blink,
|
||||
|
|
|
@ -48,19 +48,11 @@ pub fn Create(options: type) type {
|
|||
try options.load_entries(self);
|
||||
if (@hasDecl(options, "restore_state"))
|
||||
options.restore_state(self) catch {};
|
||||
const input_handler, const keybind_hints = try keybind.mode("mini/file_browser", allocator, .{
|
||||
var mode = try keybind.mode("mini/file_browser", allocator, .{
|
||||
.insert_command = "mini_mode_insert_bytes",
|
||||
});
|
||||
return .{
|
||||
.{
|
||||
.input_handler = input_handler,
|
||||
.event_handler = EventHandler.to_owned(self),
|
||||
.keybind_hints = keybind_hints,
|
||||
},
|
||||
.{
|
||||
.name = options.name(self),
|
||||
},
|
||||
};
|
||||
mode.event_handler = EventHandler.to_owned(self);
|
||||
return .{ mode, .{ .name = options.name(self) } };
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Self) void {
|
||||
|
|
|
@ -44,19 +44,11 @@ pub fn create(allocator: Allocator, _: command.Context) !struct { tui.Mode, tui.
|
|||
defer self.allocator.free(text);
|
||||
try self.input.appendSlice(text);
|
||||
}
|
||||
const input_handler, const keybind_hints = try keybind.mode("mini/find", allocator, .{
|
||||
var mode = try keybind.mode("mini/find", allocator, .{
|
||||
.insert_command = "mini_mode_insert_bytes",
|
||||
});
|
||||
return .{
|
||||
.{
|
||||
.input_handler = input_handler,
|
||||
.event_handler = EventHandler.to_owned(self),
|
||||
.keybind_hints = keybind_hints,
|
||||
},
|
||||
.{
|
||||
.name = name,
|
||||
},
|
||||
};
|
||||
mode.event_handler = EventHandler.to_owned(self);
|
||||
return .{ mode, .{ .name = name } };
|
||||
};
|
||||
return error.NotFound;
|
||||
}
|
||||
|
|
|
@ -38,19 +38,11 @@ pub fn create(allocator: Allocator, _: command.Context) !struct { tui.Mode, tui.
|
|||
@memcpy(self.buf[0..text.len], text);
|
||||
self.input = self.buf[0..text.len];
|
||||
};
|
||||
const input_handler, const keybind_hints = try keybind.mode("mini/find_in_files", allocator, .{
|
||||
var mode = try keybind.mode("mini/find_in_files", allocator, .{
|
||||
.insert_command = "mini_mode_insert_bytes",
|
||||
});
|
||||
return .{
|
||||
.{
|
||||
.input_handler = input_handler,
|
||||
.event_handler = EventHandler.to_owned(self),
|
||||
.keybind_hints = keybind_hints,
|
||||
},
|
||||
.{
|
||||
.name = name,
|
||||
},
|
||||
};
|
||||
mode.event_handler = EventHandler.to_owned(self);
|
||||
return .{ mode, .{ .name = name } };
|
||||
}
|
||||
return error.NotFound;
|
||||
}
|
||||
|
|
|
@ -32,19 +32,11 @@ pub fn create(allocator: Allocator, _: command.Context) !struct { tui.Mode, tui.
|
|||
.start = editor.get_primary().cursor.row + 1,
|
||||
};
|
||||
try self.commands.init(self);
|
||||
const input_handler, const keybind_hints = try keybind.mode("mini/goto", allocator, .{
|
||||
var mode = try keybind.mode("mini/goto", allocator, .{
|
||||
.insert_command = "mini_mode_insert_bytes",
|
||||
});
|
||||
return .{
|
||||
.{
|
||||
.input_handler = input_handler,
|
||||
.event_handler = EventHandler.to_owned(self),
|
||||
.keybind_hints = keybind_hints,
|
||||
},
|
||||
.{
|
||||
.name = name,
|
||||
},
|
||||
};
|
||||
mode.event_handler = EventHandler.to_owned(self);
|
||||
return .{ mode, .{ .name = name } };
|
||||
};
|
||||
return error.NotFound;
|
||||
}
|
||||
|
|
|
@ -41,19 +41,11 @@ pub fn create(allocator: Allocator, ctx: command.Context) !struct { tui.Mode, tu
|
|||
.operation = if (select) .select else .move,
|
||||
};
|
||||
try self.commands.init(self);
|
||||
const input_handler, const keybind_hints = try keybind.mode("mini/move_to_char", allocator, .{
|
||||
var mode = try keybind.mode("mini/move_to_char", allocator, .{
|
||||
.insert_command = "mini_mode_insert_bytes",
|
||||
});
|
||||
return .{
|
||||
.{
|
||||
.input_handler = input_handler,
|
||||
.event_handler = EventHandler.to_owned(self),
|
||||
.keybind_hints = keybind_hints,
|
||||
},
|
||||
.{
|
||||
.name = self.name(),
|
||||
},
|
||||
};
|
||||
mode.event_handler = EventHandler.to_owned(self);
|
||||
return .{ mode, .{ .name = self.name() } };
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Self) void {
|
||||
|
|
|
@ -59,15 +59,12 @@ pub fn create(allocator: std.mem.Allocator) !tui.Mode {
|
|||
self.menu.resize(.{ .y = 0, .x = self.menu_pos_x(), .w = max_menu_width() + 2 });
|
||||
try mv.floating_views.add(self.modal.widget());
|
||||
try mv.floating_views.add(self.menu.container_widget);
|
||||
const input_handler, const keybind_hints = try keybind.mode("overlay/palette", allocator, .{
|
||||
var mode = try keybind.mode("overlay/palette", allocator, .{
|
||||
.insert_command = "overlay_insert_bytes",
|
||||
});
|
||||
return .{
|
||||
.input_handler = input_handler,
|
||||
.event_handler = EventHandler.to_owned(self),
|
||||
.keybind_hints = keybind_hints,
|
||||
.name = " open recent",
|
||||
};
|
||||
mode.event_handler = EventHandler.to_owned(self);
|
||||
mode.name = " open recent";
|
||||
return mode;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Self) void {
|
||||
|
|
|
@ -82,15 +82,12 @@ pub fn Create(options: type) type {
|
|||
try self.start_query();
|
||||
try mv.floating_views.add(self.modal.widget());
|
||||
try mv.floating_views.add(self.menu.container_widget);
|
||||
const input_handler, const keybind_hints = try keybind.mode("overlay/palette", allocator, .{
|
||||
var mode = try keybind.mode("overlay/palette", allocator, .{
|
||||
.insert_command = "overlay_insert_bytes",
|
||||
});
|
||||
return .{
|
||||
.input_handler = input_handler,
|
||||
.event_handler = EventHandler.to_owned(self),
|
||||
.keybind_hints = keybind_hints,
|
||||
.name = options.name,
|
||||
};
|
||||
mode.event_handler = EventHandler.to_owned(self);
|
||||
mode.name = options.name;
|
||||
return mode;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Self) void {
|
||||
|
|
|
@ -583,24 +583,8 @@ fn enter_overlay_mode(self: *Self, mode: type) command.Result {
|
|||
self.refresh_hover();
|
||||
}
|
||||
|
||||
fn get_input_mode(self: *Self, mode_name: []const u8, name: []const u8, opts: anytype) !Mode {
|
||||
const input_handler, const keybind_hints = keybind.mode(mode_name, self.allocator, opts) catch |e| switch (e) {
|
||||
error.NotFound => return error.Stop,
|
||||
else => return e,
|
||||
};
|
||||
return .{
|
||||
.input_handler = input_handler,
|
||||
.keybind_hints = keybind_hints,
|
||||
.name = name,
|
||||
.line_numbers = if (@hasField(@TypeOf(opts), "line_numbers_relative"))
|
||||
if (opts.line_numbers_relative)
|
||||
.relative
|
||||
else
|
||||
.absolute
|
||||
else
|
||||
.absolute,
|
||||
.cursor_shape = if (@hasField(@TypeOf(opts), "cursor_shape")) opts.cursor_shape else .block,
|
||||
};
|
||||
fn get_input_mode(self: *Self, mode_name: []const u8) !Mode {
|
||||
return keybind.mode(mode_name, self.allocator, .{});
|
||||
}
|
||||
|
||||
const cmds = struct {
|
||||
|
@ -700,44 +684,9 @@ const cmds = struct {
|
|||
return;
|
||||
}
|
||||
|
||||
const current_namespace = keybind.get_namespace();
|
||||
const is_vim_mode = std.mem.eql(u8, current_namespace, "vim");
|
||||
const is_helix_mode = std.mem.eql(u8, current_namespace, "helix");
|
||||
var new_mode = if (is_vim_mode and std.mem.eql(u8, mode, "normal"))
|
||||
try self.get_input_mode("normal", "NORMAL", .{
|
||||
.line_numbers_relative = self.config.vim_normal_gutter_line_numbers_relative,
|
||||
.cursor_shape = .block,
|
||||
})
|
||||
else if (is_vim_mode and std.mem.eql(u8, mode, "insert"))
|
||||
try self.get_input_mode("insert", "INSERT", .{
|
||||
.line_numbers_relative = self.config.vim_insert_gutter_line_numbers_relative,
|
||||
.cursor_shape = .beam,
|
||||
})
|
||||
else if (is_vim_mode and std.mem.eql(u8, mode, "visual"))
|
||||
try self.get_input_mode("visual", "VISUAL", .{
|
||||
.line_numbers_relative = self.config.vim_visual_gutter_line_numbers_relative,
|
||||
.cursor_shape = .underline,
|
||||
})
|
||||
else if (is_helix_mode and std.mem.eql(u8, mode, "normal"))
|
||||
try self.get_input_mode("normal", "NOR", .{
|
||||
.line_numbers_relative = self.config.vim_normal_gutter_line_numbers_relative,
|
||||
.cursor_shape = .block,
|
||||
})
|
||||
else if (is_helix_mode and std.mem.eql(u8, mode, "insert"))
|
||||
try self.get_input_mode("insert", "INS", .{
|
||||
.line_numbers_relative = self.config.vim_insert_gutter_line_numbers_relative,
|
||||
.cursor_shape = .beam,
|
||||
})
|
||||
else if (is_helix_mode and std.mem.eql(u8, mode, "select"))
|
||||
try self.get_input_mode("visual", "SEL", .{
|
||||
.line_numbers_relative = self.config.vim_visual_gutter_line_numbers_relative,
|
||||
.cursor_shape = .block,
|
||||
})
|
||||
else ret: {
|
||||
break :ret self.get_input_mode(mode, current_namespace, .{}) catch {
|
||||
self.logger.print("unknown mode {s}", .{mode});
|
||||
break :ret try self.get_input_mode(keybind.default_mode, current_namespace, .{});
|
||||
};
|
||||
var new_mode = self.get_input_mode(mode) catch ret: {
|
||||
self.logger.print("unknown mode {s}", .{mode});
|
||||
break :ret try self.get_input_mode(keybind.default_mode);
|
||||
};
|
||||
errdefer new_mode.deinit();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue