Merge branch 'master' into keybind
This commit is contained in:
commit
eddc074a23
5 changed files with 178 additions and 3 deletions
|
@ -30,8 +30,8 @@
|
|||
.hash = "122019f077d09686b1ec47928ca2b4bf264422f3a27afc5b49dafb0129a4ceca0d01",
|
||||
},
|
||||
.vaxis = .{
|
||||
.url = "https://github.com/neurocyte/libvaxis/archive/c26a190401bcd354263fa6f90446c947aca5ec2d.tar.gz",
|
||||
.hash = "1220f89a746527174f2f297f5f6f85e1cca4267d5f75c7b6b840926ff0b1bb187e97",
|
||||
.url = "https://github.com/neurocyte/libvaxis/archive/352fa9c89d6339325b9f851b9a27e62ec79ba33c.tar.gz",
|
||||
.hash = "1220e604b723781b4a306db5801eee419a689b4d470232a1bacc525f45f00d455b1a",
|
||||
},
|
||||
.zeit = .{
|
||||
.url = "https://github.com/rockorager/zeit/archive/9cca8ec620a54c3b07cd249f25e5bcb3153d03d7.tar.gz",
|
||||
|
|
|
@ -759,7 +759,7 @@ const Node = union(enum) {
|
|||
return if (found) ctx.result else error.NotFound;
|
||||
}
|
||||
|
||||
pub fn pos_to_width(self: *const Node, line: usize, pos: usize, metrics_: Metrics) !usize {
|
||||
pub fn pos_to_width(self: *const Node, line: usize, pos: usize, metrics_: Metrics) error{NotFound}!usize {
|
||||
const do = struct {
|
||||
result: usize = 0,
|
||||
pos: usize,
|
||||
|
|
|
@ -91,6 +91,8 @@
|
|||
["alt+shift+i", "add_cursors_to_line_ends"],
|
||||
["alt+shift+left", "shrink_selection"],
|
||||
["alt+shift+right", "expand_selection"],
|
||||
["alt+home", "select_prev_sibling"],
|
||||
["alt+end", "select_next_sibling"],
|
||||
["alt+shift+home", "move_scroll_left"],
|
||||
["alt+shift+end", "move_scroll_right"],
|
||||
["alt+shift+up", "add_cursor_up"],
|
||||
|
|
|
@ -184,3 +184,9 @@ pub fn highlights_at_point(self: *const Self, ctx: anytype, comptime cb: CallBac
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
pub fn node_at_point_range(self: *const Self, range: Range) error{Stop}!treez.Node {
|
||||
const tree = self.tree orelse return error.Stop;
|
||||
const root_node = tree.getRootNode();
|
||||
return treez.Node.externs.ts_node_descendant_for_point_range(root_node, range.start_point, range.end_point);
|
||||
}
|
||||
|
|
|
@ -111,6 +111,21 @@ pub const CurSel = struct {
|
|||
return sel;
|
||||
}
|
||||
|
||||
fn select_node(self: *Self, node: syntax.Node, root: Buffer.Root, metrics: Buffer.Metrics) error{NotFound}!void {
|
||||
const range = node.getRange();
|
||||
self.selection = .{
|
||||
.begin = .{
|
||||
.row = range.start_point.row,
|
||||
.col = try root.pos_to_width(range.start_point.row, range.start_point.column, metrics),
|
||||
},
|
||||
.end = .{
|
||||
.row = range.end_point.row,
|
||||
.col = try root.pos_to_width(range.end_point.row, range.end_point.column, metrics),
|
||||
},
|
||||
};
|
||||
self.cursor = self.selection.?.end;
|
||||
}
|
||||
|
||||
fn write(self: *const Self, writer: Buffer.MetaWriter) !void {
|
||||
try self.cursor.write(writer);
|
||||
if (self.selection) |sel| {
|
||||
|
@ -2924,6 +2939,158 @@ pub const Editor = struct {
|
|||
}
|
||||
pub const selections_reverse_meta = .{ .description = "Reverse selection" };
|
||||
|
||||
fn node_at_selection(self: *Self, sel: Selection, root: Buffer.Root, metrics: Buffer.Metrics) error{Stop}!syntax.Node {
|
||||
const syn = self.syntax orelse return error.Stop;
|
||||
const node = try syn.node_at_point_range(.{
|
||||
.start_point = .{
|
||||
.row = @intCast(sel.begin.row),
|
||||
.column = @intCast(try root.get_line_width_to_pos(sel.begin.row, sel.begin.col, metrics)),
|
||||
},
|
||||
.end_point = .{
|
||||
.row = @intCast(sel.end.row),
|
||||
.column = @intCast(try root.get_line_width_to_pos(sel.end.row, sel.end.col, metrics)),
|
||||
},
|
||||
.start_byte = 0,
|
||||
.end_byte = 0,
|
||||
});
|
||||
if (node.isNull()) return error.Stop;
|
||||
return node;
|
||||
}
|
||||
|
||||
fn select_node_at_cursor(self: *Self, root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
||||
cursel.selection = null;
|
||||
const sel = cursel.enable_selection().*;
|
||||
return cursel.select_node(try self.node_at_selection(sel, root, metrics), root, metrics);
|
||||
}
|
||||
|
||||
fn expand_selection_to_parent_node(self: *Self, root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
||||
const sel = cursel.enable_selection().*;
|
||||
const node = try self.node_at_selection(sel, root, metrics);
|
||||
if (node.isNull()) return error.Stop;
|
||||
const parent = node.getParent();
|
||||
if (parent.isNull()) return error.Stop;
|
||||
return cursel.select_node(parent, root, metrics);
|
||||
}
|
||||
|
||||
pub fn expand_selection(self: *Self, _: Context) Result {
|
||||
try self.send_editor_jump_source();
|
||||
const root = try self.buf_root();
|
||||
const cursel = self.get_primary();
|
||||
cursel.check_selection();
|
||||
try if (cursel.selection) |_|
|
||||
self.expand_selection_to_parent_node(root, cursel, self.metrics)
|
||||
else
|
||||
self.select_node_at_cursor(root, cursel, self.metrics);
|
||||
self.clamp();
|
||||
try self.send_editor_jump_destination();
|
||||
}
|
||||
pub const expand_selection_meta = .{ .description = "Expand selection to AST parent node" };
|
||||
|
||||
fn shrink_selection_to_child_node(self: *Self, root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
||||
const sel = cursel.enable_selection().*;
|
||||
const node = try self.node_at_selection(sel, root, metrics);
|
||||
if (node.isNull() or node.getChildCount() == 0) return error.Stop;
|
||||
const child = node.getChild(0);
|
||||
if (child.isNull()) return error.Stop;
|
||||
return cursel.select_node(child, root, metrics);
|
||||
}
|
||||
|
||||
fn shrink_selection_to_named_child_node(self: *Self, root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
||||
const sel = cursel.enable_selection().*;
|
||||
const node = try self.node_at_selection(sel, root, metrics);
|
||||
if (node.isNull() or node.getNamedChildCount() == 0) return error.Stop;
|
||||
const child = node.getNamedChild(0);
|
||||
if (child.isNull()) return error.Stop;
|
||||
return cursel.select_node(child, root, metrics);
|
||||
}
|
||||
|
||||
pub fn shrink_selection(self: *Self, ctx: Context) Result {
|
||||
var unnamed: bool = false;
|
||||
_ = ctx.args.match(.{tp.extract(&unnamed)}) catch false;
|
||||
try self.send_editor_jump_source();
|
||||
const root = try self.buf_root();
|
||||
const cursel = self.get_primary();
|
||||
cursel.check_selection();
|
||||
if (cursel.selection) |_|
|
||||
try if (unnamed)
|
||||
self.shrink_selection_to_child_node(root, cursel, self.metrics)
|
||||
else
|
||||
self.shrink_selection_to_named_child_node(root, cursel, self.metrics);
|
||||
self.clamp();
|
||||
try self.send_editor_jump_destination();
|
||||
}
|
||||
pub const shrink_selection_meta = .{ .description = "Shrink selection to first AST child node" };
|
||||
|
||||
fn select_next_sibling_node(self: *Self, root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
||||
const sel = cursel.enable_selection().*;
|
||||
const node = try self.node_at_selection(sel, root, metrics);
|
||||
if (node.isNull()) return error.Stop;
|
||||
const sibling = syntax.Node.externs.ts_node_next_sibling(node);
|
||||
if (sibling.isNull()) return error.Stop;
|
||||
return cursel.select_node(sibling, root, metrics);
|
||||
}
|
||||
|
||||
fn select_next_named_sibling_node(self: *Self, root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
||||
const sel = cursel.enable_selection().*;
|
||||
const node = try self.node_at_selection(sel, root, metrics);
|
||||
if (node.isNull()) return error.Stop;
|
||||
const sibling = syntax.Node.externs.ts_node_next_named_sibling(node);
|
||||
if (sibling.isNull()) return error.Stop;
|
||||
return cursel.select_node(sibling, root, metrics);
|
||||
}
|
||||
|
||||
pub fn select_next_sibling(self: *Self, ctx: Context) Result {
|
||||
var unnamed: bool = false;
|
||||
_ = ctx.args.match(.{tp.extract(&unnamed)}) catch false;
|
||||
try self.send_editor_jump_source();
|
||||
const root = try self.buf_root();
|
||||
const cursel = self.get_primary();
|
||||
cursel.check_selection();
|
||||
if (cursel.selection) |_|
|
||||
try if (unnamed)
|
||||
self.select_next_sibling_node(root, cursel, self.metrics)
|
||||
else
|
||||
self.select_next_named_sibling_node(root, cursel, self.metrics);
|
||||
self.clamp();
|
||||
try self.send_editor_jump_destination();
|
||||
}
|
||||
pub const select_next_sibling_meta = .{ .description = "Move selection to next AST sibling node" };
|
||||
|
||||
fn select_prev_sibling_node(self: *Self, root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
||||
const sel = cursel.enable_selection().*;
|
||||
const node = try self.node_at_selection(sel, root, metrics);
|
||||
if (node.isNull()) return error.Stop;
|
||||
const sibling = syntax.Node.externs.ts_node_prev_sibling(node);
|
||||
if (sibling.isNull()) return error.Stop;
|
||||
return cursel.select_node(sibling, root, metrics);
|
||||
}
|
||||
|
||||
fn select_prev_named_sibling_node(self: *Self, root: Buffer.Root, cursel: *CurSel, metrics: Buffer.Metrics) !void {
|
||||
const sel = cursel.enable_selection().*;
|
||||
const node = try self.node_at_selection(sel, root, metrics);
|
||||
if (node.isNull()) return error.Stop;
|
||||
const sibling = syntax.Node.externs.ts_node_prev_named_sibling(node);
|
||||
if (sibling.isNull()) return error.Stop;
|
||||
return cursel.select_node(sibling, root, metrics);
|
||||
}
|
||||
|
||||
pub fn select_prev_sibling(self: *Self, ctx: Context) Result {
|
||||
var unnamed: bool = false;
|
||||
_ = ctx.args.match(.{tp.extract(&unnamed)}) catch false;
|
||||
try self.send_editor_jump_source();
|
||||
const root = try self.buf_root();
|
||||
const cursel = self.get_primary();
|
||||
cursel.check_selection();
|
||||
if (cursel.selection) |_|
|
||||
try if (unnamed)
|
||||
self.select_prev_sibling_node(root, cursel, self.metrics)
|
||||
else
|
||||
self.select_prev_named_sibling_node(root, cursel, self.metrics);
|
||||
self.clamp();
|
||||
try self.send_editor_jump_destination();
|
||||
}
|
||||
pub const select_prev_sibling_meta = .{ .description = "Move selection to previous AST sibling node" };
|
||||
|
||||
pub fn insert_chars(self: *Self, ctx: Context) Result {
|
||||
var chars: []const u8 = undefined;
|
||||
if (!try ctx.args.match(.{tp.extract(&chars)}))
|
||||
|
|
Loading…
Add table
Reference in a new issue