Add quote textobject actions
This commit is contained in:
parent
763935912f
commit
76cc8260bb
3 changed files with 314 additions and 24 deletions
|
|
@ -88,6 +88,8 @@
|
||||||
["di]", "cut_inside_square_brackets"],
|
["di]", "cut_inside_square_brackets"],
|
||||||
["di{", "cut_inside_braces"],
|
["di{", "cut_inside_braces"],
|
||||||
["di}", "cut_inside_braces"],
|
["di}", "cut_inside_braces"],
|
||||||
|
["di'", "cut_inside_single_quotes"],
|
||||||
|
["di\"", "cut_inside_double_quotes"],
|
||||||
|
|
||||||
["daw", "cut_around_word"],
|
["daw", "cut_around_word"],
|
||||||
["da(", "cut_around_parentheses"],
|
["da(", "cut_around_parentheses"],
|
||||||
|
|
@ -96,6 +98,8 @@
|
||||||
["da]", "cut_around_square_brackets"],
|
["da]", "cut_around_square_brackets"],
|
||||||
["da{", "cut_around_braces"],
|
["da{", "cut_around_braces"],
|
||||||
["da}", "cut_around_braces"],
|
["da}", "cut_around_braces"],
|
||||||
|
["da'", "cut_around_single_quotes"],
|
||||||
|
["da\"", "cut_around_double_quotes"],
|
||||||
|
|
||||||
["cc", ["enter_mode", "insert"], ["cut_internal_vim"]],
|
["cc", ["enter_mode", "insert"], ["cut_internal_vim"]],
|
||||||
["C", ["enter_mode", "insert"], ["cut_to_end_vim"]],
|
["C", ["enter_mode", "insert"], ["cut_to_end_vim"]],
|
||||||
|
|
@ -110,6 +114,8 @@
|
||||||
["ci]", ["enter_mode", "insert"], ["cut_inside_square_brackets"]],
|
["ci]", ["enter_mode", "insert"], ["cut_inside_square_brackets"]],
|
||||||
["ci{", ["enter_mode", "insert"], ["cut_inside_braces"]],
|
["ci{", ["enter_mode", "insert"], ["cut_inside_braces"]],
|
||||||
["ci}", ["enter_mode", "insert"], ["cut_inside_braces"]],
|
["ci}", ["enter_mode", "insert"], ["cut_inside_braces"]],
|
||||||
|
["ci'", ["enter_mode", "insert"], ["cut_inside_single_quotes"]],
|
||||||
|
["ci\"", ["enter_mode", "insert"], ["cut_inside_double_quotes"]],
|
||||||
|
|
||||||
["caw", ["enter_mode", "insert"], ["cut_around_word"]],
|
["caw", ["enter_mode", "insert"], ["cut_around_word"]],
|
||||||
["ca(", ["enter_mode", "insert"], ["cut_around_parentheses"]],
|
["ca(", ["enter_mode", "insert"], ["cut_around_parentheses"]],
|
||||||
|
|
@ -118,6 +124,8 @@
|
||||||
["ca]", ["enter_mode", "insert"], ["cut_around_square_brackets"]],
|
["ca]", ["enter_mode", "insert"], ["cut_around_square_brackets"]],
|
||||||
["ca{", ["enter_mode", "insert"], ["cut_around_braces"]],
|
["ca{", ["enter_mode", "insert"], ["cut_around_braces"]],
|
||||||
["ca}", ["enter_mode", "insert"], ["cut_around_braces"]],
|
["ca}", ["enter_mode", "insert"], ["cut_around_braces"]],
|
||||||
|
["ca'", ["enter_mode", "insert"], ["cut_around_single_quotes"]],
|
||||||
|
["ca\"", ["enter_mode", "insert"], ["cut_around_double_quotes"]],
|
||||||
|
|
||||||
["yy", ["copy_line_internal_vim"], ["cancel"]],
|
["yy", ["copy_line_internal_vim"], ["cancel"]],
|
||||||
|
|
||||||
|
|
@ -128,6 +136,8 @@
|
||||||
["yi]", ["copy_inside_square_brackets"], ["cancel"]],
|
["yi]", ["copy_inside_square_brackets"], ["cancel"]],
|
||||||
["yi{", ["copy_inside_braces"], ["cancel"]],
|
["yi{", ["copy_inside_braces"], ["cancel"]],
|
||||||
["yi}", ["copy_inside_braces"], ["cancel"]],
|
["yi}", ["copy_inside_braces"], ["cancel"]],
|
||||||
|
["yi'", ["copy_inside_single_quotes"], ["cancel"]],
|
||||||
|
["yi\"", ["copy_inside_double_quotes"], ["cancel"]],
|
||||||
|
|
||||||
["yaw", ["copy_around_word"], ["cancel"]],
|
["yaw", ["copy_around_word"], ["cancel"]],
|
||||||
["ya(", ["copy_around_parentheses"], ["cancel"]],
|
["ya(", ["copy_around_parentheses"], ["cancel"]],
|
||||||
|
|
@ -136,6 +146,8 @@
|
||||||
["ya]", ["copy_around_square_brackets"], ["cancel"]],
|
["ya]", ["copy_around_square_brackets"], ["cancel"]],
|
||||||
["ya{", ["copy_around_braces"], ["cancel"]],
|
["ya{", ["copy_around_braces"], ["cancel"]],
|
||||||
["ya}", ["copy_around_braces"], ["cancel"]],
|
["ya}", ["copy_around_braces"], ["cancel"]],
|
||||||
|
["ya'", ["copy_around_single_quotes"], ["cancel"]],
|
||||||
|
["ya\"", ["copy_around_double_quotes"], ["cancel"]],
|
||||||
|
|
||||||
["<C-u>", "move_scroll_half_page_up_vim"],
|
["<C-u>", "move_scroll_half_page_up_vim"],
|
||||||
["<C-d>", "move_scroll_half_page_down_vim"],
|
["<C-d>", "move_scroll_half_page_down_vim"],
|
||||||
|
|
@ -214,6 +226,8 @@
|
||||||
["i]", "select_inside_square_brackets"],
|
["i]", "select_inside_square_brackets"],
|
||||||
["i{", "select_inside_braces"],
|
["i{", "select_inside_braces"],
|
||||||
["i}", "select_inside_braces"],
|
["i}", "select_inside_braces"],
|
||||||
|
["i'", "select_inside_single_quotes"],
|
||||||
|
["i\"", "select_inside_double_quotes"],
|
||||||
|
|
||||||
["aw", "select_around_word"],
|
["aw", "select_around_word"],
|
||||||
["a(", "select_around_parentheses"],
|
["a(", "select_around_parentheses"],
|
||||||
|
|
@ -222,6 +236,8 @@
|
||||||
["a]", "select_around_square_brackets"],
|
["a]", "select_around_square_brackets"],
|
||||||
["a{", "select_around_braces"],
|
["a{", "select_around_braces"],
|
||||||
["a}", "select_around_braces"],
|
["a}", "select_around_braces"],
|
||||||
|
["a'", "select_around_single_quotes"],
|
||||||
|
["a\"", "select_around_double_quotes"],
|
||||||
|
|
||||||
["^", "smart_move_begin"],
|
["^", "smart_move_begin"],
|
||||||
["$", "select_end"],
|
["$", "select_end"],
|
||||||
|
|
|
||||||
|
|
@ -3974,6 +3974,126 @@ pub const Editor = struct {
|
||||||
}
|
}
|
||||||
pub const goto_bracket_meta: Meta = .{ .description = "Goto matching bracket" };
|
pub const goto_bracket_meta: Meta = .{ .description = "Goto matching bracket" };
|
||||||
|
|
||||||
|
const QuoteRole = enum { opening, closing };
|
||||||
|
|
||||||
|
fn row_start_cursor(root: Buffer.Root, cursor: Cursor, metrics: Buffer.Metrics) Cursor {
|
||||||
|
var c = cursor;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
var prev = c;
|
||||||
|
prev.move_left(root, metrics) catch break;
|
||||||
|
if (prev.row != c.row) break;
|
||||||
|
c = prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn quote_is_escaped(root: Buffer.Root, quote_cursor: Cursor, metrics: Buffer.Metrics) bool {
|
||||||
|
var cursor = quote_cursor;
|
||||||
|
var backslashes: usize = 0;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
var prev = cursor;
|
||||||
|
prev.move_left(root, metrics) catch break;
|
||||||
|
if (prev.row != cursor.row) break;
|
||||||
|
|
||||||
|
const egc, _, _ = root.egc_at(prev.row, prev.col, metrics) catch break;
|
||||||
|
if (!std.mem.eql(u8, egc, "\\")) break;
|
||||||
|
|
||||||
|
backslashes += 1;
|
||||||
|
cursor = prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (backslashes % 2) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_unescaped_quote(
|
||||||
|
root: Buffer.Root,
|
||||||
|
start: Cursor,
|
||||||
|
metrics: Buffer.Metrics,
|
||||||
|
direction: enum { left, right },
|
||||||
|
quote: []const u8,
|
||||||
|
) error{Stop}!Cursor {
|
||||||
|
var cursor = start;
|
||||||
|
var i: usize = 0;
|
||||||
|
|
||||||
|
while (i < bracket_search_radius) : (i += 1) {
|
||||||
|
switch (direction) {
|
||||||
|
.left => cursor.move_left(root, metrics) catch return error.Stop,
|
||||||
|
.right => cursor.move_right(root, metrics) catch return error.Stop,
|
||||||
|
}
|
||||||
|
|
||||||
|
const egc, _, _ = root.egc_at(cursor.row, cursor.col, metrics) catch {
|
||||||
|
return error.Stop;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!std.mem.eql(u8, egc, quote)) continue;
|
||||||
|
if (quote_is_escaped(root, cursor, metrics)) continue;
|
||||||
|
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return error.Stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn quote_role_on_row(
|
||||||
|
root: Buffer.Root,
|
||||||
|
quote_cursor: Cursor,
|
||||||
|
metrics: Buffer.Metrics,
|
||||||
|
quote: []const u8,
|
||||||
|
) error{Stop}!QuoteRole {
|
||||||
|
var cursor = row_start_cursor(root, .{ .row = quote_cursor.row, .col = 0 }, metrics);
|
||||||
|
var opening = true;
|
||||||
|
|
||||||
|
while (cursor.row == quote_cursor.row and cursor.col <= quote_cursor.col) {
|
||||||
|
const egc, _, _ = root.egc_at(cursor.row, cursor.col, metrics) catch {
|
||||||
|
return error.Stop;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, egc, quote) and !quote_is_escaped(root, cursor, metrics)) {
|
||||||
|
if (cursor.col == quote_cursor.col) {
|
||||||
|
return if (opening) .opening else .closing;
|
||||||
|
}
|
||||||
|
opening = !opening;
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor.move_right(root, metrics) catch break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return error.Stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find_quote_pair(
|
||||||
|
root: Buffer.Root,
|
||||||
|
original_cursor: Cursor,
|
||||||
|
metrics: Buffer.Metrics,
|
||||||
|
quote: []const u8,
|
||||||
|
) error{Stop}!struct { struct { usize, usize }, struct { usize, usize } } {
|
||||||
|
|
||||||
|
// Find nearest quote (prefer rightward)
|
||||||
|
const anchor =
|
||||||
|
find_unescaped_quote(root, original_cursor, metrics, .right, quote) catch find_unescaped_quote(root, original_cursor, metrics, .left, quote) catch return error.Stop;
|
||||||
|
|
||||||
|
const role = try quote_role_on_row(root, anchor, metrics, quote);
|
||||||
|
|
||||||
|
const other = switch (role) {
|
||||||
|
.opening => try find_unescaped_quote(root, anchor, metrics, .right, quote),
|
||||||
|
.closing => try find_unescaped_quote(root, anchor, metrics, .left, quote),
|
||||||
|
};
|
||||||
|
|
||||||
|
return switch (role) {
|
||||||
|
.opening => .{
|
||||||
|
.{ anchor.row, anchor.col },
|
||||||
|
.{ other.row, other.col },
|
||||||
|
},
|
||||||
|
.closing => .{
|
||||||
|
.{ other.row, other.col },
|
||||||
|
.{ anchor.row, anchor.col },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
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 {
|
||||||
const selected = if (self.get_primary().selection) |_| true else false;
|
const selected = if (self.get_primary().selection) |_| true else false;
|
||||||
if (selected) try self.select_to_char_right(ctx) else try self.move_to_char_right(ctx);
|
if (selected) try self.select_to_char_right(ctx) else try self.move_to_char_right(ctx);
|
||||||
|
|
|
||||||
|
|
@ -220,6 +220,42 @@ const cmds_ = struct {
|
||||||
}
|
}
|
||||||
pub const select_around_braces_meta: Meta = .{ .description = "Select around {}" };
|
pub const select_around_braces_meta: Meta = .{ .description = "Select around {}" };
|
||||||
|
|
||||||
|
pub fn select_inside_single_quotes(_: *void, _: 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(root, select_inside_single_quotes_textobject, ed.metrics);
|
||||||
|
}
|
||||||
|
pub const select_inside_single_quotes_meta: Meta = .{ .description = "Select inside ''" };
|
||||||
|
|
||||||
|
pub fn select_around_single_quotes(_: *void, _: 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(root, select_around_single_quotes_textobject, ed.metrics);
|
||||||
|
}
|
||||||
|
pub const select_around_single_quotes_meta: Meta = .{ .description = "Select around ''" };
|
||||||
|
|
||||||
|
pub fn select_inside_double_quotes(_: *void, _: 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(root, select_inside_double_quotes_textobject, ed.metrics);
|
||||||
|
}
|
||||||
|
pub const select_inside_double_quotes_meta: Meta = .{ .description = "Select inside \"\"" };
|
||||||
|
|
||||||
|
pub fn select_around_double_quotes(_: *void, _: 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(root, select_around_double_quotes_textobject, ed.metrics);
|
||||||
|
}
|
||||||
|
pub const select_around_double_quotes_meta: Meta = .{ .description = "Select around \"\"" };
|
||||||
|
|
||||||
pub fn cut_inside_word(_: *void, ctx: Ctx) Result {
|
pub fn cut_inside_word(_: *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;
|
||||||
|
|
@ -300,6 +336,46 @@ const cmds_ = struct {
|
||||||
}
|
}
|
||||||
pub const cut_around_braces_meta: Meta = .{ .description = "Cut around {}" };
|
pub const cut_around_braces_meta: Meta = .{ .description = "Cut around {}" };
|
||||||
|
|
||||||
|
pub fn cut_inside_single_quotes(_: *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(root, select_inside_single_quotes_textobject, ed.metrics);
|
||||||
|
try ed.cut_internal_vim(ctx);
|
||||||
|
}
|
||||||
|
pub const cut_inside_single_quotes_meta: Meta = .{ .description = "Cut inside ''" };
|
||||||
|
|
||||||
|
pub fn cut_around_single_quotes(_: *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(root, select_around_single_quotes_textobject, ed.metrics);
|
||||||
|
try ed.cut_internal_vim(ctx);
|
||||||
|
}
|
||||||
|
pub const cut_around_single_quotes_meta: Meta = .{ .description = "Cut around ''" };
|
||||||
|
|
||||||
|
pub fn cut_inside_double_quotes(_: *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(root, select_inside_double_quotes_textobject, ed.metrics);
|
||||||
|
try ed.cut_internal_vim(ctx);
|
||||||
|
}
|
||||||
|
pub const cut_inside_double_quotes_meta: Meta = .{ .description = "Cut inside \"\"" };
|
||||||
|
|
||||||
|
pub fn cut_around_double_quotes(_: *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(root, select_around_double_quotes_textobject, ed.metrics);
|
||||||
|
try ed.cut_internal_vim(ctx);
|
||||||
|
}
|
||||||
|
pub const cut_around_double_quotes_meta: Meta = .{ .description = "Cut around \"\"" };
|
||||||
|
|
||||||
pub fn copy_inside_word(_: *void, ctx: Ctx) Result {
|
pub fn copy_inside_word(_: *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;
|
||||||
|
|
@ -379,6 +455,46 @@ const cmds_ = struct {
|
||||||
try ed.copy_internal_vim(ctx);
|
try ed.copy_internal_vim(ctx);
|
||||||
}
|
}
|
||||||
pub const copy_around_braces_meta: Meta = .{ .description = "Copy around {}" };
|
pub const copy_around_braces_meta: Meta = .{ .description = "Copy around {}" };
|
||||||
|
|
||||||
|
pub fn copy_inside_single_quotes(_: *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(root, select_inside_single_quotes_textobject, ed.metrics);
|
||||||
|
try ed.copy_internal_vim(ctx);
|
||||||
|
}
|
||||||
|
pub const copy_inside_single_quotes_meta: Meta = .{ .description = "Copy inside ''" };
|
||||||
|
|
||||||
|
pub fn copy_around_single_quotes(_: *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(root, select_around_single_quotes_textobject, ed.metrics);
|
||||||
|
try ed.copy_internal_vim(ctx);
|
||||||
|
}
|
||||||
|
pub const copy_around_single_quotes_meta: Meta = .{ .description = "Copy around ''" };
|
||||||
|
|
||||||
|
pub fn copy_inside_double_quotes(_: *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(root, select_inside_double_quotes_textobject, ed.metrics);
|
||||||
|
try ed.copy_internal_vim(ctx);
|
||||||
|
}
|
||||||
|
pub const copy_inside_double_quotes_meta: Meta = .{ .description = "Copy inside \"\"" };
|
||||||
|
|
||||||
|
pub fn copy_around_double_quotes(_: *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(root, select_around_double_quotes_textobject, ed.metrics);
|
||||||
|
try ed.copy_internal_vim(ctx);
|
||||||
|
}
|
||||||
|
pub const copy_around_double_quotes_meta: Meta = .{ .description = "Copy around \"\"" };
|
||||||
};
|
};
|
||||||
|
|
||||||
fn is_tab_or_space(c: []const u8) bool {
|
fn is_tab_or_space(c: []const u8) bool {
|
||||||
|
|
@ -444,56 +560,94 @@ fn select_word_textobject(root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Me
|
||||||
}
|
}
|
||||||
|
|
||||||
fn select_inside_parentheses_textobject(root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
fn select_inside_parentheses_textobject(root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
||||||
return try select_bracket_textobject(root, cursel, metrics, "(", ")", .inside);
|
return try select_scope_textobject(root, cursel, metrics, "(", ")", .inside);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn select_around_parentheses_textobject(root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
fn select_around_parentheses_textobject(root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
||||||
return try select_bracket_textobject(root, cursel, metrics, "(", ")", .around);
|
return try select_scope_textobject(root, cursel, metrics, "(", ")", .around);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn select_inside_square_brackets_textobject(root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
fn select_inside_square_brackets_textobject(root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
||||||
return try select_bracket_textobject(root, cursel, metrics, "[", "]", .inside);
|
return try select_scope_textobject(root, cursel, metrics, "[", "]", .inside);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn select_around_square_brackets_textobject(root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
fn select_around_square_brackets_textobject(root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
||||||
return try select_bracket_textobject(root, cursel, metrics, "[", "]", .around);
|
return try select_scope_textobject(root, cursel, metrics, "[", "]", .around);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn select_inside_braces_textobject(root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
fn select_inside_braces_textobject(root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
||||||
return try select_bracket_textobject(root, cursel, metrics, "{", "}", .inside);
|
return try select_scope_textobject(root, cursel, metrics, "{", "}", .inside);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn select_around_braces_textobject(root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
fn select_around_braces_textobject(root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
||||||
return try select_bracket_textobject(root, cursel, metrics, "{", "}", .around);
|
return try select_scope_textobject(root, cursel, metrics, "{", "}", .around);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn select_bracket_textobject(root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics, opening_char: []const u8, closing_char: []const u8, scope: enum { inside, around }) !void {
|
fn select_inside_single_quotes_textobject(root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
||||||
|
return try select_scope_textobject(root, cursel, metrics, "'", "'", .inside);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn select_around_single_quotes_textobject(root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
||||||
|
return try select_scope_textobject(root, cursel, metrics, "'", "'", .around);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn select_inside_double_quotes_textobject(root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
||||||
|
return try select_scope_textobject(root, cursel, metrics, "\"", "\"", .inside);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn select_around_double_quotes_textobject(root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
||||||
|
return try select_scope_textobject(root, cursel, metrics, "\"", "\"", .around);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn select_scope_textobject(
|
||||||
|
root: Buffer.Root,
|
||||||
|
cursel: *CurSel,
|
||||||
|
metrics: Buffer.Metrics,
|
||||||
|
opening_char: []const u8,
|
||||||
|
closing_char: []const u8,
|
||||||
|
scope: enum { inside, around },
|
||||||
|
) !void {
|
||||||
const current = cursel.cursor;
|
const current = cursel.cursor;
|
||||||
var prev = cursel.cursor;
|
var prev = cursel.cursor;
|
||||||
var next = cursel.cursor;
|
var next = cursel.cursor;
|
||||||
|
|
||||||
const bracket_egc, _, _ = root.egc_at(current.row, current.col, metrics) catch {
|
if (std.mem.eql(u8, opening_char, closing_char)) {
|
||||||
return error.Stop;
|
const opening_pos, const closing_pos =
|
||||||
};
|
try Editor.find_quote_pair(root, current, metrics, opening_char);
|
||||||
if (std.mem.eql(u8, bracket_egc, opening_char)) {
|
|
||||||
const closing_row, const closing_col = try Editor.match_bracket(root, current, metrics);
|
|
||||||
|
|
||||||
prev = current;
|
|
||||||
next.row = closing_row;
|
|
||||||
next.col = closing_col;
|
|
||||||
} else if (std.mem.eql(u8, bracket_egc, closing_char)) {
|
|
||||||
const opening_row, const opening_col = try Editor.match_bracket(root, current, metrics);
|
|
||||||
|
|
||||||
prev.row = opening_row;
|
|
||||||
prev.col = opening_col;
|
|
||||||
next = current;
|
|
||||||
} else {
|
|
||||||
const opening_pos, const closing_pos = find_bracket_pair(root, cursel, metrics, .left, opening_char) catch try find_bracket_pair(root, cursel, metrics, .right, opening_char);
|
|
||||||
|
|
||||||
prev.row = opening_pos[0];
|
prev.row = opening_pos[0];
|
||||||
prev.col = opening_pos[1];
|
prev.col = opening_pos[1];
|
||||||
next.row = closing_pos[0];
|
next.row = closing_pos[0];
|
||||||
next.col = closing_pos[1];
|
next.col = closing_pos[1];
|
||||||
|
} else {
|
||||||
|
const bracket_egc, _, _ = root.egc_at(current.row, current.col, metrics) catch {
|
||||||
|
return error.Stop;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, bracket_egc, opening_char)) {
|
||||||
|
const closing_row, const closing_col =
|
||||||
|
try Editor.match_bracket(root, current, metrics);
|
||||||
|
|
||||||
|
prev = current;
|
||||||
|
next.row = closing_row;
|
||||||
|
next.col = closing_col;
|
||||||
|
} else if (std.mem.eql(u8, bracket_egc, closing_char)) {
|
||||||
|
const opening_row, const opening_col =
|
||||||
|
try Editor.match_bracket(root, current, metrics);
|
||||||
|
|
||||||
|
prev.row = opening_row;
|
||||||
|
prev.col = opening_col;
|
||||||
|
next = current;
|
||||||
|
} else {
|
||||||
|
const pair = find_bracket_pair(root, cursel, metrics, .left, opening_char) catch blk: {
|
||||||
|
break :blk try find_bracket_pair(root, cursel, metrics, .right, opening_char);
|
||||||
|
};
|
||||||
|
|
||||||
|
prev.row = pair[0][0];
|
||||||
|
prev.col = pair[0][1];
|
||||||
|
next.row = pair[1][0];
|
||||||
|
next.col = pair[1][1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prev.move_right(root, metrics) catch {};
|
prev.move_right(root, metrics) catch {};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue