feat: make mode/namespace loading more dynamic and add fallback handling
This commit is contained in:
parent
27613eab1f
commit
94fb5119ef
12 changed files with 152 additions and 130 deletions
|
@ -196,7 +196,7 @@
|
|||
["enter", "home_menu_activate"]
|
||||
]
|
||||
},
|
||||
"palette": {
|
||||
"overlay/palette": {
|
||||
"press": [
|
||||
["ctrl+j", "toggle_panel"],
|
||||
["ctrl+q", "quit"],
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
{
|
||||
"settings": {
|
||||
"fallback": "vim"
|
||||
},
|
||||
"normal": {
|
||||
"syntax": "vim",
|
||||
"on_match_failure": "ignore",
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
["l", "move_right_vim"],
|
||||
["h", "move_left"],
|
||||
["<Space>", "move_right_vim"],
|
||||
["i", "enter_mode", "vim/insert"],
|
||||
["v", "enter_mode", "vim/visual"],
|
||||
["i", "enter_mode", "insert"],
|
||||
["v", "enter_mode", "visual"],
|
||||
["/", "find"],
|
||||
["n", "goto_next_match"],
|
||||
["0", "move_begin"],
|
||||
|
@ -72,17 +72,6 @@
|
|||
["<C-F5>", "toggle_inspector_view"],
|
||||
["<C-F10>", "toggle_whitespace_mode"],
|
||||
|
||||
["<F2>", "toggle_input_mode"],
|
||||
["<F3>", "goto_next_match"],
|
||||
["<F15>", "goto_prev_match"],
|
||||
["<F5>", "toggle_inspector_view"],
|
||||
["<F6>", "dump_current_line_tree"],
|
||||
["<F7>", "dump_current_line"],
|
||||
["<F9>", "theme_prev"],
|
||||
["<F10>", "theme_next"],
|
||||
["<F11>", "toggle_panel"],
|
||||
["<F12>", "goto_definition"],
|
||||
["<F34>", "toggle_whitespace_mode"],
|
||||
["<CR>", "smart_insert_line"],
|
||||
["<Del>", "delete_forward"],
|
||||
["<BS>", "delete_backward"]
|
||||
|
@ -91,8 +80,8 @@
|
|||
"insert": {
|
||||
"syntax": "vim",
|
||||
"press": [
|
||||
["jk", "enter_mode", "vim/normal"],
|
||||
["<Esc>", "enter_mode", "vim/normal"],
|
||||
["jk", "enter_mode", "normal"],
|
||||
["<Esc>", "enter_mode", "normal"],
|
||||
["<Del>", "delete_forward"],
|
||||
["<BS>", "delete_backward"]
|
||||
]
|
||||
|
|
|
@ -17,33 +17,6 @@ const KeyEvent = input.KeyEvent;
|
|||
const parse_flow = @import("parse_flow.zig");
|
||||
const parse_vim = @import("parse_vim.zig");
|
||||
|
||||
pub const mode = struct {
|
||||
pub const input = struct {
|
||||
pub const flow = Handler("flow", "normal");
|
||||
pub const home = Handler("flow", "home");
|
||||
pub const vim = struct {
|
||||
pub const normal = Handler("vim", "normal");
|
||||
pub const insert = Handler("vim", "insert");
|
||||
pub const visual = Handler("vim", "visual");
|
||||
};
|
||||
pub const helix = struct {
|
||||
pub const normal = Handler("helix", "normal");
|
||||
pub const insert = Handler("helix", "insert");
|
||||
pub const visual = Handler("helix", "select");
|
||||
};
|
||||
};
|
||||
pub const overlay = struct {
|
||||
pub const palette = Handler("flow", "palette");
|
||||
};
|
||||
pub const mini = struct {
|
||||
pub const goto = Handler("flow", "mini/goto");
|
||||
pub const move_to_char = Handler("flow", "mini/move_to_char");
|
||||
pub const file_browser = Handler("flow", "mini/file_browser");
|
||||
pub const find_in_files = Handler("flow", "mini/find_in_files");
|
||||
pub const find = Handler("flow", "mini/find");
|
||||
};
|
||||
};
|
||||
|
||||
const builtin_keybinds = std.static_string_map.StaticStringMap([]const u8).initComptime(.{
|
||||
.{ "flow", @embedFile("builtin/flow.json") },
|
||||
.{ "vim", @embedFile("builtin/vim.json") },
|
||||
|
@ -51,17 +24,23 @@ const builtin_keybinds = std.static_string_map.StaticStringMap([]const u8).initC
|
|||
.{ "emacs", @embedFile("builtin/emacs.json") },
|
||||
});
|
||||
|
||||
fn Handler(namespace_name: []const u8, mode_name: []const u8) type {
|
||||
return struct {
|
||||
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 const default_mode = "normal";
|
||||
pub const default_namespace = "flow";
|
||||
|
||||
const Handler = struct {
|
||||
allocator: std.mem.Allocator,
|
||||
bindings: *const BindingSet,
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator, opts: anytype) !struct { EventHandler, *const KeybindHints } {
|
||||
fn create(mode_name: []const u8, allocator: std.mem.Allocator, opts: anytype) !struct { EventHandler, *const KeybindHints } {
|
||||
const self: *@This() = try allocator.create(@This());
|
||||
errdefer allocator.destroy(self);
|
||||
self.* = .{
|
||||
.allocator = allocator,
|
||||
.bindings = try get_namespace_mode(
|
||||
namespace_name,
|
||||
.bindings = try get_mode_binding_set(
|
||||
mode_name,
|
||||
if (@hasField(@TypeOf(opts), "insert_command"))
|
||||
opts.insert_command
|
||||
|
@ -77,8 +56,7 @@ fn Handler(namespace_name: []const u8, mode_name: []const u8) type {
|
|||
pub fn receive(self: *@This(), from: tp.pid_ref, m: tp.message) error{Exit}!bool {
|
||||
return self.bindings.receive(from, m);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const Mode = struct {
|
||||
input_handler: EventHandler,
|
||||
|
@ -97,16 +75,32 @@ pub const Mode = struct {
|
|||
|
||||
const NamespaceMap = std.StringHashMapUnmanaged(Namespace);
|
||||
|
||||
fn get_namespace_mode(namespace_name: []const u8, mode_name: []const u8, insert_command: []const u8) LoadError!*const BindingSet {
|
||||
pub fn get_namespace() []const u8 {
|
||||
return current_namespace().name;
|
||||
}
|
||||
|
||||
fn current_namespace() *const Namespace {
|
||||
return globals.current_namespace orelse @panic("no keybind namespace set");
|
||||
}
|
||||
|
||||
fn get_or_load_namespace(namespace_name: []const u8) LoadError!*const Namespace {
|
||||
const allocator = globals_allocator;
|
||||
const namespace = globals.namespaces.getPtr(namespace_name) orelse blk: {
|
||||
return globals.namespaces.getPtr(namespace_name) orelse blk: {
|
||||
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);
|
||||
result.value_ptr.* = namespace;
|
||||
break :blk result.value_ptr;
|
||||
};
|
||||
var binding_set = namespace.modes.getPtr(mode_name) orelse {
|
||||
}
|
||||
|
||||
pub fn set_namespace(namespace_name: []const u8) LoadError!void {
|
||||
globals.current_namespace = try get_or_load_namespace(namespace_name);
|
||||
}
|
||||
|
||||
fn get_mode_binding_set(mode_name: []const u8, insert_command: []const u8) LoadError!*const BindingSet {
|
||||
const namespace = current_namespace();
|
||||
var binding_set = namespace.get_mode(mode_name) orelse {
|
||||
const logger = log.logger("keybind");
|
||||
logger.print_err("get_namespace_mode", "ERROR: mode not found: {s}", .{mode_name});
|
||||
var iter = namespace.modes.iterator();
|
||||
|
@ -124,7 +118,6 @@ const LoadError = (error{ NotFound, NotAnObject } || std.json.ParseError(std.jso
|
|||
const Namespace = struct {
|
||||
name: []const u8,
|
||||
fallback: ?*const Namespace = null,
|
||||
default_mode: []const u8,
|
||||
modes: std.StringHashMapUnmanaged(BindingSet),
|
||||
|
||||
init_command: Command = .{},
|
||||
|
@ -144,7 +137,6 @@ const Namespace = struct {
|
|||
|
||||
var self: @This() = .{
|
||||
.name = try allocator.dupe(u8, namespace_name),
|
||||
.default_mode = "",
|
||||
.modes = .{},
|
||||
};
|
||||
errdefer allocator.free(self.name);
|
||||
|
@ -154,40 +146,61 @@ const Namespace = struct {
|
|||
try self.load_settings(allocator, mode_entry.value_ptr.*);
|
||||
}
|
||||
|
||||
if (!std.mem.eql(u8, self.name, default_namespace) and self.fallback == null)
|
||||
self.fallback = try get_or_load_namespace(default_namespace);
|
||||
|
||||
var modes = parsed.value.object.iterator();
|
||||
while (modes.next()) |mode_entry| {
|
||||
if (std.mem.eql(u8, mode_entry.key_ptr.*, "settings")) continue;
|
||||
try self.load_mode(allocator, mode_entry.key_ptr.*, mode_entry.value_ptr.*);
|
||||
}
|
||||
|
||||
if (self.fallback) |fallback| {
|
||||
var iter = fallback.modes.iterator();
|
||||
while (iter.next()) |entry|
|
||||
if (self.get_mode(entry.key_ptr.*) == null)
|
||||
try self.copy_mode(allocator, entry.key_ptr.*, entry.value_ptr);
|
||||
}
|
||||
|
||||
const logger = log.logger("keybind");
|
||||
logger.print("loaded namespace {s} fallback: {any} default: {s}", .{
|
||||
self.name,
|
||||
self.fallback,
|
||||
default_namespace,
|
||||
});
|
||||
var iter = self.modes.iterator();
|
||||
while (iter.next()) |entry| logger.print("available modes: {s}", .{entry.key_ptr.*});
|
||||
logger.deinit();
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
fn load_settings(self: *@This(), allocator: std.mem.Allocator, settings_value: std.json.Value) (parse_flow.ParseError || parse_vim.ParseError || std.json.ParseFromValueError)!void {
|
||||
fn load_settings(self: *@This(), allocator: std.mem.Allocator, settings_value: std.json.Value) LoadError!void {
|
||||
const JsonSettings = struct {
|
||||
init_command: []const std.json.Value = &[_]std.json.Value{},
|
||||
deinit_command: []const std.json.Value = &[_]std.json.Value{},
|
||||
fallback: []const u8 = "flow",
|
||||
fallback: ?[]const u8 = null,
|
||||
};
|
||||
const parsed = try std.json.parseFromValue(JsonSettings, allocator, settings_value, .{
|
||||
.ignore_unknown_fields = true,
|
||||
});
|
||||
defer parsed.deinit();
|
||||
// self.fallback = try allocator.dupe(u8, parsed.value.fallback);
|
||||
self.fallback = if (parsed.value.fallback) |fallback| try get_or_load_namespace(fallback) else null;
|
||||
try self.init_command.load(allocator, parsed.value.init_command);
|
||||
try self.deinit_command.load(allocator, parsed.value.deinit_command);
|
||||
}
|
||||
|
||||
fn load_mode(self: *@This(), allocator: std.mem.Allocator, mode_name: []const u8, mode_value: std.json.Value) !void {
|
||||
try self.modes.put(allocator, try allocator.dupe(u8, mode_name), try BindingSet.load(allocator, mode_value));
|
||||
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));
|
||||
}
|
||||
|
||||
fn get_mode(self: *@This(), mode_name: []const u8) error{}!*BindingSet {
|
||||
for (self.modes.items) |*mode_|
|
||||
if (std.mem.eql(u8, mode_.name, mode_name))
|
||||
return mode_;
|
||||
const mode_ = try self.modes.addOne();
|
||||
mode_.* = try BindingSet.init(self.modes.allocator, mode_name);
|
||||
return mode_;
|
||||
fn copy_mode(self: *@This(), allocator: std.mem.Allocator, mode_name: []const u8, fallback_mode: *const BindingSet) !void {
|
||||
try self.modes.put(allocator, mode_name, try BindingSet.copy(allocator, fallback_mode));
|
||||
}
|
||||
|
||||
fn get_mode(self: *const @This(), mode_name: []const u8) ?*BindingSet {
|
||||
return self.modes.getPtr(mode_name);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -278,6 +291,7 @@ const max_input_buffer_size = 4096;
|
|||
|
||||
var globals: struct {
|
||||
namespaces: NamespaceMap = .{},
|
||||
current_namespace: ?*const Namespace = null,
|
||||
input_buffer: std.ArrayListUnmanaged(u8) = .{},
|
||||
insert_command: []const u8 = "",
|
||||
insert_command_id: ?command.ID = null,
|
||||
|
@ -299,17 +313,9 @@ const BindingSet = struct {
|
|||
const KeySyntax = enum { flow, vim };
|
||||
const OnMatchFailure = enum { insert, ignore };
|
||||
|
||||
fn load(allocator: std.mem.Allocator, mode_bindings: std.json.Value) (error{OutOfMemory} || parse_flow.ParseError || parse_vim.ParseError || std.json.ParseFromValueError)!@This() {
|
||||
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() = .{};
|
||||
|
||||
defer self.press.append(allocator, .{
|
||||
.key_events = allocator.dupe(KeyEvent, &[_]KeyEvent{.{ .key = input.key.f2 }}) catch @panic("failed to add toggle_input_mode fallback"),
|
||||
.command = .{
|
||||
.command = allocator.dupe(u8, "toggle_input_mode") catch @panic("failed to add toggle_input_mode fallback"),
|
||||
.args = "",
|
||||
},
|
||||
}) catch {};
|
||||
|
||||
const JsonConfig = struct {
|
||||
press: []const []const std.json.Value = &[_][]std.json.Value{},
|
||||
release: []const []const std.json.Value = &[_][]std.json.Value{},
|
||||
|
@ -324,6 +330,10 @@ const BindingSet = struct {
|
|||
self.on_match_failure = parsed.value.on_match_failure;
|
||||
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_| {
|
||||
for (fallback_.press.items) |binding| try self.press.append(allocator, binding);
|
||||
for (fallback_.release.items) |binding| try self.release.append(allocator, binding);
|
||||
}
|
||||
self.build_hints(allocator) catch {};
|
||||
return self;
|
||||
}
|
||||
|
@ -401,6 +411,15 @@ const BindingSet = struct {
|
|||
}
|
||||
}
|
||||
|
||||
fn copy(allocator: std.mem.Allocator, fallback: *const BindingSet) error{OutOfMemory}!@This() {
|
||||
var self: @This() = .{};
|
||||
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);
|
||||
self.build_hints(allocator) catch {};
|
||||
return self;
|
||||
}
|
||||
|
||||
fn hints(self: *const @This()) *const KeybindHints {
|
||||
return &self.hints_map;
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ 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.create(allocator, .{
|
||||
const input_handler, const keybind_hints = try keybind.mode("mini/file_browser", allocator, .{
|
||||
.insert_command = "mini_mode_insert_bytes",
|
||||
});
|
||||
return .{
|
||||
|
|
|
@ -44,7 +44,7 @@ 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.create(allocator, .{
|
||||
const input_handler, const keybind_hints = try keybind.mode("mini/find", allocator, .{
|
||||
.insert_command = "mini_mode_insert_bytes",
|
||||
});
|
||||
return .{
|
||||
|
|
|
@ -38,7 +38,7 @@ 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.create(allocator, .{
|
||||
const input_handler, const keybind_hints = try keybind.mode("mini/find_in_files", allocator, .{
|
||||
.insert_command = "mini_mode_insert_bytes",
|
||||
});
|
||||
return .{
|
||||
|
|
|
@ -32,7 +32,7 @@ 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.create(allocator, .{
|
||||
const input_handler, const keybind_hints = try keybind.mode("mini/goto", allocator, .{
|
||||
.insert_command = "mini_mode_insert_bytes",
|
||||
});
|
||||
return .{
|
||||
|
|
|
@ -41,7 +41,7 @@ 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.create(allocator, .{
|
||||
const input_handler, const keybind_hints = try keybind.mode("mini/move_to_char", allocator, .{
|
||||
.insert_command = "mini_mode_insert_bytes",
|
||||
});
|
||||
return .{
|
||||
|
|
|
@ -59,7 +59,7 @@ 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.create(allocator, .{
|
||||
const input_handler, const keybind_hints = try keybind.mode("overlay/palette", allocator, .{
|
||||
.insert_command = "overlay_insert_bytes",
|
||||
});
|
||||
return .{
|
||||
|
|
|
@ -82,7 +82,7 @@ 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.create(allocator, .{
|
||||
const input_handler, const keybind_hints = try keybind.mode("overlay/palette", allocator, .{
|
||||
.insert_command = "overlay_insert_bytes",
|
||||
});
|
||||
return .{
|
||||
|
|
|
@ -152,8 +152,16 @@ fn init(allocator: Allocator) !*Self {
|
|||
fn init_delayed(self: *Self) !void {
|
||||
self.delayed_init_done = true;
|
||||
if (self.input_mode) |_| {} else {
|
||||
var mode_parts = std.mem.splitScalar(u8, self.config.input_mode, '/');
|
||||
const namespace_name = mode_parts.first();
|
||||
keybind.set_namespace(namespace_name) catch {
|
||||
self.logger.print_err("keybind", "unknown mode {s}", .{namespace_name});
|
||||
try keybind.set_namespace("flow");
|
||||
self.config.input_mode = "flow";
|
||||
try self.save_config();
|
||||
};
|
||||
return cmds.enter_mode(self, command.Context.fmt(.{
|
||||
self.delayed_init_input_mode orelse self.config.input_mode,
|
||||
self.delayed_init_input_mode orelse keybind.default_mode,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@ -575,8 +583,8 @@ fn enter_overlay_mode(self: *Self, mode: type) command.Result {
|
|||
self.refresh_hover();
|
||||
}
|
||||
|
||||
fn get_input_mode(self: *Self, mode: anytype, name: []const u8, opts: anytype) !Mode {
|
||||
const input_handler, const keybind_hints = try mode.create(self.allocator, opts);
|
||||
fn get_input_mode(self: *Self, mode_name: []const u8, name: []const u8, opts: anytype) !Mode {
|
||||
const input_handler, const keybind_hints = try keybind.mode(mode_name, self.allocator, opts);
|
||||
return .{
|
||||
.input_handler = input_handler,
|
||||
.keybind_hints = keybind_hints,
|
||||
|
@ -658,16 +666,18 @@ const cmds = struct {
|
|||
pub const toggle_whitespace_mode_meta = .{ .description = "Switch to next whitespace rendering mode" };
|
||||
|
||||
pub fn toggle_input_mode(self: *Self, _: Ctx) Result {
|
||||
var it = std.mem.splitScalar(u8, self.config.input_mode, '/');
|
||||
self.config.input_mode = it.first();
|
||||
self.config.input_mode = if (std.mem.eql(u8, self.config.input_mode, "flow"))
|
||||
"vim/normal"
|
||||
else if (std.mem.eql(u8, self.config.input_mode, "vim/normal"))
|
||||
"helix/normal"
|
||||
"vim"
|
||||
else if (std.mem.eql(u8, self.config.input_mode, "vim"))
|
||||
"helix"
|
||||
else
|
||||
"flow";
|
||||
try self.save_config();
|
||||
var it = std.mem.splitScalar(u8, self.config.input_mode, '/');
|
||||
self.logger.print("input mode {s}", .{it.first()});
|
||||
return enter_mode(self, Ctx.fmt(.{self.config.input_mode}));
|
||||
self.logger.print("input mode {s}", .{self.config.input_mode});
|
||||
try keybind.set_namespace(self.config.input_mode);
|
||||
return enter_mode(self, Ctx.fmt(.{keybind.default_mode}));
|
||||
}
|
||||
pub const toggle_input_mode_meta = .{ .description = "Switch to next input mode" };
|
||||
|
||||
|
@ -685,51 +695,52 @@ const cmds = struct {
|
|||
m.deinit();
|
||||
self.input_mode = null;
|
||||
}
|
||||
self.input_mode = if (std.mem.eql(u8, mode, "vim/normal"))
|
||||
try self.get_input_mode(keybind.mode.input.vim.normal, "NORMAL", .{
|
||||
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");
|
||||
self.input_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 (std.mem.eql(u8, mode, "vim/insert"))
|
||||
try self.get_input_mode(keybind.mode.input.vim.insert, "INSERT", .{
|
||||
else if (is_vim_mode and std.mem.eql(u8, mode, "insert"))
|
||||
try self.get_input_mode("insert", "INSERT", .{
|
||||
.enable_chording = self.config.vim_insert_chording_keybindings,
|
||||
.line_numbers_relative = self.config.vim_insert_gutter_line_numbers_relative,
|
||||
.cursor_shape = .beam,
|
||||
})
|
||||
else if (std.mem.eql(u8, mode, "vim/visual"))
|
||||
try self.get_input_mode(keybind.mode.input.vim.visual, "VISUAL", .{
|
||||
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 (std.mem.eql(u8, mode, "helix/normal"))
|
||||
try self.get_input_mode(keybind.mode.input.helix.normal, "NOR", .{
|
||||
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 (std.mem.eql(u8, mode, "helix/insert"))
|
||||
try self.get_input_mode(keybind.mode.input.helix.insert, "INS", .{
|
||||
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 (std.mem.eql(u8, mode, "helix/select"))
|
||||
try self.get_input_mode(keybind.mode.input.helix.visual, "SEL", .{
|
||||
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 if (std.mem.eql(u8, mode, "flow"))
|
||||
try self.get_input_mode(keybind.mode.input.flow, "flow", .{})
|
||||
else if (std.mem.eql(u8, mode, "home"))
|
||||
try self.get_input_mode(keybind.mode.input.home, "flow", .{})
|
||||
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.mode.input.flow, "flow", .{});
|
||||
break :ret try self.get_input_mode(keybind.default_mode, current_namespace, .{});
|
||||
};
|
||||
};
|
||||
// self.logger.print("input mode: {s}", .{(self.input_mode orelse return).description});
|
||||
}
|
||||
pub const enter_mode_meta = .{ .arguments = &.{.string} };
|
||||
|
||||
pub fn enter_mode_default(self: *Self, _: Ctx) Result {
|
||||
return enter_mode(self, Ctx.fmt(.{self.config.input_mode}));
|
||||
return enter_mode(self, Ctx.fmt(.{keybind.default_mode}));
|
||||
}
|
||||
pub const enter_mode_default_meta = .{};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue