From 128182a4489e9e116108edbaf80e91ffd1d3bae7 Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Fri, 5 Jul 2024 00:33:31 +0200 Subject: [PATCH] refactor(Buffer): remove Plane dependency in Buffer --- build.zig | 16 ++-- src/buffer/Buffer.zig | 175 ++++++++++++++++++----------------- src/buffer/Cursor.zig | 96 +++++++++---------- src/buffer/Selection.zig | 6 +- src/renderer/vaxis/Plane.zig | 19 ++++ src/tui/editor.zig | 144 ++++++++++++++-------------- src/tui/inspector_view.zig | 2 +- 7 files changed, 242 insertions(+), 216 deletions(-) diff --git a/build.zig b/build.zig index 810a86b..61099d0 100644 --- a/build.zig +++ b/build.zig @@ -128,6 +128,13 @@ pub fn build(b: *std.Build) void { .root_source_file = b.path("src/color.zig"), }); + const Buffer_mod = b.createModule(.{ + .root_source_file = b.path("src/buffer/Buffer.zig"), + .imports = &.{ + .{ .name = "cbor", .module = cbor_mod }, + }, + }); + const renderer_mod = b.createModule(.{ .root_source_file = b.path("src/renderer/vaxis/renderer.zig"), .imports = &.{ @@ -136,14 +143,7 @@ pub fn build(b: *std.Build) void { .{ .name = "cbor", .module = cbor_mod }, .{ .name = "log", .module = log_mod }, .{ .name = "thespian", .module = thespian_mod }, - }, - }); - - const Buffer_mod = b.createModule(.{ - .root_source_file = b.path("src/buffer/Buffer.zig"), - .imports = &.{ - .{ .name = "renderer", .module = renderer_mod }, - .{ .name = "cbor", .module = cbor_mod }, + .{ .name = "Buffer", .module = Buffer_mod }, }, }); diff --git a/src/buffer/Buffer.zig b/src/buffer/Buffer.zig index 06331ef..90eb0ea 100644 --- a/src/buffer/Buffer.zig +++ b/src/buffer/Buffer.zig @@ -1,5 +1,4 @@ const std = @import("std"); -const Plane = @import("renderer").Plane; const builtin = @import("builtin"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayList; @@ -17,6 +16,14 @@ pub const View = @import("View.zig"); pub const Selection = @import("Selection.zig"); pub const MetaWriter = std.ArrayList(u8).Writer; +pub const Metrix = struct { + ctx: *const anyopaque, + egc_length: egc_length_func, + egc_chunk_width: egc_chunk_width_func, + pub const egc_length_func = *const fn (ctx: *const anyopaque, egcs: []const u8, colcount: *c_int, abs_col: usize) usize; + pub const egc_chunk_width_func = *const fn (self: *const anyopaque, chunk_: []const u8, abs_col_: usize) usize; +}; + arena: std.heap.ArenaAllocator, a: Allocator, external_a: Allocator, @@ -51,7 +58,7 @@ pub const WalkerMut = struct { pub const stop = WalkerMut{ .keep_walking = false }; pub const found = WalkerMut{ .found = true }; - const F = *const fn (ctx: *anyopaque, leaf: *const Leaf, plane: Plane) WalkerMut; + const F = *const fn (ctx: *anyopaque, leaf: *const Leaf, mtrx: Metrix) WalkerMut; }; pub const Walker = struct { @@ -63,7 +70,7 @@ pub const Walker = struct { pub const stop = Walker{ .keep_walking = false }; pub const found = Walker{ .found = true }; - const F = *const fn (ctx: *anyopaque, leaf: *const Leaf, plane: Plane) Walker; + const F = *const fn (ctx: *anyopaque, leaf: *const Leaf, mtrx: Metrix) Walker; }; pub const Weights = struct { @@ -145,7 +152,7 @@ pub const Leaf = struct { return self.buf.len == 0 and !self.bol and !self.eol; } - fn pos_to_width(self: *const Leaf, pos: *usize, abs_col_: usize, plane: Plane) usize { + fn pos_to_width(self: *const Leaf, pos: *usize, abs_col_: usize, mtrx: Metrix) usize { var col: usize = 0; var abs_col = abs_col_; var cols: c_int = 0; @@ -156,7 +163,7 @@ pub const Leaf = struct { buf = buf[1..]; pos.* -= 1; } else { - const bytes = plane.egc_length(buf, &cols, abs_col); + const bytes = mtrx.egc_length(mtrx.ctx, buf, &cols, abs_col); buf = buf[bytes..]; pos.* -= bytes; } @@ -166,12 +173,12 @@ pub const Leaf = struct { return col; } - fn width(self: *const Leaf, abs_col: usize, plane: Plane) usize { + fn width(self: *const Leaf, abs_col: usize, mtrx: Metrix) usize { var pos: usize = std.math.maxInt(usize); - return self.pos_to_width(&pos, abs_col, plane); + return self.pos_to_width(&pos, abs_col, mtrx); } - inline fn width_to_pos(self: *const Leaf, col_: usize, abs_col_: usize, plane: Plane) !usize { + inline fn width_to_pos(self: *const Leaf, col_: usize, abs_col_: usize, mtrx: Metrix) !usize { var abs_col = abs_col_; var col = col_; var cols: c_int = 0; @@ -179,7 +186,7 @@ pub const Leaf = struct { return while (buf.len > 0) { if (col == 0) break @intFromPtr(buf.ptr) - @intFromPtr(self.buf.ptr); - const bytes = plane.egc_length(buf, &cols, abs_col); + const bytes = mtrx.egc_length(mtrx.ctx, buf, &cols, abs_col); buf = buf[bytes..]; if (col < cols) break @intFromPtr(buf.ptr) - @intFromPtr(self.buf.ptr); @@ -188,20 +195,20 @@ pub const Leaf = struct { } else error.BufferUnderrun; } - inline fn dump(self: *const Leaf, l: *ArrayList(u8), abs_col: usize, plane: Plane) !void { + inline fn dump(self: *const Leaf, l: *ArrayList(u8), abs_col: usize, mtrx: Metrix) !void { var buf: [16]u8 = undefined; - const wcwidth = try std.fmt.bufPrint(&buf, "{d}", .{self.width(abs_col, plane)}); + const wcwidth = try std.fmt.bufPrint(&buf, "{d}", .{self.width(abs_col, mtrx)}); if (self.bol) try l.appendSlice("BOL "); try l.appendSlice(wcwidth); try l.append('"'); - try debug_render_chunk(self.buf, l, plane); + try debug_render_chunk(self.buf, l, mtrx); try l.appendSlice("\" "); if (self.eol) try l.appendSlice("EOL "); } - fn debug_render_chunk(chunk: []const u8, l: *ArrayList(u8), plane: Plane) !void { + fn debug_render_chunk(chunk: []const u8, l: *ArrayList(u8), mtrx: Metrix) !void { var cols: c_int = 0; var buf = chunk; while (buf.len > 0) { @@ -212,7 +219,7 @@ pub const Leaf = struct { buf = buf[1..]; }, else => { - const bytes = plane.egc_length(buf, &cols, 0); + const bytes = mtrx.egc_length(mtrx.ctx, buf, &cols, 0); var buf_: [4096]u8 = undefined; try l.appendSlice(try std.fmt.bufPrint(&buf_, "{s}", .{std.fmt.fmtSliceEscapeLower(buf[0..bytes])})); buf = buf[bytes..]; @@ -314,27 +321,27 @@ const Node = union(enum) { return leaves.toOwnedSlice(); } - fn walk_const(self: *const Node, f: Walker.F, ctx: *anyopaque, plane: Plane) Walker { + fn walk_const(self: *const Node, f: Walker.F, ctx: *anyopaque, mtrx: Metrix) Walker { switch (self.*) { .node => |*node| { - const left = node.left.walk_const(f, ctx, plane); + const left = node.left.walk_const(f, ctx, mtrx); if (!left.keep_walking) { var result = Walker{}; result.err = left.err; result.found = left.found; return result; } - const right = node.right.walk_const(f, ctx, plane); + const right = node.right.walk_const(f, ctx, mtrx); return node.merge_results_const(left, right); }, - .leaf => |*l| return f(ctx, l, plane), + .leaf => |*l| return f(ctx, l, mtrx), } } - fn walk(self: *const Node, a: Allocator, f: WalkerMut.F, ctx: *anyopaque, plane: Plane) WalkerMut { + fn walk(self: *const Node, a: Allocator, f: WalkerMut.F, ctx: *anyopaque, mtrx: Metrix) WalkerMut { switch (self.*) { .node => |*node| { - const left = node.left.walk(a, f, ctx, plane); + const left = node.left.walk(a, f, ctx, mtrx); if (!left.keep_walking) { var result = WalkerMut{}; result.err = left.err; @@ -344,26 +351,26 @@ const Node = union(enum) { } return result; } - const right = node.right.walk(a, f, ctx, plane); + const right = node.right.walk(a, f, ctx, mtrx); return node.merge_results(a, left, right); }, - .leaf => |*l| return f(ctx, l, plane), + .leaf => |*l| return f(ctx, l, mtrx), } } - fn walk_from_line_begin_const_internal(self: *const Node, line: usize, f: Walker.F, ctx: *anyopaque, plane: Plane) Walker { + fn walk_from_line_begin_const_internal(self: *const Node, line: usize, f: Walker.F, ctx: *anyopaque, mtrx: Metrix) Walker { switch (self.*) { .node => |*node| { const left_bols = node.weights.bols; if (line >= left_bols) - return node.right.walk_from_line_begin_const_internal(line - left_bols, f, ctx, plane); - const left_result = node.left.walk_from_line_begin_const_internal(line, f, ctx, plane); - const right_result = if (left_result.found and left_result.keep_walking) node.right.walk_const(f, ctx, plane) else Walker{}; + return node.right.walk_from_line_begin_const_internal(line - left_bols, f, ctx, mtrx); + const left_result = node.left.walk_from_line_begin_const_internal(line, f, ctx, mtrx); + const right_result = if (left_result.found and left_result.keep_walking) node.right.walk_const(f, ctx, mtrx) else Walker{}; return node.merge_results_const(left_result, right_result); }, .leaf => |*l| { if (line == 0) { - var result = f(ctx, l, plane); + var result = f(ctx, l, mtrx); if (result.err) |_| return result; result.found = true; return result; @@ -373,18 +380,18 @@ const Node = union(enum) { } } - pub fn walk_from_line_begin_const(self: *const Node, line: usize, f: Walker.F, ctx: *anyopaque, plane: Plane) !bool { - const result = self.walk_from_line_begin_const_internal(line, f, ctx, plane); + pub fn walk_from_line_begin_const(self: *const Node, line: usize, f: Walker.F, ctx: *anyopaque, mtrx: Metrix) !bool { + const result = self.walk_from_line_begin_const_internal(line, f, ctx, mtrx); if (result.err) |e| return e; return result.found; } - fn walk_from_line_begin_internal(self: *const Node, a: Allocator, line: usize, f: WalkerMut.F, ctx: *anyopaque, plane: Plane) WalkerMut { + fn walk_from_line_begin_internal(self: *const Node, a: Allocator, line: usize, f: WalkerMut.F, ctx: *anyopaque, mtrx: Metrix) WalkerMut { switch (self.*) { .node => |*node| { const left_bols = node.weights.bols; if (line >= left_bols) { - const right_result = node.right.walk_from_line_begin_internal(a, line - left_bols, f, ctx, plane); + const right_result = node.right.walk_from_line_begin_internal(a, line - left_bols, f, ctx, mtrx); if (right_result.replace) |p| { var result = WalkerMut{}; result.err = right_result.err; @@ -399,13 +406,13 @@ const Node = union(enum) { return right_result; } } - const left_result = node.left.walk_from_line_begin_internal(a, line, f, ctx, plane); - const right_result = if (left_result.found and left_result.keep_walking) node.right.walk(a, f, ctx, plane) else WalkerMut{}; + const left_result = node.left.walk_from_line_begin_internal(a, line, f, ctx, mtrx); + const right_result = if (left_result.found and left_result.keep_walking) node.right.walk(a, f, ctx, mtrx) else WalkerMut{}; return node.merge_results(a, left_result, right_result); }, .leaf => |*l| { if (line == 0) { - var result = f(ctx, l, plane); + var result = f(ctx, l, mtrx); if (result.err) |_| { result.replace = null; return result; @@ -418,8 +425,8 @@ const Node = union(enum) { } } - pub fn walk_from_line_begin(self: *const Node, a: Allocator, line: usize, f: WalkerMut.F, ctx: *anyopaque, plane: Plane) !struct { bool, ?Root } { - const result = self.walk_from_line_begin_internal(a, line, f, ctx, plane); + pub fn walk_from_line_begin(self: *const Node, a: Allocator, line: usize, f: WalkerMut.F, ctx: *anyopaque, mtrx: Metrix) !struct { bool, ?Root } { + const result = self.walk_from_line_begin_internal(a, line, f, ctx, mtrx); if (result.err) |e| return e; return .{ result.found, result.replace }; } @@ -459,27 +466,27 @@ const Node = union(enum) { } } - const EgcF = *const fn (ctx: *anyopaque, egc: []const u8, wcwidth: usize, plane: Plane) Walker; + const EgcF = *const fn (ctx: *anyopaque, egc: []const u8, wcwidth: usize, mtrx: Metrix) Walker; - pub fn walk_egc_forward(self: *const Node, line: usize, walker_f: EgcF, walker_ctx: *anyopaque, plane_: Plane) !void { + pub fn walk_egc_forward(self: *const Node, line: usize, walker_f: EgcF, walker_ctx: *anyopaque, mtrx_: Metrix) !void { const Ctx = struct { walker_f: EgcF, walker_ctx: @TypeOf(walker_ctx), abs_col: usize = 0, - fn walker(ctx_: *anyopaque, leaf: *const Self.Leaf, plane: Plane) Walker { + fn walker(ctx_: *anyopaque, leaf: *const Self.Leaf, mtrx: Metrix) Walker { const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_))); var buf: []const u8 = leaf.buf; while (buf.len > 0) { var cols: c_int = undefined; - const bytes = plane.egc_length(buf, &cols, ctx.abs_col); - const ret = ctx.walker_f(ctx.walker_ctx, buf[0..bytes], @intCast(cols), plane); + const bytes = mtrx.egc_length(mtrx.ctx, buf, &cols, ctx.abs_col); + const ret = ctx.walker_f(ctx.walker_ctx, buf[0..bytes], @intCast(cols), mtrx); if (ret.err) |e| return .{ .err = e }; buf = buf[bytes..]; ctx.abs_col += @intCast(cols); if (!ret.keep_walking) return Walker.stop; } if (leaf.eol) { - const ret = ctx.walker_f(ctx.walker_ctx, "\n", 1, plane); + const ret = ctx.walker_f(ctx.walker_ctx, "\n", 1, mtrx); if (ret.err) |e| return .{ .err = e }; if (!ret.keep_walking) return Walker.stop; ctx.abs_col = 0; @@ -488,16 +495,16 @@ const Node = union(enum) { } }; var ctx: Ctx = .{ .walker_f = walker_f, .walker_ctx = walker_ctx }; - const found = try self.walk_from_line_begin_const(line, Ctx.walker, &ctx, plane_); + const found = try self.walk_from_line_begin_const(line, Ctx.walker, &ctx, mtrx_); if (!found) return error.NotFound; } - pub fn ecg_at(self: *const Node, line: usize, col: usize, plane: Plane) error{NotFound}!struct { []const u8, usize, usize } { + pub fn ecg_at(self: *const Node, line: usize, col: usize, mtrx: Metrix) error{NotFound}!struct { []const u8, usize, usize } { const ctx_ = struct { col: usize, at: ?[]const u8 = null, wcwidth: usize = 0, - fn walker(ctx_: *anyopaque, egc: []const u8, wcwidth: usize, _: Plane) Walker { + fn walker(ctx_: *anyopaque, egc: []const u8, wcwidth: usize, _: Metrix) Walker { const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_))); ctx.at = egc; ctx.wcwidth = wcwidth; @@ -508,20 +515,20 @@ const Node = union(enum) { } }; var ctx: ctx_ = .{ .col = col }; - self.walk_egc_forward(line, ctx_.walker, &ctx, plane) catch return .{ "?", 1, 0 }; + self.walk_egc_forward(line, ctx_.walker, &ctx, mtrx) catch return .{ "?", 1, 0 }; return if (ctx.at) |at| .{ at, ctx.wcwidth, ctx.col } else error.NotFound; } - pub fn test_at(self: *const Node, pred: *const fn (c: []const u8) bool, line: usize, col: usize, plane: Plane) bool { - const ecg, _, _ = self.ecg_at(line, col, plane) catch return false; + pub fn test_at(self: *const Node, pred: *const fn (c: []const u8) bool, line: usize, col: usize, mtrx: Metrix) bool { + const ecg, _, _ = self.ecg_at(line, col, mtrx) catch return false; return pred(ecg); } - pub fn get_line_width_map(self: *const Node, line: usize, map: *ArrayList(usize), plane: Plane) error{ Stop, NoSpaceLeft }!void { + pub fn get_line_width_map(self: *const Node, line: usize, map: *ArrayList(usize), mtrx: Metrix) error{ Stop, NoSpaceLeft }!void { const Ctx = struct { map: *ArrayList(usize), wcwidth: usize = 0, - fn walker(ctx_: *anyopaque, egc: []const u8, wcwidth: usize, _: Plane) Walker { + fn walker(ctx_: *anyopaque, egc: []const u8, wcwidth: usize, _: Metrix) Walker { const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_))); var n = egc.len; while (n > 0) : (n -= 1) { @@ -533,20 +540,20 @@ const Node = union(enum) { } }; var ctx: Ctx = .{ .map = map }; - self.walk_egc_forward(line, Ctx.walker, &ctx, plane) catch |e| return switch (e) { + self.walk_egc_forward(line, Ctx.walker, &ctx, mtrx) catch |e| return switch (e) { error.NoSpaceLeft => error.NoSpaceLeft, else => error.Stop, }; } - pub fn get_range(self: *const Node, sel: Selection, copy_buf: ?[]u8, size: ?*usize, wcwidth_: ?*usize, plane_: Plane) error{ Stop, NoSpaceLeft }!?[]u8 { + pub fn get_range(self: *const Node, sel: Selection, copy_buf: ?[]u8, size: ?*usize, wcwidth_: ?*usize, mtrx_: Metrix) error{ Stop, NoSpaceLeft }!?[]u8 { const Ctx = struct { col: usize = 0, sel: Selection, out: ?[]u8, bytes: usize = 0, wcwidth: usize = 0, - fn walker(ctx_: *anyopaque, egc: []const u8, wcwidth: usize, _: Plane) Walker { + fn walker(ctx_: *anyopaque, egc: []const u8, wcwidth: usize, _: Metrix) Walker { const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_))); if (ctx.col < ctx.sel.begin.col) { ctx.col += wcwidth; @@ -579,7 +586,7 @@ const Node = union(enum) { ctx.sel.normalize(); if (ctx.sel.begin.eql(ctx.sel.end)) return error.Stop; - self.walk_egc_forward(ctx.sel.begin.row, Ctx.walker, &ctx, plane_) catch |e| return switch (e) { + self.walk_egc_forward(ctx.sel.begin.row, Ctx.walker, &ctx, mtrx_) catch |e| return switch (e) { error.NoSpaceLeft => error.NoSpaceLeft, else => error.Stop, }; @@ -588,20 +595,20 @@ const Node = union(enum) { return if (copy_buf) |buf_| buf_[0..ctx.bytes] else null; } - pub fn delete_range(self: *const Node, sel: Selection, a: Allocator, size: ?*usize, plane: Plane) error{Stop}!Root { + pub fn delete_range(self: *const Node, sel: Selection, a: Allocator, size: ?*usize, mtrx: Metrix) error{Stop}!Root { var wcwidth: usize = 0; - _ = self.get_range(sel, null, size, &wcwidth, plane) catch return error.Stop; - return self.del_chars(sel.begin.row, sel.begin.col, wcwidth, a, plane) catch return error.Stop; + _ = self.get_range(sel, null, size, &wcwidth, mtrx) catch return error.Stop; + return self.del_chars(sel.begin.row, sel.begin.col, wcwidth, a, mtrx) catch return error.Stop; } - pub fn del_chars(self: *const Node, line: usize, col: usize, count: usize, a: Allocator, plane_: Plane) !Root { + pub fn del_chars(self: *const Node, line: usize, col: usize, count: usize, a: Allocator, mtrx_: Metrix) !Root { const Ctx = struct { a: Allocator, col: usize, abs_col: usize = 0, count: usize, delete_next_bol: bool = false, - fn walker(Ctx: *anyopaque, leaf: *const Leaf, plane: Plane) WalkerMut { + fn walker(Ctx: *anyopaque, leaf: *const Leaf, mtrx: Metrix) WalkerMut { const ctx = @as(*@This(), @ptrCast(@alignCast(Ctx))); var result = WalkerMut.keep_walking; if (ctx.delete_next_bol and ctx.count == 0) { @@ -610,7 +617,7 @@ const Node = union(enum) { ctx.delete_next_bol = false; return result; } - const leaf_wcwidth = leaf.width(ctx.abs_col, plane); + const leaf_wcwidth = leaf.width(ctx.abs_col, mtrx); const leaf_bol = leaf.bol and !ctx.delete_next_bol; ctx.delete_next_bol = false; const base_col = ctx.abs_col; @@ -634,7 +641,7 @@ const Node = union(enum) { result.replace = Leaf.new(ctx.a, "", leaf_bol, leaf.eol) catch |e| return .{ .err = e }; ctx.count = 0; } else { - const pos = leaf.width_to_pos(ctx.count, base_col, plane) catch |e| return .{ .err = e }; + const pos = leaf.width_to_pos(ctx.count, base_col, mtrx) catch |e| return .{ .err = e }; result.replace = Leaf.new(ctx.a, leaf.buf[pos..], leaf_bol, leaf.eol) catch |e| return .{ .err = e }; ctx.count = 0; } @@ -648,7 +655,7 @@ const Node = union(enum) { } else { if (ctx.col + ctx.count >= leaf_wcwidth) { ctx.count -= leaf_wcwidth - ctx.col; - const pos = leaf.width_to_pos(ctx.col, base_col, plane) catch |e| return .{ .err = e }; + const pos = leaf.width_to_pos(ctx.col, base_col, mtrx) catch |e| return .{ .err = e }; const leaf_eol = if (leaf.eol and ctx.count > 0) leaf_eol: { ctx.count -= 1; ctx.delete_next_bol = true; @@ -657,8 +664,8 @@ const Node = union(enum) { result.replace = Leaf.new(ctx.a, leaf.buf[0..pos], leaf_bol, leaf_eol) catch |e| return .{ .err = e }; ctx.col = 0; } else { - const pos = leaf.width_to_pos(ctx.col, base_col, plane) catch |e| return .{ .err = e }; - const pos_end = leaf.width_to_pos(ctx.col + ctx.count, base_col, plane) catch |e| return .{ .err = e }; + const pos = leaf.width_to_pos(ctx.col, base_col, mtrx) catch |e| return .{ .err = e }; + const pos_end = leaf.width_to_pos(ctx.col + ctx.count, base_col, mtrx) catch |e| return .{ .err = e }; const left = Leaf.new(ctx.a, leaf.buf[0..pos], leaf_bol, false) catch |e| return .{ .err = e }; const right = Leaf.new(ctx.a, leaf.buf[pos_end..], false, leaf.eol) catch |e| return .{ .err = e }; result.replace = Node.new(ctx.a, left, right) catch |e| return .{ .err = e }; @@ -672,7 +679,7 @@ const Node = union(enum) { } }; var ctx: Ctx = .{ .a = a, .col = col, .count = count }; - const found, const root = try self.walk_from_line_begin(a, line, Ctx.walker, &ctx, plane_); + const found, const root = try self.walk_from_line_begin(a, line, Ctx.walker, &ctx, mtrx_); return if (found) (if (root) |r| r else error.Stop) else error.NotFound; } @@ -702,32 +709,32 @@ const Node = union(enum) { return if (!found) error.NotFound; } - pub fn line_width(self: *const Node, line: usize, plane_: Plane) !usize { + pub fn line_width(self: *const Node, line: usize, mtrx_: Metrix) !usize { const do = struct { result: usize = 0, - fn walker(ctx: *anyopaque, leaf: *const Leaf, plane: Plane) Walker { + fn walker(ctx: *anyopaque, leaf: *const Leaf, mtrx: Metrix) Walker { const do = @as(*@This(), @ptrCast(@alignCast(ctx))); - do.result += leaf.width(do.result, plane); + do.result += leaf.width(do.result, mtrx); return if (!leaf.eol) Walker.keep_walking else Walker.stop; } }; var ctx: do = .{}; - const found = self.walk_from_line_begin_const(line, do.walker, &ctx, plane_) catch true; + const found = self.walk_from_line_begin_const(line, do.walker, &ctx, mtrx_) catch true; return if (found) ctx.result else error.NotFound; } - pub fn pos_to_width(self: *const Node, line: usize, pos: usize, plane_: Plane) !usize { + pub fn pos_to_width(self: *const Node, line: usize, pos: usize, mtrx_: Metrix) !usize { const do = struct { result: usize = 0, pos: usize, - fn walker(ctx: *anyopaque, leaf: *const Leaf, plane: Plane) Walker { + fn walker(ctx: *anyopaque, leaf: *const Leaf, mtrx: Metrix) Walker { const do = @as(*@This(), @ptrCast(@alignCast(ctx))); - do.result += leaf.pos_to_width(&do.pos, do.result, plane); + do.result += leaf.pos_to_width(&do.pos, do.result, mtrx); return if (!(leaf.eol or do.pos == 0)) Walker.keep_walking else Walker.stop; } }; var ctx: do = .{ .pos = pos }; - const found = self.walk_from_line_begin_const(line, do.walker, &ctx, plane_) catch true; + const found = self.walk_from_line_begin_const(line, do.walker, &ctx, mtrx_) catch true; return if (found) ctx.result else error.NotFound; } @@ -737,7 +744,7 @@ const Node = union(enum) { col_: usize, s: []const u8, a: Allocator, - plane_: Plane, + mtrx_: Metrix, ) !struct { usize, usize, Root } { var self = self_; const Ctx = struct { @@ -747,9 +754,9 @@ const Node = union(enum) { s: []const u8, eol: bool, - fn walker(ctx: *anyopaque, leaf: *const Leaf, plane: Plane) WalkerMut { + fn walker(ctx: *anyopaque, leaf: *const Leaf, mtrx: Metrix) WalkerMut { const Ctx = @as(*@This(), @ptrCast(@alignCast(ctx))); - const leaf_wcwidth = leaf.width(Ctx.abs_col, plane); + const leaf_wcwidth = leaf.width(Ctx.abs_col, mtrx); const base_col = Ctx.abs_col; Ctx.abs_col += leaf_wcwidth; @@ -781,7 +788,7 @@ const Node = union(enum) { } if (leaf_wcwidth > Ctx.col) { - const pos = leaf.width_to_pos(Ctx.col, base_col, plane) catch |e| return .{ .err = e }; + const pos = leaf.width_to_pos(Ctx.col, base_col, mtrx) catch |e| return .{ .err = e }; if (Ctx.eol and Ctx.s.len == 0) { const left = Leaf.new(Ctx.a, leaf.buf[0..pos], leaf.bol, Ctx.eol) catch |e| return .{ .err = e }; const right = Leaf.new(Ctx.a, leaf.buf[pos..], Ctx.eol, leaf.eol) catch |e| return .{ .err = e }; @@ -818,14 +825,14 @@ const Node = union(enum) { need_eol = false; } var ctx: Ctx = .{ .a = a, .col = col, .s = chunk, .eol = need_eol }; - const found, const replace = try self.walk_from_line_begin(a, line, Ctx.walker, &ctx, plane_); + const found, const replace = try self.walk_from_line_begin(a, line, Ctx.walker, &ctx, mtrx_); if (!found) return error.NotFound; if (replace) |root| self = root; if (need_eol) { line += 1; col = 0; } else { - col += plane_.egc_chunk_width(chunk, col); + col += mtrx_.egc_chunk_width(mtrx_.ctx, chunk, col); } } return .{ line, col, self }; @@ -918,19 +925,19 @@ const Node = union(enum) { return self.store(ctx.writer()); } - pub fn debug_render_chunks(self: *const Node, line: usize, output: *ArrayList(u8), plane_: Plane) !void { + pub fn debug_render_chunks(self: *const Node, line: usize, output: *ArrayList(u8), mtrx_: Metrix) !void { const ctx_ = struct { l: *ArrayList(u8), wcwidth: usize = 0, - fn walker(ctx_: *anyopaque, leaf: *const Leaf, plane: Plane) Walker { + fn walker(ctx_: *anyopaque, leaf: *const Leaf, mtrx: Metrix) Walker { const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_))); - leaf.dump(ctx.l, ctx.wcwidth, plane) catch |e| return .{ .err = e }; - ctx.wcwidth += leaf.width(ctx.wcwidth, plane); + leaf.dump(ctx.l, ctx.wcwidth, mtrx) catch |e| return .{ .err = e }; + ctx.wcwidth += leaf.width(ctx.wcwidth, mtrx); return if (!leaf.eol) Walker.keep_walking else Walker.stop; } }; var ctx: ctx_ = .{ .l = output }; - const found = self.walk_from_line_begin_const(line, ctx_.walker, &ctx, plane_) catch true; + const found = self.walk_from_line_begin_const(line, ctx_.walker, &ctx, mtrx_) catch true; if (!found) return error.NotFound; var buf: [16]u8 = undefined; diff --git a/src/buffer/Cursor.zig b/src/buffer/Cursor.zig index 7f04fa0..f6c3129 100644 --- a/src/buffer/Cursor.zig +++ b/src/buffer/Cursor.zig @@ -1,9 +1,9 @@ const std = @import("std"); const cbor = @import("cbor"); -const Plane = @import("renderer").Plane; const Buffer = @import("Buffer.zig"); const View = @import("View.zig"); const Selection = @import("Selection.zig"); +const Metrix = Buffer.Metrix; row: usize = 0, col: usize = 0, @@ -27,20 +27,20 @@ pub inline fn right_of(self: Self, other: Self) bool { return if (self.row > other.row) true else if (self.row == other.row and self.col > other.col) true else false; } -pub fn clamp_to_buffer(self: *Self, root: Buffer.Root, plane: Plane) void { +pub fn clamp_to_buffer(self: *Self, root: Buffer.Root, mtrx: Metrix) void { self.row = @min(self.row, root.lines() - 1); - self.col = @min(self.col, root.line_width(self.row, plane) catch 0); + self.col = @min(self.col, root.line_width(self.row, mtrx) catch 0); } -fn follow_target(self: *Self, root: Buffer.Root, plane: Plane) void { - self.col = @min(self.target, root.line_width(self.row, plane) catch 0); +fn follow_target(self: *Self, root: Buffer.Root, mtrx: Metrix) void { + self.col = @min(self.target, root.line_width(self.row, mtrx) catch 0); } -fn move_right_no_target(self: *Self, root: Buffer.Root, plane: Plane) !void { +fn move_right_no_target(self: *Self, root: Buffer.Root, mtrx: Metrix) !void { const lines = root.lines(); if (lines <= self.row) return error.Stop; - if (self.col < root.line_width(self.row, plane) catch 0) { - _, const wcwidth, const offset = root.ecg_at(self.row, self.col, plane) catch return error.Stop; + if (self.col < root.line_width(self.row, mtrx) catch 0) { + _, const wcwidth, const offset = root.ecg_at(self.row, self.col, mtrx) catch return error.Stop; self.col += wcwidth - offset; } else if (self.row < lines - 1) { self.col = 0; @@ -48,73 +48,73 @@ fn move_right_no_target(self: *Self, root: Buffer.Root, plane: Plane) !void { } else return error.Stop; } -pub fn move_right(self: *Self, root: Buffer.Root, plane: Plane) !void { - try self.move_right_no_target(root, plane); +pub fn move_right(self: *Self, root: Buffer.Root, mtrx: Metrix) !void { + try self.move_right_no_target(root, mtrx); self.target = self.col; } -fn move_left_no_target(self: *Self, root: Buffer.Root, plane: Plane) !void { +fn move_left_no_target(self: *Self, root: Buffer.Root, mtrx: Metrix) !void { if (self.col == 0) { if (self.row == 0) return error.Stop; self.row -= 1; - self.col = root.line_width(self.row, plane) catch 0; + self.col = root.line_width(self.row, mtrx) catch 0; } else { - _, const wcwidth, _ = root.ecg_at(self.row, self.col - 1, plane) catch return error.Stop; + _, const wcwidth, _ = root.ecg_at(self.row, self.col - 1, mtrx) catch return error.Stop; if (self.col > wcwidth) self.col -= wcwidth else self.col = 0; } } -pub fn move_left(self: *Self, root: Buffer.Root, plane: Plane) !void { - try self.move_left_no_target(root, plane); +pub fn move_left(self: *Self, root: Buffer.Root, mtrx: Metrix) !void { + try self.move_left_no_target(root, mtrx); self.target = self.col; } -pub fn move_up(self: *Self, root: Buffer.Root, plane: Plane) !void { +pub fn move_up(self: *Self, root: Buffer.Root, mtrx: Metrix) !void { if (self.row > 0) { self.row -= 1; - self.follow_target(root, plane); - self.move_left_no_target(root, plane) catch return; - try self.move_right_no_target(root, plane); + self.follow_target(root, mtrx); + self.move_left_no_target(root, mtrx) catch return; + try self.move_right_no_target(root, mtrx); } else return error.Stop; } -pub fn move_down(self: *Self, root: Buffer.Root, plane: Plane) !void { +pub fn move_down(self: *Self, root: Buffer.Root, mtrx: Metrix) !void { if (self.row < root.lines() - 1) { self.row += 1; - self.follow_target(root, plane); - self.move_left_no_target(root, plane) catch return; - try self.move_right_no_target(root, plane); + self.follow_target(root, mtrx); + self.move_left_no_target(root, mtrx) catch return; + try self.move_right_no_target(root, mtrx); } else return error.Stop; } -pub fn move_page_up(self: *Self, root: Buffer.Root, view: *const View, plane: Plane) void { +pub fn move_page_up(self: *Self, root: Buffer.Root, view: *const View, mtrx: Metrix) void { self.row = if (self.row > view.rows) self.row - view.rows else 0; - self.follow_target(root, plane); - self.move_left_no_target(root, plane) catch return; - self.move_right_no_target(root, plane) catch return; + self.follow_target(root, mtrx); + self.move_left_no_target(root, mtrx) catch return; + self.move_right_no_target(root, mtrx) catch return; } -pub fn move_page_down(self: *Self, root: Buffer.Root, view: *const View, plane: Plane) void { +pub fn move_page_down(self: *Self, root: Buffer.Root, view: *const View, mtrx: Metrix) void { if (root.lines() > self.row + view.rows) { self.row += view.rows; - } else self.move_buffer_last(root, plane); - self.follow_target(root, plane); - self.move_left_no_target(root, plane) catch return; - self.move_right_no_target(root, plane) catch return; + } else self.move_buffer_last(root, mtrx); + self.follow_target(root, mtrx); + self.move_left_no_target(root, mtrx) catch return; + self.move_right_no_target(root, mtrx) catch return; } -pub fn move_to(self: *Self, root: Buffer.Root, row: usize, col: usize, plane: Plane) !void { +pub fn move_to(self: *Self, root: Buffer.Root, row: usize, col: usize, mtrx: Metrix) !void { if (row < root.lines()) { self.row = row; - self.col = @min(col, root.line_width(self.row, plane) catch return error.Stop); + self.col = @min(col, root.line_width(self.row, mtrx) catch return error.Stop); self.target = self.col; } else return error.Stop; } -pub fn move_abs(self: *Self, root: Buffer.Root, v: *View, y: usize, x: usize, plane: Plane) !void { +pub fn move_abs(self: *Self, root: Buffer.Root, v: *View, y: usize, x: usize, mtrx: Metrix) !void { self.row = v.row + y; self.col = v.col + x; - self.clamp_to_buffer(root, plane); + self.clamp_to_buffer(root, mtrx); self.target = self.col; } @@ -123,8 +123,8 @@ pub fn move_begin(self: *Self) void { self.target = self.col; } -pub fn move_end(self: *Self, root: Buffer.Root, plane: Plane) void { - if (self.row < root.lines()) self.col = root.line_width(self.row, plane) catch 0; +pub fn move_end(self: *Self, root: Buffer.Root, mtrx: Metrix) void { + if (self.row < root.lines()) self.col = root.line_width(self.row, mtrx) catch 0; self.target = std.math.maxInt(u32); } @@ -134,32 +134,32 @@ pub fn move_buffer_begin(self: *Self) void { self.target = 0; } -pub fn move_buffer_end(self: *Self, root: Buffer.Root, plane: Plane) void { +pub fn move_buffer_end(self: *Self, root: Buffer.Root, mtrx: Metrix) void { self.row = root.lines() - 1; - self.move_end(root, plane); + self.move_end(root, mtrx); if (self.col == 0) self.target = 0; } -fn move_buffer_first(self: *Self, root: Buffer.Root, plane: Plane) void { +fn move_buffer_first(self: *Self, root: Buffer.Root, mtrx: Metrix) void { self.row = 0; - self.follow_target(root, plane); + self.follow_target(root, mtrx); } -fn move_buffer_last(self: *Self, root: Buffer.Root, plane: Plane) void { +fn move_buffer_last(self: *Self, root: Buffer.Root, mtrx: Metrix) void { self.row = root.lines() - 1; - self.follow_target(root, plane); + self.follow_target(root, mtrx); } fn is_at_begin(self: *const Self) bool { return self.col == 0; } -fn is_at_end(self: *const Self, root: Buffer.Root, plane: Plane) bool { - return if (self.row < root.lines()) self.col == root.line_width(self.row, plane) catch 0 else true; +fn is_at_end(self: *const Self, root: Buffer.Root, mtrx: Metrix) bool { + return if (self.row < root.lines()) self.col == root.line_width(self.row, mtrx) catch 0 else true; } -pub fn test_at(self: *const Self, root: Buffer.Root, pred: *const fn (c: []const u8) bool, plane: Plane) bool { - return root.test_at(pred, self.row, self.col, plane); +pub fn test_at(self: *const Self, root: Buffer.Root, pred: *const fn (c: []const u8) bool, mtrx: Metrix) bool { + return root.test_at(pred, self.row, self.col, mtrx); } pub fn write(self: *const Self, writer: Buffer.MetaWriter) !void { diff --git a/src/buffer/Selection.zig b/src/buffer/Selection.zig index 26e142f..a1f4541 100644 --- a/src/buffer/Selection.zig +++ b/src/buffer/Selection.zig @@ -16,12 +16,12 @@ pub fn from_cursor(cursor: *const Cursor) Self { return .{ .begin = cursor.*, .end = cursor.* }; } -pub fn line_from_cursor(cursor: Cursor, root: Buffer.Root, plane: Plane) Self { +pub fn line_from_cursor(cursor: Cursor, root: Buffer.Root, mtrx: Buffer.Metrix) Self { var begin = cursor; var end = cursor; begin.move_begin(); - end.move_end(root, plane); - end.move_right(root, plane) catch {}; + end.move_end(root, mtrx); + end.move_right(root, mtrx) catch {}; return .{ .begin = begin, .end = end }; } diff --git a/src/renderer/vaxis/Plane.zig b/src/renderer/vaxis/Plane.zig index 60f1c6a..1fe2bed 100644 --- a/src/renderer/vaxis/Plane.zig +++ b/src/renderer/vaxis/Plane.zig @@ -4,6 +4,7 @@ const FontStyle = @import("theme").FontStyle; const StyleBits = @import("style.zig").StyleBits; const Cell = @import("Cell.zig"); const vaxis = @import("vaxis"); +const Buffer = @import("Buffer"); const Plane = @This(); @@ -364,6 +365,24 @@ pub fn egc_chunk_width(self: *const Plane, chunk_: []const u8, abs_col_: usize) return colcount; } +pub fn metrix(self: *const Plane) Buffer.Metrix { + return .{ + .ctx = self, + .egc_length = struct { + fn f(ctx: *const anyopaque, egcs: []const u8, colcount: *c_int, abs_col: usize) usize { + const self_: *const Plane = @ptrCast(@alignCast(ctx)); + return self_.egc_length(egcs, colcount, abs_col); + } + }.f, + .egc_chunk_width = struct { + fn f(ctx: *const anyopaque, chunk_: []const u8, abs_col_: usize) usize { + const self_: *const Plane = @ptrCast(@alignCast(ctx)); + return self_.egc_chunk_width(chunk_, abs_col_); + } + }.f, + }; +} + const GraphemeCache = struct { buf: [1024 * 16]u8 = undefined, idx: usize = 0, diff --git a/src/tui/editor.zig b/src/tui/editor.zig index 5a8db21..e672d09 100644 --- a/src/tui/editor.zig +++ b/src/tui/editor.zig @@ -109,8 +109,8 @@ pub const CurSel = struct { sel.normalize(); sel.begin.move_begin(); if (!(sel.end.row > sel.begin.row and sel.end.col == 0)) { - sel.end.move_end(root, plane); - sel.end.move_right(root, plane) catch {}; + sel.end.move_end(root, plane.metrix()); + sel.end.move_right(root, plane.metrix()) catch {}; } return sel; } @@ -560,7 +560,7 @@ pub const Editor = struct { fn find_first_non_ws(root: Buffer.Root, row: usize, plane: Plane) usize { const Ctx = struct { col: usize = 0, - fn walker(ctx_: *anyopaque, egc: []const u8, wcwidth: usize, _: Plane) Buffer.Walker { + fn walker(ctx_: *anyopaque, egc: []const u8, wcwidth: usize, _: Buffer.Metrix) Buffer.Walker { const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_))); if (egc[0] == ' ' or egc[0] == '\t') { ctx.col += wcwidth; @@ -570,7 +570,7 @@ pub const Editor = struct { } }; var ctx: Ctx = .{}; - root.walk_egc_forward(row, Ctx.walker, &ctx, plane) catch return 0; + root.walk_egc_forward(row, Ctx.walker, &ctx, plane.metrix()) catch return 0; return ctx.col; } @@ -590,7 +590,7 @@ pub const Editor = struct { sel: Selection, writer: Writer, wcwidth: usize = 0, - fn walker(ctx_: *anyopaque, egc: []const u8, wcwidth: usize, _: Plane) Buffer.Walker { + fn walker(ctx_: *anyopaque, egc: []const u8, wcwidth: usize, _: Buffer.Metrix) Buffer.Walker { const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_))); if (ctx.col < ctx.sel.begin.col) { ctx.col += wcwidth; @@ -617,7 +617,7 @@ pub const Editor = struct { ctx.sel.normalize(); if (sel.begin.eql(sel.end)) return; - root.walk_egc_forward(sel.begin.row, Ctx.walker, &ctx, plane_) catch |e| return map_error(e, @errorReturnTrace()); + root.walk_egc_forward(sel.begin.row, Ctx.walker, &ctx, plane_.metrix()) catch |e| return map_error(e, @errorReturnTrace()); if (wcwidth_) |p| p.* = ctx.wcwidth; } @@ -657,7 +657,7 @@ pub const Editor = struct { theme: *const Widget.Theme, hl_row: ?usize, - fn walker(ctx_: *anyopaque, leaf: *const Buffer.Leaf, _: Plane) Buffer.Walker { + fn walker(ctx_: *anyopaque, leaf: *const Buffer.Leaf, _: Buffer.Metrix) Buffer.Walker { const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_))); const self_ = ctx.self; const view = self_.view; @@ -750,7 +750,7 @@ pub const Editor = struct { if (hl_row) |_| self.render_line_highlight(&self.get_primary().cursor, theme) catch {}; self.plane.home(); - _ = root.walk_from_line_begin_const(self.view.row, ctx.walker, &ctx_, self.plane) catch {}; + _ = root.walk_from_line_begin_const(self.view.row, ctx.walker, &ctx_, self.plane.metrix()) catch {}; } self.render_syntax(theme, cache, root) catch {}; self.render_diagnostics(theme, hl_row) catch {}; @@ -1440,7 +1440,7 @@ pub const Editor = struct { if (self.syntax) |syn| { const root = self.buf_root() catch return; var start_byte: usize = 0; - _ = root.get_range(.{ .begin = .{}, .end = nudge.begin }, null, &start_byte, null, self.plane) catch return; + _ = root.get_range(.{ .begin = .{}, .end = nudge.begin }, null, &start_byte, null, self.plane.metrix()) catch return; syn.edit(.{ .start_byte = @intCast(start_byte), .old_end_byte = @intCast(start_byte), @@ -1472,7 +1472,7 @@ pub const Editor = struct { cursel.cursor = sel.begin; cursel.selection = null; var size: usize = 0; - const root_ = try root.delete_range(sel, a, &size, self.plane); + const root_ = try root.delete_range(sel, a, &size, self.plane.metrix()); self.nudge_delete(sel, cursel, size); return root_; } @@ -1539,11 +1539,11 @@ pub const Editor = struct { } fn is_word_char_at_cursor(root: Buffer.Root, cursor: *const Cursor, plane: Plane) bool { - return cursor.test_at(root, is_word_char, plane); + return cursor.test_at(root, is_word_char, plane.metrix()); } fn is_non_word_char_at_cursor(root: Buffer.Root, cursor: *const Cursor, plane: Plane) bool { - return cursor.test_at(root, is_not_word_char, plane); + return cursor.test_at(root, is_not_word_char, plane.metrix()); } fn is_word_boundary_left(root: Buffer.Root, cursor: *const Cursor, plane: Plane) bool { @@ -1552,7 +1552,7 @@ pub const Editor = struct { if (is_non_word_char_at_cursor(root, cursor, plane)) return false; var next = cursor.*; - next.move_left(root, plane) catch return true; + next.move_left(root, plane.metrix()) catch return true; if (is_non_word_char_at_cursor(root, &next, plane)) return true; return false; @@ -1564,33 +1564,33 @@ pub const Editor = struct { if (is_word_char_at_cursor(root, cursor, plane)) return false; var next = cursor.*; - next.move_left(root, plane) catch return true; + next.move_left(root, plane.metrix()) catch return true; if (is_word_char_at_cursor(root, &next, plane)) return true; return false; } fn is_word_boundary_right(root: Buffer.Root, cursor: *const Cursor, plane: Plane) bool { - const line_width = root.line_width(cursor.row, plane) catch return true; + const line_width = root.line_width(cursor.row, plane.metrix()) catch return true; if (cursor.col >= line_width) return true; if (is_non_word_char_at_cursor(root, cursor, plane)) return false; var next = cursor.*; - next.move_right(root, plane) catch return true; + next.move_right(root, plane.metrix()) catch return true; if (is_non_word_char_at_cursor(root, &next, plane)) return true; return false; } fn is_non_word_boundary_right(root: Buffer.Root, cursor: *const Cursor, plane: Plane) bool { - const line_width = root.line_width(cursor.row, plane) catch return true; + const line_width = root.line_width(cursor.row, plane.metrix()) catch return true; if (cursor.col >= line_width) return true; if (is_word_char_at_cursor(root, cursor, plane)) return false; var next = cursor.*; - next.move_right(root, plane) catch return true; + next.move_right(root, plane.metrix()) catch return true; if (is_word_char_at_cursor(root, &next, plane)) return true; return false; @@ -1603,14 +1603,14 @@ pub const Editor = struct { } fn is_eol_right(root: Buffer.Root, cursor: *const Cursor, plane: Plane) bool { - const line_width = root.line_width(cursor.row, plane) catch return true; + const line_width = root.line_width(cursor.row, plane.metrix()) catch return true; if (cursor.col >= line_width) return true; return false; } fn is_eol_right_vim(root: Buffer.Root, cursor: *const Cursor, plane: Plane) bool { - const line_width = root.line_width(cursor.row, plane) catch return true; + const line_width = root.line_width(cursor.row, plane.metrix()) catch return true; if (line_width == 0) return true; if (cursor.col >= line_width - 1) return true; @@ -1618,7 +1618,7 @@ pub const Editor = struct { } fn move_cursor_left(root: Buffer.Root, cursor: *Cursor, plane: Plane) error{Stop}!void { - try cursor.move_left(root, plane); + try cursor.move_left(root, plane.metrix()); } fn move_cursor_left_until(root: Buffer.Root, cursor: *Cursor, pred: cursor_predicate, plane: Plane) void { @@ -1637,11 +1637,11 @@ pub const Editor = struct { fn smart_move_cursor_begin(root: Buffer.Root, cursor: *Cursor, plane: Plane) !void { const first = find_first_non_ws(root, cursor.row, plane); - return if (cursor.col == first) cursor.move_begin() else cursor.move_to(root, cursor.row, first, plane); + return if (cursor.col == first) cursor.move_begin() else cursor.move_to(root, cursor.row, first, plane.metrix()); } fn move_cursor_right(root: Buffer.Root, cursor: *Cursor, plane: Plane) error{Stop}!void { - try cursor.move_right(root, plane); + try cursor.move_right(root, plane.metrix()); } fn move_cursor_right_until(root: Buffer.Root, cursor: *Cursor, pred: cursor_predicate, plane: Plane) void { @@ -1655,15 +1655,15 @@ pub const Editor = struct { } fn move_cursor_end(root: Buffer.Root, cursor: *Cursor, plane: Plane) !void { - cursor.move_end(root, plane); + cursor.move_end(root, plane.metrix()); } fn move_cursor_up(root: Buffer.Root, cursor: *Cursor, plane: Plane) !void { - try cursor.move_up(root, plane); + try cursor.move_up(root, plane.metrix()); } fn move_cursor_down(root: Buffer.Root, cursor: *Cursor, plane: Plane) !void { - try cursor.move_down(root, plane); + try cursor.move_down(root, plane.metrix()); } fn move_cursor_buffer_begin(_: Buffer.Root, cursor: *Cursor, _: Plane) !void { @@ -1671,15 +1671,15 @@ pub const Editor = struct { } fn move_cursor_buffer_end(root: Buffer.Root, cursor: *Cursor, plane: Plane) !void { - cursor.move_buffer_end(root, plane); + cursor.move_buffer_end(root, plane.metrix()); } fn move_cursor_page_up(root: Buffer.Root, cursor: *Cursor, view: *const View, plane: Plane) !void { - cursor.move_page_up(root, view, plane); + cursor.move_page_up(root, view, plane.metrix()); } fn move_cursor_page_down(root: Buffer.Root, cursor: *Cursor, view: *const View, plane: Plane) !void { - cursor.move_page_down(root, view, plane); + cursor.move_page_down(root, view, plane.metrix()); } pub fn primary_click(self: *Self, y: c_int, x: c_int) !void { @@ -1692,7 +1692,7 @@ pub const Editor = struct { self.selection_mode = .char; try self.send_editor_jump_source(); const root = self.buf_root() catch return; - primary.cursor.move_abs(root, &self.view, @intCast(y), @intCast(x), self.plane) catch return; + primary.cursor.move_abs(root, &self.view, @intCast(y), @intCast(x), self.plane.metrix()) catch return; self.clamp_mouse(); try self.send_editor_jump_destination(); if (self.jump_mode) try self.goto_definition(.{}); @@ -1703,7 +1703,7 @@ pub const Editor = struct { primary.selection = null; self.selection_mode = .word; const root = self.buf_root() catch return; - primary.cursor.move_abs(root, &self.view, @intCast(y), @intCast(x), self.plane) catch return; + primary.cursor.move_abs(root, &self.view, @intCast(y), @intCast(x), self.plane.metrix()) catch return; _ = try self.select_word_at_cursor(primary); self.clamp_mouse(); } @@ -1713,7 +1713,7 @@ pub const Editor = struct { primary.selection = null; self.selection_mode = .line; const root = self.buf_root() catch return; - primary.cursor.move_abs(root, &self.view, @intCast(y), @intCast(x), self.plane) catch return; + primary.cursor.move_abs(root, &self.view, @intCast(y), @intCast(x), self.plane.metrix()) catch return; try self.select_line_at_cursor(primary); self.clamp_mouse(); } @@ -1724,7 +1724,7 @@ pub const Editor = struct { const primary = self.get_primary(); const sel = primary.enable_selection(); const root = self.buf_root() catch return; - sel.end.move_abs(root, &self.view, @intCast(y_), @intCast(x_), self.plane) catch return; + sel.end.move_abs(root, &self.view, @intCast(y_), @intCast(x_), self.plane.metrix()) catch return; switch (self.selection_mode) { .char => {}, .word => if (sel.begin.right_of(sel.end)) @@ -1882,9 +1882,9 @@ pub const Editor = struct { fn copy_selection(root: Buffer.Root, sel: Selection, text_a: Allocator, plane: Plane) ![]const u8 { var size: usize = 0; - _ = try root.get_range(sel, null, &size, null, plane); + _ = try root.get_range(sel, null, &size, null, plane.metrix()); const buf__ = try text_a.alloc(u8, size); - return (try root.get_range(sel, buf__, null, null, plane)).?; + return (try root.get_range(sel, buf__, null, null, plane.metrix())).?; } pub fn get_selection(self: *const Self, sel: Selection, text_a: Allocator) ![]const u8 { @@ -1921,7 +1921,7 @@ pub const Editor = struct { var root_ = if (cursel.selection) |_| try self.delete_selection(root, cursel, a) else root; const cursor = &cursel.cursor; const begin = cursel.cursor; - cursor.row, cursor.col, root_ = try root_.insert_chars(cursor.row, cursor.col, s, a, self.plane); + cursor.row, cursor.col, root_ = try root_.insert_chars(cursor.row, cursor.col, s, a, self.plane.metrix()); cursor.target = cursor.col; self.nudge_insert(.{ .begin = begin, .end = cursor.* }, cursel, s.len); return root_; @@ -2126,7 +2126,7 @@ pub const Editor = struct { fn move_cursor_word_left_space(root: Buffer.Root, cursor: *Cursor, plane: Plane) error{Stop}!void { try move_cursor_left(root, cursor, plane); var next = cursor.*; - next.move_left(root, plane) catch + next.move_left(root, plane.metrix()) catch return move_cursor_left_until(root, cursor, is_word_boundary_left, plane); if (is_non_word_char_at_cursor(root, cursor, plane) and is_non_word_char_at_cursor(root, &next, plane)) move_cursor_left_until(root, cursor, is_non_word_boundary_left, plane) @@ -2146,7 +2146,7 @@ pub const Editor = struct { pub fn move_cursor_word_right_space(root: Buffer.Root, cursor: *Cursor, plane: Plane) error{Stop}!void { var next = cursor.*; - next.move_right(root, plane) catch { + next.move_right(root, plane.metrix()) catch { move_cursor_right_until(root, cursor, is_word_boundary_right, plane); try move_cursor_right(root, cursor, plane); return; @@ -2182,7 +2182,7 @@ pub const Editor = struct { return error.Stop; try move_cursor_left(root, cursor, plane); while (true) { - const curr_egc, _, _ = root.ecg_at(cursor.row, cursor.col, plane) catch return error.Stop; + const curr_egc, _, _ = root.ecg_at(cursor.row, cursor.col, plane.metrix()) catch return error.Stop; if (std.mem.eql(u8, curr_egc, egc)) return; if (is_eol_left(root, cursor, plane)) @@ -2197,7 +2197,7 @@ pub const Editor = struct { return error.Stop; try move_cursor_right(root, cursor, plane); while (true) { - const curr_egc, _, _ = root.ecg_at(cursor.row, cursor.col, plane) catch return error.Stop; + const curr_egc, _, _ = root.ecg_at(cursor.row, cursor.col, plane.metrix()) catch return error.Stop; if (std.mem.eql(u8, curr_egc, egc)) return; if (is_eol_right(root, cursor, plane)) @@ -2258,7 +2258,7 @@ pub const Editor = struct { const root = self.buf_root() catch return; primary.selection = match.to_selection(); match.has_selection = true; - primary.cursor.move_to(root, match.end.row, match.end.col, self.plane) catch return; + primary.cursor.move_to(root, match.end.row, match.end.col, self.plane.metrix()) catch return; } self.clamp(); try self.send_editor_jump_destination(); @@ -2273,7 +2273,7 @@ pub const Editor = struct { const root = self.buf_root() catch return; primary.selection = match.to_selection(); match.has_selection = true; - primary.cursor.move_to(root, match.end.row, match.end.col, self.plane) catch return; + primary.cursor.move_to(root, match.end.row, match.end.col, self.plane.metrix()) catch return; } self.clamp(); try self.send_editor_jump_destination(); @@ -2292,7 +2292,7 @@ pub const Editor = struct { .col = 0, }, }; - new_cursel.*.?.cursor.move_end(root, self.plane); + new_cursel.*.?.cursor.move_end(root, self.plane.metrix()); } } @@ -2314,13 +2314,13 @@ pub const Editor = struct { const cut_text = copy_selection(root, sel.*, sfa.get(), self.plane) catch return error.Stop; defer a.free(cut_text); root = try self.delete_selection(root, cursel, a); - try cursel.cursor.move_up(root, self.plane); + try cursel.cursor.move_up(root, self.plane.metrix()); root = self.insert(root, cursel, cut_text, a) catch return error.Stop; cursel.* = saved; - try cursel.cursor.move_up(root, self.plane); + try cursel.cursor.move_up(root, self.plane.metrix()); if (cursel.selection) |*sel_| { - try sel_.begin.move_up(root, self.plane); - try sel_.end.move_up(root, self.plane); + try sel_.begin.move_up(root, self.plane.metrix()); + try sel_.end.move_up(root, self.plane.metrix()); } return root; } @@ -2340,13 +2340,13 @@ pub const Editor = struct { const cut_text = copy_selection(root, sel.*, sfa.get(), self.plane) catch return error.Stop; defer a.free(cut_text); root = try self.delete_selection(root, cursel, a); - try cursel.cursor.move_down(root, self.plane); + try cursel.cursor.move_down(root, self.plane.metrix()); root = self.insert(root, cursel, cut_text, a) catch return error.Stop; cursel.* = saved; - try cursel.cursor.move_down(root, self.plane); + try cursel.cursor.move_down(root, self.plane.metrix()); if (cursel.selection) |*sel_| { - try sel_.begin.move_down(root, self.plane); - try sel_.end.move_down(root, self.plane); + try sel_.begin.move_down(root, self.plane.metrix()); + try sel_.end.move_down(root, self.plane.metrix()); } return root; } @@ -2360,7 +2360,7 @@ pub const Editor = struct { fn dupe_cursel_up(self: *Self, root_: Buffer.Root, cursel: *CurSel, a: Allocator) error{Stop}!Buffer.Root { var root = root_; - const sel: Selection = if (cursel.selection) |sel_| sel_ else Selection.line_from_cursor(cursel.cursor, root, self.plane); + const sel: Selection = if (cursel.selection) |sel_| sel_ else Selection.line_from_cursor(cursel.cursor, root, self.plane.metrix()); cursel.selection = null; var sfa = std.heap.stackFallback(4096, self.a); const text = copy_selection(root, sel, sfa.get(), self.plane) catch return error.Stop; @@ -2381,7 +2381,7 @@ pub const Editor = struct { fn dupe_cursel_down(self: *Self, root_: Buffer.Root, cursel: *CurSel, a: Allocator) error{Stop}!Buffer.Root { var root = root_; - const sel: Selection = if (cursel.selection) |sel_| sel_ else Selection.line_from_cursor(cursel.cursor, root, self.plane); + const sel: Selection = if (cursel.selection) |sel_| sel_ else Selection.line_from_cursor(cursel.cursor, root, self.plane.metrix()); cursel.selection = null; var sfa = std.heap.stackFallback(4096, self.a); const text = copy_selection(root, sel, sfa.get(), self.plane) catch return error.Stop; @@ -2464,7 +2464,7 @@ pub const Editor = struct { var newroot = root; defer { cursel.* = saved; - cursel.cursor.clamp_to_buffer(newroot, self.plane); + cursel.cursor.clamp_to_buffer(newroot, self.plane.metrix()); } cursel.selection = null; cursel.cursor = cursor; @@ -2474,8 +2474,8 @@ pub const Editor = struct { const cols = if (off == 0) 4 else off; const sel = cursel.enable_selection(); sel.begin.move_begin(); - try sel.end.move_to(root, sel.end.row, cols, self.plane); - if (cursel.cursor.col < cols) try cursel.cursor.move_to(root, cursel.cursor.row, cols, self.plane); + try sel.end.move_to(root, sel.end.row, cols, self.plane.metrix()); + if (cursel.cursor.col < cols) try cursel.cursor.move_to(root, cursel.cursor.row, cols, self.plane.metrix()); newroot = try self.delete_selection(root, cursel, a); return newroot; } @@ -2589,7 +2589,7 @@ pub const Editor = struct { try self.send_editor_jump_source(); self.cancel_all_selections(); const root = self.buf_root() catch return; - self.get_primary().cursor.move_buffer_end(root, self.plane); + self.get_primary().cursor.move_buffer_end(root, self.plane.metrix()); self.clamp(); try self.send_editor_jump_destination(); } @@ -2928,7 +2928,7 @@ pub const Editor = struct { const primary = self.get_primary(); var tree = std.ArrayList(u8).init(self.a); defer tree.deinit(); - root.debug_render_chunks(primary.cursor.row, &tree, self.plane) catch |e| + root.debug_render_chunks(primary.cursor.row, &tree, self.plane.metrix()) catch |e| return self.logger.print("line {d}: {any}", .{ primary.cursor.row, e }); self.logger.print("line {d}:{s}", .{ primary.cursor.row, std.fmt.fmtSliceEscapeLower(tree.items) }); } @@ -3184,8 +3184,8 @@ pub const Editor = struct { const root = self.buf_root() catch return; const begin_line = begin_line_ - 1; const end_line = end_line_ - 1; - const begin_pos = root.pos_to_width(begin_line, begin_pos_, self.plane) catch return; - const end_pos = root.pos_to_width(end_line, end_pos_, self.plane) catch return; + const begin_pos = root.pos_to_width(begin_line, begin_pos_, self.plane.metrix()) catch return; + const end_pos = root.pos_to_width(end_line, end_pos_, self.plane.metrix()) catch return; var match: Match = .{ .begin = .{ .row = begin_line, .col = begin_pos }, .end = .{ .row = end_line, .col = end_pos } }; if (match.end.eql(self.get_primary().cursor)) match.has_selection = true; @@ -3241,7 +3241,7 @@ pub const Editor = struct { if (self.scan_prev_match(cursor)) |match| return match; const root = self.buf_root() catch return null; var cursor_ = cursor; - cursor_.move_buffer_end(root, self.plane); + cursor_.move_buffer_end(root, self.plane.metrix()); return self.scan_prev_match(cursor_); } @@ -3253,7 +3253,7 @@ pub const Editor = struct { match_.has_selection = false; }; primary.selection = match.to_selection(); - primary.cursor.move_to(root, match.end.row, match.end.col, self.plane) catch return; + primary.cursor.move_to(root, match.end.row, match.end.col, self.plane.metrix()) catch return; self.clamp(); } } @@ -3280,7 +3280,7 @@ pub const Editor = struct { }; primary.selection = match.to_selection(); primary.selection.?.reverse(); - primary.cursor.move_to(root, match.begin.row, match.begin.col, self.plane) catch return; + primary.cursor.move_to(root, match.begin.row, match.begin.col, self.plane.metrix()) catch return; self.clamp(); } } @@ -3327,7 +3327,7 @@ pub const Editor = struct { const primary = self.get_primary(); try self.send_editor_jump_source(); self.cancel_all_selections(); - try primary.cursor.move_to(root, diag.sel.begin.row, diag.sel.begin.col, self.plane); + try primary.cursor.move_to(root, diag.sel.begin.row, diag.sel.begin.col, self.plane.metrix()); self.clamp(); try self.send_editor_jump_destination(); } @@ -3352,7 +3352,7 @@ pub const Editor = struct { const root = self.buf_root() catch return; self.cancel_all_selections(); const primary = self.get_primary(); - try primary.cursor.move_to(root, @intCast(if (line < 1) 0 else line - 1), primary.cursor.col, self.plane); + try primary.cursor.move_to(root, @intCast(if (line < 1) 0 else line - 1), primary.cursor.col, self.plane.metrix()); self.clamp(); try self.send_editor_jump_destination(); } @@ -3363,7 +3363,7 @@ pub const Editor = struct { return error.InvalidArgument; const root = self.buf_root() catch return; const primary = self.get_primary(); - try primary.cursor.move_to(root, primary.cursor.row, @intCast(if (column < 1) 0 else column - 1), self.plane); + try primary.cursor.move_to(root, primary.cursor.row, @intCast(if (column < 1) 0 else column - 1), self.plane.metrix()); self.clamp(); } @@ -3396,7 +3396,7 @@ pub const Editor = struct { root, @intCast(if (line < 1) 0 else line - 1), @intCast(if (column < 1) 0 else column - 1), - self.plane, + self.plane.metrix(), ); if (have_sel) primary.selection = sel; if (self.view.is_visible(&primary.cursor)) @@ -3538,7 +3538,7 @@ pub const Editor = struct { try self.write_range(state.before_root, sel, buffer.writer(), tp.exit_error, null, self.plane); try buffer.flush(); self.logger.print("filter: sent", .{}); - state.work_root = try state.work_root.delete_range(sel, buf_a_, null, self.plane); + state.work_root = try state.work_root.delete_range(sel, buf_a_, null, self.plane.metrix()); } fn filter_stdout(self: *Self, bytes: []const u8) !void { @@ -3549,7 +3549,7 @@ pub const Editor = struct { try buf.appendSlice(bytes); } else { const cursor = &state.pos.cursor; - cursor.row, cursor.col, state.work_root = try state.work_root.insert_chars(cursor.row, cursor.col, bytes, buf_a_, self.plane); + cursor.row, cursor.col, state.work_root = try state.work_root.insert_chars(cursor.row, cursor.col, bytes, buf_a_, self.plane.metrix()); state.bytes += bytes.len; state.chunks += 1; } @@ -3582,7 +3582,7 @@ pub const Editor = struct { primary.cursor = sel.end; } try self.update_buf(state.work_root); - primary.cursor.clamp_to_buffer(state.work_root, self.plane); + primary.cursor.clamp_to_buffer(state.work_root, self.plane.metrix()); self.logger.print("filter: done (bytes:{d} chunks:{d})", .{ state.bytes, state.chunks }); self.reset_syntax(); self.clamp(); @@ -3879,10 +3879,10 @@ pub const PosToWidthCache = struct { self.cache.clearRetainingCapacity(); self.cached_line = start.row; self.cached_root = root; - root.get_line_width_map(self.cached_line, &self.cache, plane) catch return null; + root.get_line_width_map(self.cached_line, &self.cache, plane.metrix()) catch return null; } const start_col = if (start.column < self.cache.items.len) self.cache.items[start.column] else start.column; - const end_col = if (end.row == start.row and end.column < self.cache.items.len) self.cache.items[end.column] else root.pos_to_width(end.row, end.column, plane) catch end.column; + const end_col = if (end.row == start.row and end.column < self.cache.items.len) self.cache.items[end.column] else root.pos_to_width(end.row, end.column, plane.metrix()) catch end.column; return .{ .begin = .{ .row = start.row, .col = start_col }, .end = .{ .row = end.row, .col = end_col } }; } }; diff --git a/src/tui/inspector_view.zig b/src/tui/inspector_view.zig index 8855a1b..78b9187 100644 --- a/src/tui/inspector_view.zig +++ b/src/tui/inspector_view.zig @@ -81,7 +81,7 @@ fn inspect_location(self: *Self, row: usize, col: usize) void { fn get_buffer_text(self: *Self, buf: []u8, sel: Buffer.Selection) ?[]const u8 { const root = self.editor.get_current_root() orelse return null; - return root.get_range(sel, buf, null, null, self.plane) catch return null; + return root.get_range(sel, buf, null, null, self.plane.metrix()) catch return null; } fn dump_highlight(self: *Self, range: syntax.Range, scope: []const u8, id: u32, _: usize, ast_node: *const syntax.Node) error{Stop}!void {