From 76d8bdebcb1bfd96b481717dca96a421f9ce3bb6 Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Mon, 4 Mar 2024 23:08:45 +0100 Subject: [PATCH] feat: add current tree-sitter node to inspecter_view --- src/syntax.zig | 7 +++--- src/tui/editor.zig | 9 ++++---- src/tui/inspector_view.zig | 46 +++++++++++++++++++++++++++++++++----- 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/syntax.zig b/src/syntax.zig index 947a32b..5fd572e 100644 --- a/src/syntax.zig +++ b/src/syntax.zig @@ -11,6 +11,7 @@ const Language = treez.Language; const Parser = treez.Parser; const Query = treez.Query; const Tree = treez.Tree; +pub const Node = treez.Node; a: std.mem.Allocator, lang: *const Language, @@ -73,7 +74,7 @@ pub fn refresh(self: *Self, content: []const u8) !void { } fn CallBack(comptime T: type) type { - return fn (ctx: T, sel: Range, scope: []const u8, id: u32, capture_idx: usize) error{Stop}!void; + return fn (ctx: T, sel: Range, scope: []const u8, id: u32, capture_idx: usize, node: *const Node) error{Stop}!void; } pub fn render(self: *const Self, ctx: anytype, comptime cb: CallBack(@TypeOf(ctx)), range: ?Range) !void { @@ -85,7 +86,7 @@ pub fn render(self: *const Self, ctx: anytype, comptime cb: CallBack(@TypeOf(ctx while (cursor.nextMatch()) |match| { var idx: usize = 0; for (match.captures()) |capture| { - try cb(ctx, capture.node.getRange(), self.query.getCaptureNameForId(capture.id), capture.id, idx); + try cb(ctx, capture.node.getRange(), self.query.getCaptureNameForId(capture.id), capture.id, idx, &capture.node); idx += 1; } } @@ -104,7 +105,7 @@ pub fn highlights_at_point(self: *const Self, ctx: anytype, comptime cb: CallBac const end = range.end_point; const scope = self.query.getCaptureNameForId(capture.id); if (start.row == point.row and start.column <= point.column and point.column < end.column) - cb(ctx, range, scope, capture.id, 0) catch return; + cb(ctx, range, scope, capture.id, 0, &capture.node) catch return; break; } } diff --git a/src/tui/editor.zig b/src/tui/editor.zig index a80fc98..089f0e7 100644 --- a/src/tui/editor.zig +++ b/src/tui/editor.zig @@ -47,6 +47,7 @@ pub const Match = struct { begin: Cursor = Cursor{}, end: Cursor = Cursor{}, has_selection: bool = false, + style: ?Widget.Theme.Style = null, const List = std.ArrayList(?Self); const Self = @This(); @@ -724,7 +725,7 @@ pub const Editor = struct { if (self.is_point_before_selection(sel, y, x)) return; if (self.is_point_in_selection(sel, y, x)) - return self.render_match_cell(theme, cell); + return self.render_match_cell(theme, cell, sel); last_idx.* += 1; } } @@ -754,8 +755,8 @@ pub const Editor = struct { tui.set_cell_style_bg(cell, theme.editor_selection); } - inline fn render_match_cell(_: *const Self, theme: *const Widget.Theme, cell: *nc.Cell) void { - tui.set_cell_style_bg(cell, theme.editor_match); + inline fn render_match_cell(_: *const Self, theme: *const Widget.Theme, cell: *nc.Cell, match: Match) void { + tui.set_cell_style_bg(cell, if (match.style) |style| style else theme.editor_match); } inline fn render_line_highlight_cell(_: *const Self, theme: *const Widget.Theme, cell: *nc.Cell) void { @@ -848,7 +849,7 @@ pub const Editor = struct { last_col: usize = std.math.maxInt(usize), root: Buffer.Root, pos_cache: PosToWidthCache, - fn cb(ctx: *@This(), range: syntax.Range, scope: []const u8, id: u32, _: usize) error{Stop}!void { + fn cb(ctx: *@This(), range: syntax.Range, scope: []const u8, id: u32, _: usize, _: *const syntax.Node) error{Stop}!void { const sel_ = ctx.pos_cache.range_to_selection(range, ctx.root) orelse return; defer { ctx.last_row = sel_.begin.row; diff --git a/src/tui/inspector_view.zig b/src/tui/inspector_view.zig index 969c7ed..aaf72e7 100644 --- a/src/tui/inspector_view.zig +++ b/src/tui/inspector_view.zig @@ -26,6 +26,7 @@ need_clear: bool = false, theme: ?*const Widget.Theme = null, theme_name: []const u8 = "", pos_cache: ed.PosToWidthCache, +last_node: usize = 0, const Self = @This(); @@ -101,19 +102,54 @@ fn get_buffer_text(self: *Self, buf: []u8, sel: Buffer.Selection) ?[]const u8 { return root.get_range(sel, buf, null, null) catch return null; } -fn dump_highlight(self: *Self, range: syntax.Range, scope: []const u8, id: u32, _: usize) error{Stop}!void { +fn dump_highlight(self: *Self, range: syntax.Range, scope: []const u8, id: u32, _: usize, ast_node: *const syntax.Node) error{Stop}!void { const sel = self.pos_cache.range_to_selection(range, self.editor.get_current_root() orelse return) orelse return; if (self.need_clear) { self.need_clear = false; self.clear(); } - if (self.editor.matches.items.len == 0) { - (self.editor.matches.addOne() catch return).* = ed.Match.from_selection(sel); - } else if (self.editor.matches.items.len == 1) { - self.editor.matches.items[0] = ed.Match.from_selection(sel); + var update_match: enum { no, add, set } = .no; + var match = ed.Match.from_selection(sel); + if (self.theme) |theme| match.style = .{ .bg = theme.editor_gutter_modified.fg }; + switch (self.editor.matches.items.len) { + 0 => { + (self.editor.matches.addOne() catch return).* = match; + update_match = .add; + }, + 1 => { + self.editor.matches.items[0] = match; + update_match = .add; + }, + 2 => { + self.editor.matches.items[0] = match; + update_match = .set; + }, + else => {}, } + const node_token = @intFromPtr(ast_node); + if (node_token != self.last_node) { + const ast = ast_node.asSExpressionString(); + _ = self.plane.print("node: {s}\n", .{ast}) catch {}; + syntax.Node.freeSExpressionString(ast); + const parent = ast_node.getParent(); + if (!parent.isNull()) { + const ast_parent = parent.asSExpressionString(); + _ = self.plane.print("parent: {s}\n", .{ast_parent}) catch {}; + syntax.Node.freeSExpressionString(ast_parent); + const sel_parent = self.pos_cache.range_to_selection(parent.getRange(), self.editor.get_current_root() orelse return) orelse return; + var match_parent = ed.Match.from_selection(sel_parent); + if (self.theme) |theme| match_parent.style = .{ .bg = theme.editor_gutter_added.fg }; + switch (update_match) { + .add => (self.editor.matches.addOne() catch return).* = match_parent, + .set => self.editor.matches.items[1] = match_parent, + .no => {}, + } + } + } + self.last_node = @intFromPtr(ast_node); + var buf: [1024]u8 = undefined; const text = self.get_buffer_text(&buf, sel) orelse ""; if (self.editor.style_lookup(self.theme, scope, id)) |token| {