feat: [hx] mm match brackets support
This commit is contained in:
parent
5a2ef01645
commit
f6d1f27337
3 changed files with 47 additions and 3 deletions
|
|
@ -463,7 +463,7 @@
|
||||||
|
|
||||||
["x", "extend_line_below"],
|
["x", "extend_line_below"],
|
||||||
|
|
||||||
["m m", "match_brackets"],
|
["m m", "match_brackets", "helix_sel_mode"],
|
||||||
["m s", "surround_add"],
|
["m s", "surround_add"],
|
||||||
["m r", "surround_replace"],
|
["m r", "surround_replace"],
|
||||||
["m d", "surround_delete"],
|
["m d", "surround_delete"],
|
||||||
|
|
|
||||||
|
|
@ -3498,7 +3498,7 @@ pub const Editor = struct {
|
||||||
}
|
}
|
||||||
pub const move_or_select_to_char_left_meta: Meta = .{ .arguments = &.{.integer} };
|
pub const move_or_select_to_char_left_meta: Meta = .{ .arguments = &.{.integer} };
|
||||||
|
|
||||||
fn match_bracket(root: Buffer.Root, original_cursor: Cursor, metrics: Buffer.Metrics) error{Stop}!struct { usize, usize } {
|
pub fn match_bracket(root: Buffer.Root, original_cursor: Cursor, metrics: Buffer.Metrics) error{Stop}!struct { usize, usize } {
|
||||||
// Find match bracket fallback when tree-sitter is not available
|
// Find match bracket fallback when tree-sitter is not available
|
||||||
// Operates exclusively when opening and closing brackets are distinct, when no match is found returns error.Stop
|
// Operates exclusively when opening and closing brackets are distinct, when no match is found returns error.Stop
|
||||||
// on success row, col.
|
// on success row, col.
|
||||||
|
|
@ -3561,7 +3561,6 @@ pub const Editor = struct {
|
||||||
try self.with_cursels_const(root, &move_to_match_bracket, self.metrics);
|
try self.with_cursels_const(root, &move_to_match_bracket, self.metrics);
|
||||||
self.clamp();
|
self.clamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const goto_bracket_meta: Meta = .{ .description = "goto matching bracket" };
|
pub const goto_bracket_meta: Meta = .{ .description = "goto matching bracket" };
|
||||||
|
|
||||||
pub fn move_or_select_to_char_right(self: *Self, ctx: Context) Result {
|
pub fn move_or_select_to_char_right(self: *Self, ctx: Context) Result {
|
||||||
|
|
|
||||||
|
|
@ -209,6 +209,15 @@ const cmds_ = struct {
|
||||||
}
|
}
|
||||||
pub const split_selection_on_newline_meta: Meta = .{ .description = "Add cursor to each line in selection helix" };
|
pub const split_selection_on_newline_meta: Meta = .{ .description = "Add cursor to each line in selection helix" };
|
||||||
|
|
||||||
|
pub fn match_brackets(_: *void, ctx: Ctx) Result {
|
||||||
|
const mv = tui.mainview() orelse return;
|
||||||
|
const ed = mv.get_active_editor() orelse return;
|
||||||
|
const root = ed.buf_root() catch return;
|
||||||
|
try ed.with_cursels_const_once_arg(root, &match_bracket, ctx);
|
||||||
|
ed.clamp();
|
||||||
|
}
|
||||||
|
pub const match_brackets_meta: Meta = .{ .description = "Goto matching bracket" };
|
||||||
|
|
||||||
pub fn extend_line_below(_: *void, ctx: Ctx) Result {
|
pub fn extend_line_below(_: *void, ctx: Ctx) Result {
|
||||||
const mv = tui.mainview() orelse return;
|
const mv = tui.mainview() orelse return;
|
||||||
const ed = mv.get_active_editor() orelse return;
|
const ed = mv.get_active_editor() orelse return;
|
||||||
|
|
@ -443,6 +452,42 @@ const cmds_ = struct {
|
||||||
pub const replace_with_character_helix_meta: Meta = .{ .description = "Replace with character" };
|
pub const replace_with_character_helix_meta: Meta = .{ .description = "Replace with character" };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fn match_bracket(root: Buffer.Root, cursel: *CurSel, ctx: command.Context, metrics: Buffer.Metrics) error{Stop}!void {
|
||||||
|
var symbol: []const u8 = undefined;
|
||||||
|
const mode: enum { helix_sel_mode, helix_nor_mode } = if ((ctx.args.match(.{tp.extract(&symbol)}) catch false) and
|
||||||
|
std.mem.eql(u8, @tagName(.helix_sel_mode), symbol)) .helix_sel_mode else .helix_nor_mode;
|
||||||
|
|
||||||
|
if (mode == .helix_sel_mode) {
|
||||||
|
const begin: Cursor = if (cursel.selection) |sel| sel.begin else cursel.*.cursor;
|
||||||
|
if (cursel.*.selection) |*sel| {
|
||||||
|
const row, const col = Editor.match_bracket(root, cursel.*.cursor, metrics) catch blk: {
|
||||||
|
// Selection in hx mode requires to move to the left to begin manipulation
|
||||||
|
try cursel.*.cursor.move_left(root, metrics);
|
||||||
|
break :blk try Editor.match_bracket(root, cursel.*.cursor, metrics);
|
||||||
|
};
|
||||||
|
cursel.*.cursor.row = row;
|
||||||
|
cursel.*.cursor.col = col;
|
||||||
|
sel.end = cursel.*.cursor;
|
||||||
|
|
||||||
|
//Then to include the whole selection, requires to extend to the right
|
||||||
|
if (sel.is_reversed()) {
|
||||||
|
try sel.begin.move_right(root, metrics);
|
||||||
|
} else {
|
||||||
|
try cursel.*.cursor.move_right(root, metrics);
|
||||||
|
try sel.end.move_right(root, metrics);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cursel.*.selection = Selection.from_cursor(&begin);
|
||||||
|
cursel.*.selection.?.end = cursel.*.cursor;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const row, const col = try Editor.match_bracket(root, cursel.*.cursor, metrics);
|
||||||
|
cursel.*.cursor.row = row;
|
||||||
|
cursel.*.cursor.col = col;
|
||||||
|
cursel.*.selection = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn move_to_word(ctx: command.Context, move: Editor.cursor_operator_const) command.Result {
|
fn move_to_word(ctx: command.Context, move: Editor.cursor_operator_const) command.Result {
|
||||||
const mv = tui.mainview() orelse return;
|
const mv = tui.mainview() orelse return;
|
||||||
const ed = mv.get_active_editor() orelse return;
|
const ed = mv.get_active_editor() orelse return;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue