summaryrefslogtreecommitdiff
path: root/src/File.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/File.zig')
-rw-r--r--src/File.zig26
1 files changed, 20 insertions, 6 deletions
diff --git a/src/File.zig b/src/File.zig
index 8ba58fbc..b8368482 100644
--- a/src/File.zig
+++ b/src/File.zig
@@ -6,6 +6,7 @@ const vaxis = @import("vaxis");
const pardes = @import("pardes.zig");
const config = @import("config.zig");
const Pardes = pardes.Pardes;
+const Surface = pardes.Surface;
const modal = @import("modal.zig");
const filesystem = @import("fs.zig");
const syntax = @import("syntax.zig");
@@ -69,9 +70,19 @@ pub const State = struct {
tree_context: bool = false,
context_declarations: []syntax.ContextDeclaration = &.{},
context_revision: ?u32 = null,
+ /// The whole file's parse for the keys that walk its nodes (Alt-o and
+ /// kin), made on the first of them after an edit and kept until the next
+ /// one: `syntax.parseTree`'s, opaque here.
+ node_tree: ?*anyopaque = null,
+ node_tree_revision: u32 = 0,
+ /// helix's object_selections: what Alt-o grew from, for Alt-i to go back
+ /// to; gpa-owned ranges and the primary's index.
+ node_history: std.ArrayList(NodeStep) = .empty,
history: *History,
};
+pub const NodeStep = struct { ranges: []modal.Selection, primary: usize };
+
pub fn dumpPane(
arena: std.mem.Allocator,
pane: *const Pane,
@@ -816,6 +827,9 @@ pub fn deinit(p: *Pardes, pane: *Pane, file: *State) void {
if (file.highlights.len > 0) p.tree_sitter_gpa.free(file.highlights);
locations.freeRows(p.gpa, file.location_rows);
if (file.context_declarations.len > 0) p.tree_sitter_gpa.free(file.context_declarations);
+ if (file.node_tree) |tree| syntax.freeTree(tree);
+ for (file.node_history.items) |step| p.gpa.free(step.ranges);
+ file.node_history.deinit(p.gpa);
for (file.history.undo[0..file.history.undo_len]) |snap| p.gpa.free(snap.content);
for (file.history.redo[0..file.history.redo_len]) |snap| p.gpa.free(snap.content);
p.gpa.destroy(file.history);
@@ -1124,8 +1138,7 @@ fn fillBody(dst: ?[]u8, pane: *Pane, f: *State, width: usize, record_wrap: bool)
return written;
}
-pub fn drawGutter(p: *Pardes, pane: *Pane, r: pardes.Rect, tx: u16, tw: u16, body_h: u16, active: bool) void {
- const s = &p.surface;
+pub fn drawGutter(p: *Pardes, s: *Surface, pane: *Pane, r: pardes.Rect, tx: u16, tw: u16, body_h: u16, active: bool) void {
const prefix_width = gutterWidth(pane);
const goff = pane.scroll();
const gcur = Terminal.gridCursor(pane);
@@ -1176,11 +1189,10 @@ fn synStyle(p: *Pardes, sy: syntax.Syn) ?SynStyle {
/// syntax colors: recolor each content cell from its tree-sitter style byte;
/// content starts after the lineno gutter
-pub fn recolorSyntax(p: *Pardes, pane: *Pane, f: *State, r: pardes.Rect, tx: u16, tw: u16, body_h: u16) void {
+pub fn recolorSyntax(p: *Pardes, s: *Surface, pane: *Pane, f: *State, r: pardes.Rect, tx: u16, tw: u16, body_h: u16) void {
const highlights = if (f.mini) |mini| mini.colors else f.highlights;
const highlight_start = if (f.mini != null) 0 else f.highlight_start;
if (highlights.len == 0 and f.output == null) return;
- const s = &p.surface;
const prefix_width = gutterWidth(pane);
const tz_recolor = tracy.zone(@src(), "synRecolor");
defer tz_recolor.end();
@@ -1255,6 +1267,7 @@ pub fn recolorSyntax(p: *Pardes, pane: *Pane, f: *State, r: pardes.Rect, tx: u16
pub fn drawWrapMarkers(
p: *Pardes,
+ s: *Surface,
pane: *const Pane,
r: pardes.Rect,
tx: u16,
@@ -1268,7 +1281,7 @@ pub fn drawWrapMarkers(
var row: u16 = 0;
while (row + 1 < pane.wrap_n and row + 1 < body_h) : (row += 1) {
if (pane.wrap_line[row + 1] != pane.wrap_line[row]) continue;
- p.surface.set(tx + tw - 1, body_y + row, config.wrap_marker, .{
+ s.set(tx + tw - 1, body_y + row, config.wrap_marker, .{
.fg = .{ .rgb = marker_fg },
.bg = pane_bg,
});
@@ -1277,6 +1290,7 @@ pub fn drawWrapMarkers(
pub fn paintWordSelection(
p: *Pardes,
+ s: *Surface,
pane: *Pane,
r: pardes.Rect,
row: i32,
@@ -1301,7 +1315,7 @@ pub fn paintWordSelection(
const c1 = @as(i32, prefix_width) + displayEndOffset(pane, row, here.at, hi - 1);
var col = @max(@as(i32, prefix_width), c0);
while (col <= c1 and col < @as(i32, tw)) : (col += 1) {
- const cell = p.surface.at(tx + @as(u16, @intCast(col)), body_y + @as(u16, @intCast(vr)));
+ const cell = s.at(tx + @as(u16, @intCast(col)), body_y + @as(u16, @intCast(vr)));
cell.default = false;
cell.style.bg = .{ .rgb = bg };
}