feat: add switch_input_mode command to change keybind mode in a mini mode
This commit is contained in:
parent
ad583879da
commit
9984d5e2b5
2 changed files with 54 additions and 7 deletions
|
|
@ -68,15 +68,13 @@ const Handler = struct {
|
||||||
fn create(mode_name: []const u8, allocator: std.mem.Allocator, opts: anytype) !Mode {
|
fn create(mode_name: []const u8, allocator: std.mem.Allocator, opts: anytype) !Mode {
|
||||||
const self = try allocator.create(@This());
|
const self = try allocator.create(@This());
|
||||||
errdefer allocator.destroy(self);
|
errdefer allocator.destroy(self);
|
||||||
self.* = .{
|
const insert_command = if (@hasField(@TypeOf(opts), "insert_command"))
|
||||||
.allocator = allocator,
|
|
||||||
.bindings = try get_mode_binding_set(
|
|
||||||
mode_name,
|
|
||||||
if (@hasField(@TypeOf(opts), "insert_command"))
|
|
||||||
opts.insert_command
|
opts.insert_command
|
||||||
else
|
else
|
||||||
"insert_chars",
|
"insert_chars";
|
||||||
),
|
self.* = .{
|
||||||
|
.allocator = allocator,
|
||||||
|
.bindings = try get_mode_binding_set(mode_name, insert_command),
|
||||||
};
|
};
|
||||||
return .{
|
return .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
|
|
@ -89,8 +87,33 @@ const Handler = struct {
|
||||||
.selection_style = self.bindings.selection_style,
|
.selection_style = self.bindings.selection_style,
|
||||||
.init_command = self.bindings.init_command,
|
.init_command = self.bindings.init_command,
|
||||||
.deinit_command = self.bindings.deinit_command,
|
.deinit_command = self.bindings.deinit_command,
|
||||||
|
.insert_command = try allocator.dupe(u8, insert_command),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
fn replace(mode_: *Mode, mode_name: []const u8, allocator: std.mem.Allocator) !void {
|
||||||
|
const self = try allocator.create(@This());
|
||||||
|
errdefer allocator.destroy(self);
|
||||||
|
self.* = .{
|
||||||
|
.allocator = allocator,
|
||||||
|
.bindings = try get_mode_binding_set(mode_name, mode_.insert_command),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (mode_.deinit_command) |deinit_command| deinit_command.execute_const();
|
||||||
|
if (mode_.input_handler) |ih| ih.deinit();
|
||||||
|
mode_.allocator.free(mode_.mode);
|
||||||
|
mode_.mode = try allocator.dupe(u8, mode_name);
|
||||||
|
mode_.allocator = allocator;
|
||||||
|
|
||||||
|
mode_.input_handler = EventHandler.to_owned(self);
|
||||||
|
mode_.keybind_hints = self.bindings.hints();
|
||||||
|
mode_.name = self.bindings.name;
|
||||||
|
mode_.line_numbers = self.bindings.line_numbers;
|
||||||
|
mode_.cursor_shape = self.bindings.cursor_shape;
|
||||||
|
mode_.selection_style = self.bindings.selection_style;
|
||||||
|
mode_.init_command = self.bindings.init_command;
|
||||||
|
mode_.deinit_command = self.bindings.deinit_command;
|
||||||
|
if (mode_.init_command) |init_command| init_command.execute_const();
|
||||||
|
}
|
||||||
pub fn deinit(self: *@This()) void {
|
pub fn deinit(self: *@This()) void {
|
||||||
self.allocator.destroy(self);
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
@ -113,6 +136,7 @@ pub const Mode = struct {
|
||||||
init_command: ?Command = null,
|
init_command: ?Command = null,
|
||||||
deinit_command: ?Command = null,
|
deinit_command: ?Command = null,
|
||||||
initialized: bool = false,
|
initialized: bool = false,
|
||||||
|
insert_command: []const u8,
|
||||||
|
|
||||||
pub fn run_init(self: *Mode) void {
|
pub fn run_init(self: *Mode) void {
|
||||||
if (self.initialized) return;
|
if (self.initialized) return;
|
||||||
|
|
@ -121,10 +145,18 @@ pub const Mode = struct {
|
||||||
if (self.init_command) |init_command| init_command.execute_const();
|
if (self.init_command) |init_command| init_command.execute_const();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn replace(self: *Mode, mode_name: []const u8, allocator: std.mem.Allocator) !void {
|
||||||
|
Handler.replace(self, mode_name, allocator) catch |e| switch (e) {
|
||||||
|
error.NotFound => return error.Stop,
|
||||||
|
else => return e,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Mode) void {
|
pub fn deinit(self: *Mode) void {
|
||||||
if (self.deinit_command) |deinit_command| deinit_command.execute_const();
|
if (self.deinit_command) |deinit_command| deinit_command.execute_const();
|
||||||
if (self.event_handler) |eh| eh.deinit();
|
if (self.event_handler) |eh| eh.deinit();
|
||||||
if (self.input_handler) |ih| ih.deinit();
|
if (self.input_handler) |ih| ih.deinit();
|
||||||
|
self.allocator.free(self.insert_command);
|
||||||
self.allocator.free(self.mode);
|
self.allocator.free(self.mode);
|
||||||
|
|
||||||
self.deinit_command = null;
|
self.deinit_command = null;
|
||||||
|
|
|
||||||
|
|
@ -835,6 +835,10 @@ fn enter_input_mode(self: *Self, new_mode: Mode) command.Result {
|
||||||
if (self.input_mode_) |*m| m.run_init();
|
if (self.input_mode_) |*m| m.run_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn switch_input_mode(self: *Self, mode_name: []const u8) !void {
|
||||||
|
if (self.input_mode_) |*m| try m.replace(mode_name, self.allocator);
|
||||||
|
}
|
||||||
|
|
||||||
fn refresh_input_mode(self: *Self) command.Result {
|
fn refresh_input_mode(self: *Self) command.Result {
|
||||||
const mode = (self.input_mode_ orelse return).mode;
|
const mode = (self.input_mode_ orelse return).mode;
|
||||||
var new_mode = self.get_input_mode(mode) catch ret: {
|
var new_mode = self.get_input_mode(mode) catch ret: {
|
||||||
|
|
@ -1090,6 +1094,17 @@ const cmds = struct {
|
||||||
}
|
}
|
||||||
pub const enter_mode_meta: Meta = .{ .arguments = &.{.string} };
|
pub const enter_mode_meta: Meta = .{ .arguments = &.{.string} };
|
||||||
|
|
||||||
|
pub fn switch_mode(self: *Self, ctx: Ctx) Result {
|
||||||
|
if (!self.delayed_init_done) return;
|
||||||
|
|
||||||
|
var mode: []const u8 = undefined;
|
||||||
|
if (!try ctx.args.match(.{tp.extract(&mode)}))
|
||||||
|
return tp.exit_error(error.InvalidSwitchModeArgument, null);
|
||||||
|
|
||||||
|
return self.switch_input_mode(mode);
|
||||||
|
}
|
||||||
|
pub const switch_mode_meta: Meta = .{ .arguments = &.{.string} };
|
||||||
|
|
||||||
pub fn enter_mode_default(self: *Self, _: Ctx) Result {
|
pub fn enter_mode_default(self: *Self, _: Ctx) Result {
|
||||||
return enter_mode(self, Ctx.fmt(.{keybind.default_mode}));
|
return enter_mode(self, Ctx.fmt(.{keybind.default_mode}));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue