refactor: move more mode specific commands to helix & vim

This commit is contained in:
CJ van den Berg 2025-11-27 18:03:53 +01:00
parent 8d8f4b82cb
commit 66f8819a19
Signed by: neurocyte
GPG key ID: 8EB1E1BB660E3FB9
4 changed files with 274 additions and 262 deletions

View file

@ -2,11 +2,19 @@ const std = @import("std");
const command = @import("command");
const cmd = command.executeName;
const tui = @import("../tui.zig");
const Editor = @import("../editor.zig").Editor;
const Buffer = @import("Buffer");
const Cursor = Buffer.Cursor;
const View = Buffer.View;
var commands: Commands = undefined;
const Self = Editor;
pub fn init() !void {
var v: void = {};
try commands.init(&v);
const mv = tui.mainview() orelse return;
const ed = mv.get_active_editor() orelse return;
try commands.init(ed);
}
pub fn deinit() void {
@ -14,74 +22,75 @@ pub fn deinit() void {
}
const Commands = command.Collection(cmds_);
const cmds_ = struct {
pub const Target = void;
const Ctx = command.Context;
const Meta = command.Metadata;
const Result = command.Result;
const Context = command.Context;
const Meta = command.Metadata;
const Result = command.Result;
pub fn w(_: *void, _: Ctx) Result {
const cmds_ = struct {
pub const Target = Self;
pub fn w(_: *Self, _: Context) Result {
try cmd("save_file", .{});
}
pub const w_meta: Meta = .{ .description = "w (write file)" };
pub fn q(_: *void, _: Ctx) Result {
pub fn q(_: *Self, _: Context) Result {
try cmd("quit", .{});
}
pub const q_meta: Meta = .{ .description = "q (quit)" };
pub fn @"q!"(_: *void, _: Ctx) Result {
pub fn @"q!"(_: *Self, _: Context) Result {
try cmd("quit_without_saving", .{});
}
pub const @"q!_meta": Meta = .{ .description = "q! (quit without saving)" };
pub fn @"qa!"(_: *void, _: Ctx) Result {
pub fn @"qa!"(_: *Self, _: Context) Result {
try cmd("quit_without_saving", .{});
}
pub const @"qa!_meta": Meta = .{ .description = "qa! (quit without saving anything)" };
pub fn wq(_: *void, _: Ctx) Result {
pub fn wq(_: *Self, _: Context) Result {
try cmd("save_file", command.fmt(.{ "then", .{ "quit", .{} } }));
}
pub const wq_meta: Meta = .{ .description = "wq (write file and quit)" };
pub fn @"wq!"(_: *void, _: Ctx) Result {
pub fn @"wq!"(_: *Self, _: Context) Result {
cmd("save_file", .{}) catch {};
try cmd("quit_without_saving", .{});
}
pub const @"wq!_meta": Meta = .{ .description = "wq! (write file and quit without saving)" };
pub fn @"e!"(_: *void, _: Ctx) Result {
pub fn @"e!"(_: *Self, _: Context) Result {
try cmd("reload_file", .{});
}
pub const @"e!_meta": Meta = .{ .description = "e! (force reload current file)" };
pub fn bd(_: *void, _: Ctx) Result {
pub fn bd(_: *Self, _: Context) Result {
try cmd("close_file", .{});
}
pub const bd_meta: Meta = .{ .description = "bd (Close file)" };
pub fn bw(_: *void, _: Ctx) Result {
pub fn bw(_: *Self, _: Context) Result {
try cmd("delete_buffer", .{});
}
pub const bw_meta: Meta = .{ .description = "bw (Delete buffer)" };
pub fn bnext(_: *void, _: Ctx) Result {
pub fn bnext(_: *Self, _: Context) Result {
try cmd("next_tab", .{});
}
pub const bnext_meta: Meta = .{ .description = "bnext (Next buffer/tab)" };
pub fn bprevious(_: *void, _: Ctx) Result {
pub fn bprevious(_: *Self, _: Context) Result {
try cmd("next_tab", .{});
}
pub const bprevious_meta: Meta = .{ .description = "bprevious (Previous buffer/tab)" };
pub fn ls(_: *void, _: Ctx) Result {
pub fn ls(_: *Self, _: Context) Result {
try cmd("switch_buffers", .{});
}
pub const ls_meta: Meta = .{ .description = "ls (List/switch buffers)" };
pub fn move_begin_or_add_integer_argument_zero(_: *void, _: Ctx) Result {
pub fn move_begin_or_add_integer_argument_zero(_: *Self, _: Context) Result {
return if (@import("keybind").current_integer_argument()) |_|
command.executeName("add_integer_argument_digit", command.fmt(.{0}))
else
@ -89,7 +98,7 @@ const cmds_ = struct {
}
pub const move_begin_or_add_integer_argument_zero_meta: Meta = .{ .description = "Move cursor to beginning of line (vim)" };
pub fn enter_mode_at_next_char(self: *void, ctx: Ctx) Result {
pub fn enter_mode_at_next_char(self: *Self, ctx: Context) Result {
_ = self; // autofix
_ = ctx; // autofix
//TODO
@ -98,7 +107,7 @@ const cmds_ = struct {
pub const enter_mode_at_next_char_meta: Meta = .{ .description = "Move forward one char and change mode" };
pub fn enter_mode_on_newline_down(self: *void, ctx: Ctx) Result {
pub fn enter_mode_on_newline_down(self: *Self, ctx: Context) Result {
_ = self; // autofix
_ = ctx; // autofix
//TODO
@ -107,7 +116,7 @@ const cmds_ = struct {
pub const enter_mode_on_newline_down_meta: Meta = .{ .description = "Insert a newline and change mode" };
pub fn enter_mode_on_newline_up(self: *void, ctx: Ctx) Result {
pub fn enter_mode_on_newline_up(self: *Self, ctx: Context) Result {
_ = self; // autofix
_ = ctx; // autofix
//TODO
@ -115,7 +124,7 @@ const cmds_ = struct {
}
pub const enter_mode_on_newline_up_meta: Meta = .{ .description = "Insert a newline above the current line and change mode" };
pub fn enter_mode_at_line_begin(self: *void, ctx: Ctx) Result {
pub fn enter_mode_at_line_begin(self: *Self, ctx: Context) Result {
_ = self; // autofix
_ = ctx; // autofix
//TODO
@ -124,7 +133,7 @@ const cmds_ = struct {
pub const enter_mode_at_line_begin_meta: Meta = .{ .description = "Goto line begin and change mode" };
pub fn enter_mode_at_line_end(self: *void, ctx: Ctx) Result {
pub fn enter_mode_at_line_end(self: *Self, ctx: Context) Result {
_ = self; // autofix
_ = ctx; // autofix
//TODO
@ -132,7 +141,7 @@ const cmds_ = struct {
}
pub const enter_mode_at_line_end_meta: Meta = .{ .description = "Goto line end and change mode" };
pub fn copy_line(self: *void, ctx: Ctx) Result {
pub fn copy_line(self: *Self, ctx: Context) Result {
_ = self; // autofix
_ = ctx; // autofix
//TODO
@ -140,4 +149,112 @@ const cmds_ = struct {
}
pub const copy_line_meta: Meta = .{ .description = "Copies the current line" };
pub fn move_scroll_half_page_up(self: *Self, _: Context) Result {
if (self.screen_cursor(&self.get_primary().cursor)) |cursor| {
const root = try self.buf_root();
self.with_cursors_and_view_const(root, move_cursor_half_page_up, &self.view) catch {};
const new_cursor_row = self.get_primary().cursor.row;
self.update_scroll_dest_abs(if (cursor.row > new_cursor_row) 0 else new_cursor_row - cursor.row);
} else {
return self.move_half_page_up(.{});
}
}
pub const move_scroll_half_page_up_meta: Meta = .{ .description = "Move and scroll half a page up" };
pub fn move_scroll_half_page_down(self: *Self, _: Context) Result {
if (self.screen_cursor(&self.get_primary().cursor)) |cursor| {
const root = try self.buf_root();
self.with_cursors_and_view_const(root, move_cursor_half_page_down, &self.view) catch {};
const new_cursor_row = self.get_primary().cursor.row;
self.update_scroll_dest_abs(if (cursor.row > new_cursor_row) 0 else new_cursor_row - cursor.row);
} else {
return self.move_half_page_down(.{});
}
}
pub const move_scroll_half_page_down_meta: Meta = .{ .description = "Move and scroll half a page down" };
pub fn move_left_vim(self: *Self, ctx: Context) Result {
const root = try self.buf_root();
self.with_cursors_const_repeat(root, move_cursor_left_vim, ctx) catch {};
self.clamp();
}
pub const move_left_vim_meta: Meta = .{ .description = "Move cursor left (vim)", .arguments = &.{.integer} };
pub fn move_right_vim(self: *Self, ctx: Context) Result {
const root = try self.buf_root();
self.with_cursors_const_repeat(root, move_cursor_right_vim, ctx) catch {};
self.clamp();
}
pub const move_right_vim_meta: Meta = .{ .description = "Move cursor right (vim)", .arguments = &.{.integer} };
pub fn cut_to_end_vim(self: *Self, _: Context) Result {
const b = try self.buf_for_update();
const root = try self.cut_to(move_cursor_end_vim, b.root);
try self.update_buf(root);
self.clamp();
}
pub const cut_to_end_vim_meta: Meta = .{ .description = "Cut to end of line (vim)" };
pub fn move_up_vim(self: *Self, ctx: Context) Result {
const root = try self.buf_root();
self.with_cursors_const_repeat(root, move_cursor_up_vim, ctx) catch {};
self.clamp();
}
pub const move_up_vim_meta: Meta = .{ .description = "Move cursor up (vim)", .arguments = &.{.integer} };
pub fn move_down_vim(self: *Self, ctx: Context) Result {
const root = try self.buf_root();
self.with_cursors_const_repeat(root, move_cursor_down_vim, ctx) catch {};
self.clamp();
}
pub const move_down_vim_meta: Meta = .{ .description = "Move cursor down (vim)", .arguments = &.{.integer} };
};
fn is_eol_right_vim(root: Buffer.Root, cursor: *const Cursor, metrics: Buffer.Metrics) bool {
const line_width = root.line_width(cursor.row, metrics) catch return true;
if (line_width == 0) return true;
if (cursor.col >= line_width - 1)
return true;
return false;
}
fn is_eol_vim(root: Buffer.Root, cursor: *const Cursor, metrics: Buffer.Metrics) bool {
const line_width = root.line_width(cursor.row, metrics) catch return true;
if (line_width == 0) return true;
if (cursor.col >= line_width)
return true;
return false;
}
fn move_cursor_half_page_up(root: Buffer.Root, cursor: *Cursor, view: *const View, metrics: Buffer.Metrics) !void {
cursor.move_half_page_up(root, view, metrics);
if (is_eol_vim(root, cursor, metrics)) try move_cursor_left_vim(root, cursor, metrics);
}
fn move_cursor_half_page_down(root: Buffer.Root, cursor: *Cursor, view: *const View, metrics: Buffer.Metrics) !void {
cursor.move_half_page_down(root, view, metrics);
if (is_eol_vim(root, cursor, metrics)) try move_cursor_left_vim(root, cursor, metrics);
}
fn move_cursor_up_vim(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) !void {
try cursor.move_up(root, metrics);
if (is_eol_vim(root, cursor, metrics)) try move_cursor_left_vim(root, cursor, metrics);
}
fn move_cursor_down_vim(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) !void {
try cursor.move_down(root, metrics);
if (is_eol_vim(root, cursor, metrics)) try move_cursor_left_vim(root, cursor, metrics);
}
fn move_cursor_end_vim(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) !void {
Editor.move_cursor_right_until(root, cursor, is_eol_vim, metrics);
}
fn move_cursor_left_vim(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void {
Editor.move_cursor_left_unless(root, cursor, Editor.is_eol_left, metrics);
}
fn move_cursor_right_vim(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void {
Editor.move_cursor_right_unless(root, cursor, is_eol_right_vim, metrics);
}