refactor(Buffer): rename Metrix to Metrics
Metrix was a bit too silly
This commit is contained in:
parent
633cc5a1c1
commit
f06a7b3d6a
7 changed files with 211 additions and 211 deletions
|
@ -16,7 +16,7 @@ pub const View = @import("View.zig");
|
||||||
pub const Selection = @import("Selection.zig");
|
pub const Selection = @import("Selection.zig");
|
||||||
pub const MetaWriter = std.ArrayList(u8).Writer;
|
pub const MetaWriter = std.ArrayList(u8).Writer;
|
||||||
|
|
||||||
pub const Metrix = struct {
|
pub const Metrics = struct {
|
||||||
ctx: *const anyopaque,
|
ctx: *const anyopaque,
|
||||||
egc_length: egc_length_func,
|
egc_length: egc_length_func,
|
||||||
egc_chunk_width: egc_chunk_width_func,
|
egc_chunk_width: egc_chunk_width_func,
|
||||||
|
@ -58,7 +58,7 @@ pub const WalkerMut = struct {
|
||||||
pub const stop = WalkerMut{ .keep_walking = false };
|
pub const stop = WalkerMut{ .keep_walking = false };
|
||||||
pub const found = WalkerMut{ .found = true };
|
pub const found = WalkerMut{ .found = true };
|
||||||
|
|
||||||
const F = *const fn (ctx: *anyopaque, leaf: *const Leaf, mtrx: Metrix) WalkerMut;
|
const F = *const fn (ctx: *anyopaque, leaf: *const Leaf, metrics: Metrics) WalkerMut;
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Walker = struct {
|
pub const Walker = struct {
|
||||||
|
@ -70,7 +70,7 @@ pub const Walker = struct {
|
||||||
pub const stop = Walker{ .keep_walking = false };
|
pub const stop = Walker{ .keep_walking = false };
|
||||||
pub const found = Walker{ .found = true };
|
pub const found = Walker{ .found = true };
|
||||||
|
|
||||||
const F = *const fn (ctx: *anyopaque, leaf: *const Leaf, mtrx: Metrix) Walker;
|
const F = *const fn (ctx: *anyopaque, leaf: *const Leaf, metrics: Metrics) Walker;
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Weights = struct {
|
pub const Weights = struct {
|
||||||
|
@ -152,7 +152,7 @@ pub const Leaf = struct {
|
||||||
return self.buf.len == 0 and !self.bol and !self.eol;
|
return self.buf.len == 0 and !self.bol and !self.eol;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pos_to_width(self: *const Leaf, pos: *usize, abs_col_: usize, mtrx: Metrix) usize {
|
fn pos_to_width(self: *const Leaf, pos: *usize, abs_col_: usize, metrics: Metrics) usize {
|
||||||
var col: usize = 0;
|
var col: usize = 0;
|
||||||
var abs_col = abs_col_;
|
var abs_col = abs_col_;
|
||||||
var cols: c_int = 0;
|
var cols: c_int = 0;
|
||||||
|
@ -163,7 +163,7 @@ pub const Leaf = struct {
|
||||||
buf = buf[1..];
|
buf = buf[1..];
|
||||||
pos.* -= 1;
|
pos.* -= 1;
|
||||||
} else {
|
} else {
|
||||||
const bytes = mtrx.egc_length(mtrx.ctx, buf, &cols, abs_col);
|
const bytes = metrics.egc_length(metrics.ctx, buf, &cols, abs_col);
|
||||||
buf = buf[bytes..];
|
buf = buf[bytes..];
|
||||||
pos.* -= bytes;
|
pos.* -= bytes;
|
||||||
}
|
}
|
||||||
|
@ -173,12 +173,12 @@ pub const Leaf = struct {
|
||||||
return col;
|
return col;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn width(self: *const Leaf, abs_col: usize, mtrx: Metrix) usize {
|
fn width(self: *const Leaf, abs_col: usize, metrics: Metrics) usize {
|
||||||
var pos: usize = std.math.maxInt(usize);
|
var pos: usize = std.math.maxInt(usize);
|
||||||
return self.pos_to_width(&pos, abs_col, mtrx);
|
return self.pos_to_width(&pos, abs_col, metrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fn width_to_pos(self: *const Leaf, col_: usize, abs_col_: usize, mtrx: Metrix) !usize {
|
inline fn width_to_pos(self: *const Leaf, col_: usize, abs_col_: usize, metrics: Metrics) !usize {
|
||||||
var abs_col = abs_col_;
|
var abs_col = abs_col_;
|
||||||
var col = col_;
|
var col = col_;
|
||||||
var cols: c_int = 0;
|
var cols: c_int = 0;
|
||||||
|
@ -186,7 +186,7 @@ pub const Leaf = struct {
|
||||||
return while (buf.len > 0) {
|
return while (buf.len > 0) {
|
||||||
if (col == 0)
|
if (col == 0)
|
||||||
break @intFromPtr(buf.ptr) - @intFromPtr(self.buf.ptr);
|
break @intFromPtr(buf.ptr) - @intFromPtr(self.buf.ptr);
|
||||||
const bytes = mtrx.egc_length(mtrx.ctx, buf, &cols, abs_col);
|
const bytes = metrics.egc_length(metrics.ctx, buf, &cols, abs_col);
|
||||||
buf = buf[bytes..];
|
buf = buf[bytes..];
|
||||||
if (col < cols)
|
if (col < cols)
|
||||||
break @intFromPtr(buf.ptr) - @intFromPtr(self.buf.ptr);
|
break @intFromPtr(buf.ptr) - @intFromPtr(self.buf.ptr);
|
||||||
|
@ -195,20 +195,20 @@ pub const Leaf = struct {
|
||||||
} else error.BufferUnderrun;
|
} else error.BufferUnderrun;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fn dump(self: *const Leaf, l: *ArrayList(u8), abs_col: usize, mtrx: Metrix) !void {
|
inline fn dump(self: *const Leaf, l: *ArrayList(u8), abs_col: usize, metrics: Metrics) !void {
|
||||||
var buf: [16]u8 = undefined;
|
var buf: [16]u8 = undefined;
|
||||||
const wcwidth = try std.fmt.bufPrint(&buf, "{d}", .{self.width(abs_col, mtrx)});
|
const wcwidth = try std.fmt.bufPrint(&buf, "{d}", .{self.width(abs_col, metrics)});
|
||||||
if (self.bol)
|
if (self.bol)
|
||||||
try l.appendSlice("BOL ");
|
try l.appendSlice("BOL ");
|
||||||
try l.appendSlice(wcwidth);
|
try l.appendSlice(wcwidth);
|
||||||
try l.append('"');
|
try l.append('"');
|
||||||
try debug_render_chunk(self.buf, l, mtrx);
|
try debug_render_chunk(self.buf, l, metrics);
|
||||||
try l.appendSlice("\" ");
|
try l.appendSlice("\" ");
|
||||||
if (self.eol)
|
if (self.eol)
|
||||||
try l.appendSlice("EOL ");
|
try l.appendSlice("EOL ");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn debug_render_chunk(chunk: []const u8, l: *ArrayList(u8), mtrx: Metrix) !void {
|
fn debug_render_chunk(chunk: []const u8, l: *ArrayList(u8), metrics: Metrics) !void {
|
||||||
var cols: c_int = 0;
|
var cols: c_int = 0;
|
||||||
var buf = chunk;
|
var buf = chunk;
|
||||||
while (buf.len > 0) {
|
while (buf.len > 0) {
|
||||||
|
@ -219,7 +219,7 @@ pub const Leaf = struct {
|
||||||
buf = buf[1..];
|
buf = buf[1..];
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
const bytes = mtrx.egc_length(mtrx.ctx, buf, &cols, 0);
|
const bytes = metrics.egc_length(metrics.ctx, buf, &cols, 0);
|
||||||
var buf_: [4096]u8 = undefined;
|
var buf_: [4096]u8 = undefined;
|
||||||
try l.appendSlice(try std.fmt.bufPrint(&buf_, "{s}", .{std.fmt.fmtSliceEscapeLower(buf[0..bytes])}));
|
try l.appendSlice(try std.fmt.bufPrint(&buf_, "{s}", .{std.fmt.fmtSliceEscapeLower(buf[0..bytes])}));
|
||||||
buf = buf[bytes..];
|
buf = buf[bytes..];
|
||||||
|
@ -321,27 +321,27 @@ const Node = union(enum) {
|
||||||
return leaves.toOwnedSlice();
|
return leaves.toOwnedSlice();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn walk_const(self: *const Node, f: Walker.F, ctx: *anyopaque, mtrx: Metrix) Walker {
|
fn walk_const(self: *const Node, f: Walker.F, ctx: *anyopaque, metrics: Metrics) Walker {
|
||||||
switch (self.*) {
|
switch (self.*) {
|
||||||
.node => |*node| {
|
.node => |*node| {
|
||||||
const left = node.left.walk_const(f, ctx, mtrx);
|
const left = node.left.walk_const(f, ctx, metrics);
|
||||||
if (!left.keep_walking) {
|
if (!left.keep_walking) {
|
||||||
var result = Walker{};
|
var result = Walker{};
|
||||||
result.err = left.err;
|
result.err = left.err;
|
||||||
result.found = left.found;
|
result.found = left.found;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
const right = node.right.walk_const(f, ctx, mtrx);
|
const right = node.right.walk_const(f, ctx, metrics);
|
||||||
return node.merge_results_const(left, right);
|
return node.merge_results_const(left, right);
|
||||||
},
|
},
|
||||||
.leaf => |*l| return f(ctx, l, mtrx),
|
.leaf => |*l| return f(ctx, l, metrics),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn walk(self: *const Node, a: Allocator, f: WalkerMut.F, ctx: *anyopaque, mtrx: Metrix) WalkerMut {
|
fn walk(self: *const Node, a: Allocator, f: WalkerMut.F, ctx: *anyopaque, metrics: Metrics) WalkerMut {
|
||||||
switch (self.*) {
|
switch (self.*) {
|
||||||
.node => |*node| {
|
.node => |*node| {
|
||||||
const left = node.left.walk(a, f, ctx, mtrx);
|
const left = node.left.walk(a, f, ctx, metrics);
|
||||||
if (!left.keep_walking) {
|
if (!left.keep_walking) {
|
||||||
var result = WalkerMut{};
|
var result = WalkerMut{};
|
||||||
result.err = left.err;
|
result.err = left.err;
|
||||||
|
@ -351,26 +351,26 @@ const Node = union(enum) {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
const right = node.right.walk(a, f, ctx, mtrx);
|
const right = node.right.walk(a, f, ctx, metrics);
|
||||||
return node.merge_results(a, left, right);
|
return node.merge_results(a, left, right);
|
||||||
},
|
},
|
||||||
.leaf => |*l| return f(ctx, l, mtrx),
|
.leaf => |*l| return f(ctx, l, metrics),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn walk_from_line_begin_const_internal(self: *const Node, line: usize, f: Walker.F, ctx: *anyopaque, mtrx: Metrix) Walker {
|
fn walk_from_line_begin_const_internal(self: *const Node, line: usize, f: Walker.F, ctx: *anyopaque, metrics: Metrics) Walker {
|
||||||
switch (self.*) {
|
switch (self.*) {
|
||||||
.node => |*node| {
|
.node => |*node| {
|
||||||
const left_bols = node.weights.bols;
|
const left_bols = node.weights.bols;
|
||||||
if (line >= left_bols)
|
if (line >= left_bols)
|
||||||
return node.right.walk_from_line_begin_const_internal(line - left_bols, f, ctx, mtrx);
|
return node.right.walk_from_line_begin_const_internal(line - left_bols, f, ctx, metrics);
|
||||||
const left_result = node.left.walk_from_line_begin_const_internal(line, f, ctx, mtrx);
|
const left_result = node.left.walk_from_line_begin_const_internal(line, f, ctx, metrics);
|
||||||
const right_result = if (left_result.found and left_result.keep_walking) node.right.walk_const(f, ctx, mtrx) else Walker{};
|
const right_result = if (left_result.found and left_result.keep_walking) node.right.walk_const(f, ctx, metrics) else Walker{};
|
||||||
return node.merge_results_const(left_result, right_result);
|
return node.merge_results_const(left_result, right_result);
|
||||||
},
|
},
|
||||||
.leaf => |*l| {
|
.leaf => |*l| {
|
||||||
if (line == 0) {
|
if (line == 0) {
|
||||||
var result = f(ctx, l, mtrx);
|
var result = f(ctx, l, metrics);
|
||||||
if (result.err) |_| return result;
|
if (result.err) |_| return result;
|
||||||
result.found = true;
|
result.found = true;
|
||||||
return result;
|
return result;
|
||||||
|
@ -380,18 +380,18 @@ const Node = union(enum) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn walk_from_line_begin_const(self: *const Node, line: usize, f: Walker.F, ctx: *anyopaque, mtrx: Metrix) !bool {
|
pub fn walk_from_line_begin_const(self: *const Node, line: usize, f: Walker.F, ctx: *anyopaque, metrics: Metrics) !bool {
|
||||||
const result = self.walk_from_line_begin_const_internal(line, f, ctx, mtrx);
|
const result = self.walk_from_line_begin_const_internal(line, f, ctx, metrics);
|
||||||
if (result.err) |e| return e;
|
if (result.err) |e| return e;
|
||||||
return result.found;
|
return result.found;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn walk_from_line_begin_internal(self: *const Node, a: Allocator, line: usize, f: WalkerMut.F, ctx: *anyopaque, mtrx: Metrix) WalkerMut {
|
fn walk_from_line_begin_internal(self: *const Node, a: Allocator, line: usize, f: WalkerMut.F, ctx: *anyopaque, metrics: Metrics) WalkerMut {
|
||||||
switch (self.*) {
|
switch (self.*) {
|
||||||
.node => |*node| {
|
.node => |*node| {
|
||||||
const left_bols = node.weights.bols;
|
const left_bols = node.weights.bols;
|
||||||
if (line >= left_bols) {
|
if (line >= left_bols) {
|
||||||
const right_result = node.right.walk_from_line_begin_internal(a, line - left_bols, f, ctx, mtrx);
|
const right_result = node.right.walk_from_line_begin_internal(a, line - left_bols, f, ctx, metrics);
|
||||||
if (right_result.replace) |p| {
|
if (right_result.replace) |p| {
|
||||||
var result = WalkerMut{};
|
var result = WalkerMut{};
|
||||||
result.err = right_result.err;
|
result.err = right_result.err;
|
||||||
|
@ -406,13 +406,13 @@ const Node = union(enum) {
|
||||||
return right_result;
|
return right_result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const left_result = node.left.walk_from_line_begin_internal(a, line, f, ctx, mtrx);
|
const left_result = node.left.walk_from_line_begin_internal(a, line, f, ctx, metrics);
|
||||||
const right_result = if (left_result.found and left_result.keep_walking) node.right.walk(a, f, ctx, mtrx) else WalkerMut{};
|
const right_result = if (left_result.found and left_result.keep_walking) node.right.walk(a, f, ctx, metrics) else WalkerMut{};
|
||||||
return node.merge_results(a, left_result, right_result);
|
return node.merge_results(a, left_result, right_result);
|
||||||
},
|
},
|
||||||
.leaf => |*l| {
|
.leaf => |*l| {
|
||||||
if (line == 0) {
|
if (line == 0) {
|
||||||
var result = f(ctx, l, mtrx);
|
var result = f(ctx, l, metrics);
|
||||||
if (result.err) |_| {
|
if (result.err) |_| {
|
||||||
result.replace = null;
|
result.replace = null;
|
||||||
return result;
|
return result;
|
||||||
|
@ -425,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, mtrx: Metrix) !struct { bool, ?Root } {
|
pub fn walk_from_line_begin(self: *const Node, a: Allocator, line: usize, f: WalkerMut.F, ctx: *anyopaque, metrics: Metrics) !struct { bool, ?Root } {
|
||||||
const result = self.walk_from_line_begin_internal(a, line, f, ctx, mtrx);
|
const result = self.walk_from_line_begin_internal(a, line, f, ctx, metrics);
|
||||||
if (result.err) |e| return e;
|
if (result.err) |e| return e;
|
||||||
return .{ result.found, result.replace };
|
return .{ result.found, result.replace };
|
||||||
}
|
}
|
||||||
|
@ -466,27 +466,27 @@ const Node = union(enum) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const EgcF = *const fn (ctx: *anyopaque, egc: []const u8, wcwidth: usize, mtrx: Metrix) Walker;
|
const EgcF = *const fn (ctx: *anyopaque, egc: []const u8, wcwidth: usize, metrics: Metrics) Walker;
|
||||||
|
|
||||||
pub fn walk_egc_forward(self: *const Node, line: usize, walker_f: EgcF, walker_ctx: *anyopaque, mtrx_: Metrix) !void {
|
pub fn walk_egc_forward(self: *const Node, line: usize, walker_f: EgcF, walker_ctx: *anyopaque, metrics_: Metrics) !void {
|
||||||
const Ctx = struct {
|
const Ctx = struct {
|
||||||
walker_f: EgcF,
|
walker_f: EgcF,
|
||||||
walker_ctx: @TypeOf(walker_ctx),
|
walker_ctx: @TypeOf(walker_ctx),
|
||||||
abs_col: usize = 0,
|
abs_col: usize = 0,
|
||||||
fn walker(ctx_: *anyopaque, leaf: *const Self.Leaf, mtrx: Metrix) Walker {
|
fn walker(ctx_: *anyopaque, leaf: *const Self.Leaf, metrics: Metrics) Walker {
|
||||||
const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_)));
|
const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_)));
|
||||||
var buf: []const u8 = leaf.buf;
|
var buf: []const u8 = leaf.buf;
|
||||||
while (buf.len > 0) {
|
while (buf.len > 0) {
|
||||||
var cols: c_int = undefined;
|
var cols: c_int = undefined;
|
||||||
const bytes = mtrx.egc_length(mtrx.ctx, buf, &cols, ctx.abs_col);
|
const bytes = metrics.egc_length(metrics.ctx, buf, &cols, ctx.abs_col);
|
||||||
const ret = ctx.walker_f(ctx.walker_ctx, buf[0..bytes], @intCast(cols), mtrx);
|
const ret = ctx.walker_f(ctx.walker_ctx, buf[0..bytes], @intCast(cols), metrics);
|
||||||
if (ret.err) |e| return .{ .err = e };
|
if (ret.err) |e| return .{ .err = e };
|
||||||
buf = buf[bytes..];
|
buf = buf[bytes..];
|
||||||
ctx.abs_col += @intCast(cols);
|
ctx.abs_col += @intCast(cols);
|
||||||
if (!ret.keep_walking) return Walker.stop;
|
if (!ret.keep_walking) return Walker.stop;
|
||||||
}
|
}
|
||||||
if (leaf.eol) {
|
if (leaf.eol) {
|
||||||
const ret = ctx.walker_f(ctx.walker_ctx, "\n", 1, mtrx);
|
const ret = ctx.walker_f(ctx.walker_ctx, "\n", 1, metrics);
|
||||||
if (ret.err) |e| return .{ .err = e };
|
if (ret.err) |e| return .{ .err = e };
|
||||||
if (!ret.keep_walking) return Walker.stop;
|
if (!ret.keep_walking) return Walker.stop;
|
||||||
ctx.abs_col = 0;
|
ctx.abs_col = 0;
|
||||||
|
@ -495,16 +495,16 @@ const Node = union(enum) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var ctx: Ctx = .{ .walker_f = walker_f, .walker_ctx = walker_ctx };
|
var ctx: Ctx = .{ .walker_f = walker_f, .walker_ctx = walker_ctx };
|
||||||
const found = try self.walk_from_line_begin_const(line, Ctx.walker, &ctx, mtrx_);
|
const found = try self.walk_from_line_begin_const(line, Ctx.walker, &ctx, metrics_);
|
||||||
if (!found) return error.NotFound;
|
if (!found) return error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ecg_at(self: *const Node, line: usize, col: usize, mtrx: Metrix) error{NotFound}!struct { []const u8, usize, usize } {
|
pub fn ecg_at(self: *const Node, line: usize, col: usize, metrics: Metrics) error{NotFound}!struct { []const u8, usize, usize } {
|
||||||
const ctx_ = struct {
|
const ctx_ = struct {
|
||||||
col: usize,
|
col: usize,
|
||||||
at: ?[]const u8 = null,
|
at: ?[]const u8 = null,
|
||||||
wcwidth: usize = 0,
|
wcwidth: usize = 0,
|
||||||
fn walker(ctx_: *anyopaque, egc: []const u8, wcwidth: usize, _: Metrix) Walker {
|
fn walker(ctx_: *anyopaque, egc: []const u8, wcwidth: usize, _: Metrics) Walker {
|
||||||
const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_)));
|
const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_)));
|
||||||
ctx.at = egc;
|
ctx.at = egc;
|
||||||
ctx.wcwidth = wcwidth;
|
ctx.wcwidth = wcwidth;
|
||||||
|
@ -515,20 +515,20 @@ const Node = union(enum) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var ctx: ctx_ = .{ .col = col };
|
var ctx: ctx_ = .{ .col = col };
|
||||||
self.walk_egc_forward(line, ctx_.walker, &ctx, mtrx) catch return .{ "?", 1, 0 };
|
self.walk_egc_forward(line, ctx_.walker, &ctx, metrics) catch return .{ "?", 1, 0 };
|
||||||
return if (ctx.at) |at| .{ at, ctx.wcwidth, ctx.col } else error.NotFound;
|
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, mtrx: Metrix) bool {
|
pub fn test_at(self: *const Node, pred: *const fn (c: []const u8) bool, line: usize, col: usize, metrics: Metrics) bool {
|
||||||
const ecg, _, _ = self.ecg_at(line, col, mtrx) catch return false;
|
const ecg, _, _ = self.ecg_at(line, col, metrics) catch return false;
|
||||||
return pred(ecg);
|
return pred(ecg);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_line_width_map(self: *const Node, line: usize, map: *ArrayList(usize), mtrx: Metrix) error{ Stop, NoSpaceLeft }!void {
|
pub fn get_line_width_map(self: *const Node, line: usize, map: *ArrayList(usize), metrics: Metrics) error{ Stop, NoSpaceLeft }!void {
|
||||||
const Ctx = struct {
|
const Ctx = struct {
|
||||||
map: *ArrayList(usize),
|
map: *ArrayList(usize),
|
||||||
wcwidth: usize = 0,
|
wcwidth: usize = 0,
|
||||||
fn walker(ctx_: *anyopaque, egc: []const u8, wcwidth: usize, _: Metrix) Walker {
|
fn walker(ctx_: *anyopaque, egc: []const u8, wcwidth: usize, _: Metrics) Walker {
|
||||||
const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_)));
|
const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_)));
|
||||||
var n = egc.len;
|
var n = egc.len;
|
||||||
while (n > 0) : (n -= 1) {
|
while (n > 0) : (n -= 1) {
|
||||||
|
@ -540,20 +540,20 @@ const Node = union(enum) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var ctx: Ctx = .{ .map = map };
|
var ctx: Ctx = .{ .map = map };
|
||||||
self.walk_egc_forward(line, Ctx.walker, &ctx, mtrx) catch |e| return switch (e) {
|
self.walk_egc_forward(line, Ctx.walker, &ctx, metrics) catch |e| return switch (e) {
|
||||||
error.NoSpaceLeft => error.NoSpaceLeft,
|
error.NoSpaceLeft => error.NoSpaceLeft,
|
||||||
else => error.Stop,
|
else => error.Stop,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_range(self: *const Node, sel: Selection, copy_buf: ?[]u8, size: ?*usize, wcwidth_: ?*usize, mtrx_: Metrix) error{ Stop, NoSpaceLeft }!?[]u8 {
|
pub fn get_range(self: *const Node, sel: Selection, copy_buf: ?[]u8, size: ?*usize, wcwidth_: ?*usize, metrics_: Metrics) error{ Stop, NoSpaceLeft }!?[]u8 {
|
||||||
const Ctx = struct {
|
const Ctx = struct {
|
||||||
col: usize = 0,
|
col: usize = 0,
|
||||||
sel: Selection,
|
sel: Selection,
|
||||||
out: ?[]u8,
|
out: ?[]u8,
|
||||||
bytes: usize = 0,
|
bytes: usize = 0,
|
||||||
wcwidth: usize = 0,
|
wcwidth: usize = 0,
|
||||||
fn walker(ctx_: *anyopaque, egc: []const u8, wcwidth: usize, _: Metrix) Walker {
|
fn walker(ctx_: *anyopaque, egc: []const u8, wcwidth: usize, _: Metrics) Walker {
|
||||||
const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_)));
|
const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_)));
|
||||||
if (ctx.col < ctx.sel.begin.col) {
|
if (ctx.col < ctx.sel.begin.col) {
|
||||||
ctx.col += wcwidth;
|
ctx.col += wcwidth;
|
||||||
|
@ -586,7 +586,7 @@ const Node = union(enum) {
|
||||||
ctx.sel.normalize();
|
ctx.sel.normalize();
|
||||||
if (ctx.sel.begin.eql(ctx.sel.end))
|
if (ctx.sel.begin.eql(ctx.sel.end))
|
||||||
return error.Stop;
|
return error.Stop;
|
||||||
self.walk_egc_forward(ctx.sel.begin.row, Ctx.walker, &ctx, mtrx_) catch |e| return switch (e) {
|
self.walk_egc_forward(ctx.sel.begin.row, Ctx.walker, &ctx, metrics_) catch |e| return switch (e) {
|
||||||
error.NoSpaceLeft => error.NoSpaceLeft,
|
error.NoSpaceLeft => error.NoSpaceLeft,
|
||||||
else => error.Stop,
|
else => error.Stop,
|
||||||
};
|
};
|
||||||
|
@ -595,20 +595,20 @@ const Node = union(enum) {
|
||||||
return if (copy_buf) |buf_| buf_[0..ctx.bytes] else null;
|
return if (copy_buf) |buf_| buf_[0..ctx.bytes] else null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_range(self: *const Node, sel: Selection, a: Allocator, size: ?*usize, mtrx: Metrix) error{Stop}!Root {
|
pub fn delete_range(self: *const Node, sel: Selection, a: Allocator, size: ?*usize, metrics: Metrics) error{Stop}!Root {
|
||||||
var wcwidth: usize = 0;
|
var wcwidth: usize = 0;
|
||||||
_ = self.get_range(sel, null, size, &wcwidth, mtrx) catch return error.Stop;
|
_ = self.get_range(sel, null, size, &wcwidth, metrics) catch return error.Stop;
|
||||||
return self.del_chars(sel.begin.row, sel.begin.col, wcwidth, a, mtrx) catch return error.Stop;
|
return self.del_chars(sel.begin.row, sel.begin.col, wcwidth, a, metrics) catch return error.Stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn del_chars(self: *const Node, line: usize, col: usize, count: usize, a: Allocator, mtrx_: Metrix) !Root {
|
pub fn del_chars(self: *const Node, line: usize, col: usize, count: usize, a: Allocator, metrics_: Metrics) !Root {
|
||||||
const Ctx = struct {
|
const Ctx = struct {
|
||||||
a: Allocator,
|
a: Allocator,
|
||||||
col: usize,
|
col: usize,
|
||||||
abs_col: usize = 0,
|
abs_col: usize = 0,
|
||||||
count: usize,
|
count: usize,
|
||||||
delete_next_bol: bool = false,
|
delete_next_bol: bool = false,
|
||||||
fn walker(Ctx: *anyopaque, leaf: *const Leaf, mtrx: Metrix) WalkerMut {
|
fn walker(Ctx: *anyopaque, leaf: *const Leaf, metrics: Metrics) WalkerMut {
|
||||||
const ctx = @as(*@This(), @ptrCast(@alignCast(Ctx)));
|
const ctx = @as(*@This(), @ptrCast(@alignCast(Ctx)));
|
||||||
var result = WalkerMut.keep_walking;
|
var result = WalkerMut.keep_walking;
|
||||||
if (ctx.delete_next_bol and ctx.count == 0) {
|
if (ctx.delete_next_bol and ctx.count == 0) {
|
||||||
|
@ -617,7 +617,7 @@ const Node = union(enum) {
|
||||||
ctx.delete_next_bol = false;
|
ctx.delete_next_bol = false;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
const leaf_wcwidth = leaf.width(ctx.abs_col, mtrx);
|
const leaf_wcwidth = leaf.width(ctx.abs_col, metrics);
|
||||||
const leaf_bol = leaf.bol and !ctx.delete_next_bol;
|
const leaf_bol = leaf.bol and !ctx.delete_next_bol;
|
||||||
ctx.delete_next_bol = false;
|
ctx.delete_next_bol = false;
|
||||||
const base_col = ctx.abs_col;
|
const base_col = ctx.abs_col;
|
||||||
|
@ -641,7 +641,7 @@ const Node = union(enum) {
|
||||||
result.replace = Leaf.new(ctx.a, "", leaf_bol, leaf.eol) catch |e| return .{ .err = e };
|
result.replace = Leaf.new(ctx.a, "", leaf_bol, leaf.eol) catch |e| return .{ .err = e };
|
||||||
ctx.count = 0;
|
ctx.count = 0;
|
||||||
} else {
|
} else {
|
||||||
const pos = leaf.width_to_pos(ctx.count, base_col, mtrx) catch |e| return .{ .err = e };
|
const pos = leaf.width_to_pos(ctx.count, base_col, metrics) catch |e| return .{ .err = e };
|
||||||
result.replace = Leaf.new(ctx.a, leaf.buf[pos..], leaf_bol, leaf.eol) 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;
|
ctx.count = 0;
|
||||||
}
|
}
|
||||||
|
@ -655,7 +655,7 @@ const Node = union(enum) {
|
||||||
} else {
|
} else {
|
||||||
if (ctx.col + ctx.count >= leaf_wcwidth) {
|
if (ctx.col + ctx.count >= leaf_wcwidth) {
|
||||||
ctx.count -= leaf_wcwidth - ctx.col;
|
ctx.count -= leaf_wcwidth - ctx.col;
|
||||||
const pos = leaf.width_to_pos(ctx.col, base_col, mtrx) catch |e| return .{ .err = e };
|
const pos = leaf.width_to_pos(ctx.col, base_col, metrics) catch |e| return .{ .err = e };
|
||||||
const leaf_eol = if (leaf.eol and ctx.count > 0) leaf_eol: {
|
const leaf_eol = if (leaf.eol and ctx.count > 0) leaf_eol: {
|
||||||
ctx.count -= 1;
|
ctx.count -= 1;
|
||||||
ctx.delete_next_bol = true;
|
ctx.delete_next_bol = true;
|
||||||
|
@ -664,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 };
|
result.replace = Leaf.new(ctx.a, leaf.buf[0..pos], leaf_bol, leaf_eol) catch |e| return .{ .err = e };
|
||||||
ctx.col = 0;
|
ctx.col = 0;
|
||||||
} else {
|
} else {
|
||||||
const pos = leaf.width_to_pos(ctx.col, base_col, mtrx) catch |e| return .{ .err = e };
|
const pos = leaf.width_to_pos(ctx.col, base_col, metrics) 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 pos_end = leaf.width_to_pos(ctx.col + ctx.count, base_col, metrics) catch |e| return .{ .err = e };
|
||||||
const left = Leaf.new(ctx.a, leaf.buf[0..pos], leaf_bol, false) 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 };
|
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 };
|
result.replace = Node.new(ctx.a, left, right) catch |e| return .{ .err = e };
|
||||||
|
@ -679,7 +679,7 @@ const Node = union(enum) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var ctx: Ctx = .{ .a = a, .col = col, .count = count };
|
var ctx: Ctx = .{ .a = a, .col = col, .count = count };
|
||||||
const found, const root = try self.walk_from_line_begin(a, line, Ctx.walker, &ctx, mtrx_);
|
const found, const root = try self.walk_from_line_begin(a, line, Ctx.walker, &ctx, metrics_);
|
||||||
return if (found) (if (root) |r| r else error.Stop) else error.NotFound;
|
return if (found) (if (root) |r| r else error.Stop) else error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,46 +695,46 @@ const Node = union(enum) {
|
||||||
return Node.new(a, try merge_in_place(leaves[0..mid], a), try merge_in_place(leaves[mid..], a));
|
return Node.new(a, try merge_in_place(leaves[0..mid], a), try merge_in_place(leaves[mid..], a));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_line(self: *const Node, line: usize, result: *ArrayList(u8), mtrx: Metrix) !void {
|
pub fn get_line(self: *const Node, line: usize, result: *ArrayList(u8), metrics: Metrics) !void {
|
||||||
const Ctx = struct {
|
const Ctx = struct {
|
||||||
line: *ArrayList(u8),
|
line: *ArrayList(u8),
|
||||||
fn walker(ctx_: *anyopaque, leaf: *const Leaf, _: Metrix) Walker {
|
fn walker(ctx_: *anyopaque, leaf: *const Leaf, _: Metrics) Walker {
|
||||||
const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_)));
|
const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_)));
|
||||||
ctx.line.appendSlice(leaf.buf) catch |e| return .{ .err = e };
|
ctx.line.appendSlice(leaf.buf) catch |e| return .{ .err = e };
|
||||||
return if (!leaf.eol) Walker.keep_walking else Walker.stop;
|
return if (!leaf.eol) Walker.keep_walking else Walker.stop;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var ctx: Ctx = .{ .line = result };
|
var ctx: Ctx = .{ .line = result };
|
||||||
const found = self.walk_from_line_begin_const(line, Ctx.walker, &ctx, mtrx) catch false;
|
const found = self.walk_from_line_begin_const(line, Ctx.walker, &ctx, metrics) catch false;
|
||||||
return if (!found) error.NotFound;
|
return if (!found) error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn line_width(self: *const Node, line: usize, mtrx_: Metrix) !usize {
|
pub fn line_width(self: *const Node, line: usize, metrics_: Metrics) !usize {
|
||||||
const do = struct {
|
const do = struct {
|
||||||
result: usize = 0,
|
result: usize = 0,
|
||||||
fn walker(ctx: *anyopaque, leaf: *const Leaf, mtrx: Metrix) Walker {
|
fn walker(ctx: *anyopaque, leaf: *const Leaf, metrics: Metrics) Walker {
|
||||||
const do = @as(*@This(), @ptrCast(@alignCast(ctx)));
|
const do = @as(*@This(), @ptrCast(@alignCast(ctx)));
|
||||||
do.result += leaf.width(do.result, mtrx);
|
do.result += leaf.width(do.result, metrics);
|
||||||
return if (!leaf.eol) Walker.keep_walking else Walker.stop;
|
return if (!leaf.eol) Walker.keep_walking else Walker.stop;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var ctx: do = .{};
|
var ctx: do = .{};
|
||||||
const found = self.walk_from_line_begin_const(line, do.walker, &ctx, mtrx_) catch true;
|
const found = self.walk_from_line_begin_const(line, do.walker, &ctx, metrics_) catch true;
|
||||||
return if (found) ctx.result else error.NotFound;
|
return if (found) ctx.result else error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pos_to_width(self: *const Node, line: usize, pos: usize, mtrx_: Metrix) !usize {
|
pub fn pos_to_width(self: *const Node, line: usize, pos: usize, metrics_: Metrics) !usize {
|
||||||
const do = struct {
|
const do = struct {
|
||||||
result: usize = 0,
|
result: usize = 0,
|
||||||
pos: usize,
|
pos: usize,
|
||||||
fn walker(ctx: *anyopaque, leaf: *const Leaf, mtrx: Metrix) Walker {
|
fn walker(ctx: *anyopaque, leaf: *const Leaf, metrics: Metrics) Walker {
|
||||||
const do = @as(*@This(), @ptrCast(@alignCast(ctx)));
|
const do = @as(*@This(), @ptrCast(@alignCast(ctx)));
|
||||||
do.result += leaf.pos_to_width(&do.pos, do.result, mtrx);
|
do.result += leaf.pos_to_width(&do.pos, do.result, metrics);
|
||||||
return if (!(leaf.eol or do.pos == 0)) Walker.keep_walking else Walker.stop;
|
return if (!(leaf.eol or do.pos == 0)) Walker.keep_walking else Walker.stop;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var ctx: do = .{ .pos = pos };
|
var ctx: do = .{ .pos = pos };
|
||||||
const found = self.walk_from_line_begin_const(line, do.walker, &ctx, mtrx_) catch true;
|
const found = self.walk_from_line_begin_const(line, do.walker, &ctx, metrics_) catch true;
|
||||||
return if (found) ctx.result else error.NotFound;
|
return if (found) ctx.result else error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -744,7 +744,7 @@ const Node = union(enum) {
|
||||||
col_: usize,
|
col_: usize,
|
||||||
s: []const u8,
|
s: []const u8,
|
||||||
a: Allocator,
|
a: Allocator,
|
||||||
mtrx_: Metrix,
|
metrics_: Metrics,
|
||||||
) !struct { usize, usize, Root } {
|
) !struct { usize, usize, Root } {
|
||||||
var self = self_;
|
var self = self_;
|
||||||
const Ctx = struct {
|
const Ctx = struct {
|
||||||
|
@ -754,9 +754,9 @@ const Node = union(enum) {
|
||||||
s: []const u8,
|
s: []const u8,
|
||||||
eol: bool,
|
eol: bool,
|
||||||
|
|
||||||
fn walker(ctx: *anyopaque, leaf: *const Leaf, mtrx: Metrix) WalkerMut {
|
fn walker(ctx: *anyopaque, leaf: *const Leaf, metrics: Metrics) WalkerMut {
|
||||||
const Ctx = @as(*@This(), @ptrCast(@alignCast(ctx)));
|
const Ctx = @as(*@This(), @ptrCast(@alignCast(ctx)));
|
||||||
const leaf_wcwidth = leaf.width(Ctx.abs_col, mtrx);
|
const leaf_wcwidth = leaf.width(Ctx.abs_col, metrics);
|
||||||
const base_col = Ctx.abs_col;
|
const base_col = Ctx.abs_col;
|
||||||
Ctx.abs_col += leaf_wcwidth;
|
Ctx.abs_col += leaf_wcwidth;
|
||||||
|
|
||||||
|
@ -788,7 +788,7 @@ const Node = union(enum) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (leaf_wcwidth > Ctx.col) {
|
if (leaf_wcwidth > Ctx.col) {
|
||||||
const pos = leaf.width_to_pos(Ctx.col, base_col, mtrx) catch |e| return .{ .err = e };
|
const pos = leaf.width_to_pos(Ctx.col, base_col, metrics) catch |e| return .{ .err = e };
|
||||||
if (Ctx.eol and Ctx.s.len == 0) {
|
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 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 };
|
const right = Leaf.new(Ctx.a, leaf.buf[pos..], Ctx.eol, leaf.eol) catch |e| return .{ .err = e };
|
||||||
|
@ -825,14 +825,14 @@ const Node = union(enum) {
|
||||||
need_eol = false;
|
need_eol = false;
|
||||||
}
|
}
|
||||||
var ctx: Ctx = .{ .a = a, .col = col, .s = chunk, .eol = need_eol };
|
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, mtrx_);
|
const found, const replace = try self.walk_from_line_begin(a, line, Ctx.walker, &ctx, metrics_);
|
||||||
if (!found) return error.NotFound;
|
if (!found) return error.NotFound;
|
||||||
if (replace) |root| self = root;
|
if (replace) |root| self = root;
|
||||||
if (need_eol) {
|
if (need_eol) {
|
||||||
line += 1;
|
line += 1;
|
||||||
col = 0;
|
col = 0;
|
||||||
} else {
|
} else {
|
||||||
col += mtrx_.egc_chunk_width(mtrx_.ctx, chunk, col);
|
col += metrics_.egc_chunk_width(metrics_.ctx, chunk, col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return .{ line, col, self };
|
return .{ line, col, self };
|
||||||
|
@ -925,19 +925,19 @@ const Node = union(enum) {
|
||||||
return self.store(ctx.writer());
|
return self.store(ctx.writer());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn debug_render_chunks(self: *const Node, line: usize, output: *ArrayList(u8), mtrx_: Metrix) !void {
|
pub fn debug_render_chunks(self: *const Node, line: usize, output: *ArrayList(u8), metrics_: Metrics) !void {
|
||||||
const ctx_ = struct {
|
const ctx_ = struct {
|
||||||
l: *ArrayList(u8),
|
l: *ArrayList(u8),
|
||||||
wcwidth: usize = 0,
|
wcwidth: usize = 0,
|
||||||
fn walker(ctx_: *anyopaque, leaf: *const Leaf, mtrx: Metrix) Walker {
|
fn walker(ctx_: *anyopaque, leaf: *const Leaf, metrics: Metrics) Walker {
|
||||||
const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_)));
|
const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_)));
|
||||||
leaf.dump(ctx.l, ctx.wcwidth, mtrx) catch |e| return .{ .err = e };
|
leaf.dump(ctx.l, ctx.wcwidth, metrics) catch |e| return .{ .err = e };
|
||||||
ctx.wcwidth += leaf.width(ctx.wcwidth, mtrx);
|
ctx.wcwidth += leaf.width(ctx.wcwidth, metrics);
|
||||||
return if (!leaf.eol) Walker.keep_walking else Walker.stop;
|
return if (!leaf.eol) Walker.keep_walking else Walker.stop;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var ctx: ctx_ = .{ .l = output };
|
var ctx: ctx_ = .{ .l = output };
|
||||||
const found = self.walk_from_line_begin_const(line, ctx_.walker, &ctx, mtrx_) catch true;
|
const found = self.walk_from_line_begin_const(line, ctx_.walker, &ctx, metrics_) catch true;
|
||||||
if (!found) return error.NotFound;
|
if (!found) return error.NotFound;
|
||||||
|
|
||||||
var buf: [16]u8 = undefined;
|
var buf: [16]u8 = undefined;
|
||||||
|
|
|
@ -3,7 +3,7 @@ const cbor = @import("cbor");
|
||||||
const Buffer = @import("Buffer.zig");
|
const Buffer = @import("Buffer.zig");
|
||||||
const View = @import("View.zig");
|
const View = @import("View.zig");
|
||||||
const Selection = @import("Selection.zig");
|
const Selection = @import("Selection.zig");
|
||||||
const Metrix = Buffer.Metrix;
|
const Metrics = Buffer.Metrics;
|
||||||
|
|
||||||
row: usize = 0,
|
row: usize = 0,
|
||||||
col: 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;
|
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, mtrx: Metrix) void {
|
pub fn clamp_to_buffer(self: *Self, root: Buffer.Root, metrics: Metrics) void {
|
||||||
self.row = @min(self.row, root.lines() - 1);
|
self.row = @min(self.row, root.lines() - 1);
|
||||||
self.col = @min(self.col, root.line_width(self.row, mtrx) catch 0);
|
self.col = @min(self.col, root.line_width(self.row, metrics) catch 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn follow_target(self: *Self, root: Buffer.Root, mtrx: Metrix) void {
|
fn follow_target(self: *Self, root: Buffer.Root, metrics: Metrics) void {
|
||||||
self.col = @min(self.target, root.line_width(self.row, mtrx) catch 0);
|
self.col = @min(self.target, root.line_width(self.row, metrics) catch 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_right_no_target(self: *Self, root: Buffer.Root, mtrx: Metrix) !void {
|
fn move_right_no_target(self: *Self, root: Buffer.Root, metrics: Metrics) !void {
|
||||||
const lines = root.lines();
|
const lines = root.lines();
|
||||||
if (lines <= self.row) return error.Stop;
|
if (lines <= self.row) return error.Stop;
|
||||||
if (self.col < root.line_width(self.row, mtrx) catch 0) {
|
if (self.col < root.line_width(self.row, metrics) catch 0) {
|
||||||
_, const wcwidth, const offset = root.ecg_at(self.row, self.col, mtrx) catch return error.Stop;
|
_, const wcwidth, const offset = root.ecg_at(self.row, self.col, metrics) catch return error.Stop;
|
||||||
self.col += wcwidth - offset;
|
self.col += wcwidth - offset;
|
||||||
} else if (self.row < lines - 1) {
|
} else if (self.row < lines - 1) {
|
||||||
self.col = 0;
|
self.col = 0;
|
||||||
|
@ -48,73 +48,73 @@ fn move_right_no_target(self: *Self, root: Buffer.Root, mtrx: Metrix) !void {
|
||||||
} else return error.Stop;
|
} else return error.Stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_right(self: *Self, root: Buffer.Root, mtrx: Metrix) !void {
|
pub fn move_right(self: *Self, root: Buffer.Root, metrics: Metrics) !void {
|
||||||
try self.move_right_no_target(root, mtrx);
|
try self.move_right_no_target(root, metrics);
|
||||||
self.target = self.col;
|
self.target = self.col;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_left_no_target(self: *Self, root: Buffer.Root, mtrx: Metrix) !void {
|
fn move_left_no_target(self: *Self, root: Buffer.Root, metrics: Metrics) !void {
|
||||||
if (self.col == 0) {
|
if (self.col == 0) {
|
||||||
if (self.row == 0) return error.Stop;
|
if (self.row == 0) return error.Stop;
|
||||||
self.row -= 1;
|
self.row -= 1;
|
||||||
self.col = root.line_width(self.row, mtrx) catch 0;
|
self.col = root.line_width(self.row, metrics) catch 0;
|
||||||
} else {
|
} else {
|
||||||
_, const wcwidth, _ = root.ecg_at(self.row, self.col - 1, mtrx) catch return error.Stop;
|
_, const wcwidth, _ = root.ecg_at(self.row, self.col - 1, metrics) catch return error.Stop;
|
||||||
if (self.col > wcwidth) self.col -= wcwidth else self.col = 0;
|
if (self.col > wcwidth) self.col -= wcwidth else self.col = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_left(self: *Self, root: Buffer.Root, mtrx: Metrix) !void {
|
pub fn move_left(self: *Self, root: Buffer.Root, metrics: Metrics) !void {
|
||||||
try self.move_left_no_target(root, mtrx);
|
try self.move_left_no_target(root, metrics);
|
||||||
self.target = self.col;
|
self.target = self.col;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_up(self: *Self, root: Buffer.Root, mtrx: Metrix) !void {
|
pub fn move_up(self: *Self, root: Buffer.Root, metrics: Metrics) !void {
|
||||||
if (self.row > 0) {
|
if (self.row > 0) {
|
||||||
self.row -= 1;
|
self.row -= 1;
|
||||||
self.follow_target(root, mtrx);
|
self.follow_target(root, metrics);
|
||||||
self.move_left_no_target(root, mtrx) catch return;
|
self.move_left_no_target(root, metrics) catch return;
|
||||||
try self.move_right_no_target(root, mtrx);
|
try self.move_right_no_target(root, metrics);
|
||||||
} else return error.Stop;
|
} else return error.Stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_down(self: *Self, root: Buffer.Root, mtrx: Metrix) !void {
|
pub fn move_down(self: *Self, root: Buffer.Root, metrics: Metrics) !void {
|
||||||
if (self.row < root.lines() - 1) {
|
if (self.row < root.lines() - 1) {
|
||||||
self.row += 1;
|
self.row += 1;
|
||||||
self.follow_target(root, mtrx);
|
self.follow_target(root, metrics);
|
||||||
self.move_left_no_target(root, mtrx) catch return;
|
self.move_left_no_target(root, metrics) catch return;
|
||||||
try self.move_right_no_target(root, mtrx);
|
try self.move_right_no_target(root, metrics);
|
||||||
} else return error.Stop;
|
} else return error.Stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_page_up(self: *Self, root: Buffer.Root, view: *const View, mtrx: Metrix) void {
|
pub fn move_page_up(self: *Self, root: Buffer.Root, view: *const View, metrics: Metrics) void {
|
||||||
self.row = if (self.row > view.rows) self.row - view.rows else 0;
|
self.row = if (self.row > view.rows) self.row - view.rows else 0;
|
||||||
self.follow_target(root, mtrx);
|
self.follow_target(root, metrics);
|
||||||
self.move_left_no_target(root, mtrx) catch return;
|
self.move_left_no_target(root, metrics) catch return;
|
||||||
self.move_right_no_target(root, mtrx) catch return;
|
self.move_right_no_target(root, metrics) catch return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_page_down(self: *Self, root: Buffer.Root, view: *const View, mtrx: Metrix) void {
|
pub fn move_page_down(self: *Self, root: Buffer.Root, view: *const View, metrics: Metrics) void {
|
||||||
if (root.lines() > self.row + view.rows) {
|
if (root.lines() > self.row + view.rows) {
|
||||||
self.row += view.rows;
|
self.row += view.rows;
|
||||||
} else self.move_buffer_last(root, mtrx);
|
} else self.move_buffer_last(root, metrics);
|
||||||
self.follow_target(root, mtrx);
|
self.follow_target(root, metrics);
|
||||||
self.move_left_no_target(root, mtrx) catch return;
|
self.move_left_no_target(root, metrics) catch return;
|
||||||
self.move_right_no_target(root, mtrx) catch return;
|
self.move_right_no_target(root, metrics) catch return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_to(self: *Self, root: Buffer.Root, row: usize, col: usize, mtrx: Metrix) !void {
|
pub fn move_to(self: *Self, root: Buffer.Root, row: usize, col: usize, metrics: Metrics) !void {
|
||||||
if (row < root.lines()) {
|
if (row < root.lines()) {
|
||||||
self.row = row;
|
self.row = row;
|
||||||
self.col = @min(col, root.line_width(self.row, mtrx) catch return error.Stop);
|
self.col = @min(col, root.line_width(self.row, metrics) catch return error.Stop);
|
||||||
self.target = self.col;
|
self.target = self.col;
|
||||||
} else return error.Stop;
|
} else return error.Stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_abs(self: *Self, root: Buffer.Root, v: *View, y: usize, x: usize, mtrx: Metrix) !void {
|
pub fn move_abs(self: *Self, root: Buffer.Root, v: *View, y: usize, x: usize, metrics: Metrics) !void {
|
||||||
self.row = v.row + y;
|
self.row = v.row + y;
|
||||||
self.col = v.col + x;
|
self.col = v.col + x;
|
||||||
self.clamp_to_buffer(root, mtrx);
|
self.clamp_to_buffer(root, metrics);
|
||||||
self.target = self.col;
|
self.target = self.col;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,8 +123,8 @@ pub fn move_begin(self: *Self) void {
|
||||||
self.target = self.col;
|
self.target = self.col;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_end(self: *Self, root: Buffer.Root, mtrx: Metrix) void {
|
pub fn move_end(self: *Self, root: Buffer.Root, metrics: Metrics) void {
|
||||||
if (self.row < root.lines()) self.col = root.line_width(self.row, mtrx) catch 0;
|
if (self.row < root.lines()) self.col = root.line_width(self.row, metrics) catch 0;
|
||||||
self.target = std.math.maxInt(u32);
|
self.target = std.math.maxInt(u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,32 +134,32 @@ pub fn move_buffer_begin(self: *Self) void {
|
||||||
self.target = 0;
|
self.target = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_buffer_end(self: *Self, root: Buffer.Root, mtrx: Metrix) void {
|
pub fn move_buffer_end(self: *Self, root: Buffer.Root, metrics: Metrics) void {
|
||||||
self.row = root.lines() - 1;
|
self.row = root.lines() - 1;
|
||||||
self.move_end(root, mtrx);
|
self.move_end(root, metrics);
|
||||||
if (self.col == 0) self.target = 0;
|
if (self.col == 0) self.target = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_buffer_first(self: *Self, root: Buffer.Root, mtrx: Metrix) void {
|
fn move_buffer_first(self: *Self, root: Buffer.Root, metrics: Metrics) void {
|
||||||
self.row = 0;
|
self.row = 0;
|
||||||
self.follow_target(root, mtrx);
|
self.follow_target(root, metrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_buffer_last(self: *Self, root: Buffer.Root, mtrx: Metrix) void {
|
fn move_buffer_last(self: *Self, root: Buffer.Root, metrics: Metrics) void {
|
||||||
self.row = root.lines() - 1;
|
self.row = root.lines() - 1;
|
||||||
self.follow_target(root, mtrx);
|
self.follow_target(root, metrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_at_begin(self: *const Self) bool {
|
fn is_at_begin(self: *const Self) bool {
|
||||||
return self.col == 0;
|
return self.col == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_at_end(self: *const Self, root: Buffer.Root, mtrx: Metrix) bool {
|
fn is_at_end(self: *const Self, root: Buffer.Root, metrics: Metrics) bool {
|
||||||
return if (self.row < root.lines()) self.col == root.line_width(self.row, mtrx) catch 0 else true;
|
return if (self.row < root.lines()) self.col == root.line_width(self.row, metrics) catch 0 else true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn test_at(self: *const Self, root: Buffer.Root, pred: *const fn (c: []const u8) bool, mtrx: Metrix) bool {
|
pub fn test_at(self: *const Self, root: Buffer.Root, pred: *const fn (c: []const u8) bool, metrics: Metrics) bool {
|
||||||
return root.test_at(pred, self.row, self.col, mtrx);
|
return root.test_at(pred, self.row, self.col, metrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write(self: *const Self, writer: Buffer.MetaWriter) !void {
|
pub fn write(self: *const Self, writer: Buffer.MetaWriter) !void {
|
||||||
|
|
|
@ -16,7 +16,7 @@ pub fn from_cursor(cursor: *const Cursor) Self {
|
||||||
return .{ .begin = cursor.*, .end = cursor.* };
|
return .{ .begin = cursor.*, .end = cursor.* };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn line_from_cursor(cursor: Cursor, root: Buffer.Root, mtrx: Buffer.Metrix) Self {
|
pub fn line_from_cursor(cursor: Cursor, root: Buffer.Root, mtrx: Buffer.Metrics) Self {
|
||||||
var begin = cursor;
|
var begin = cursor;
|
||||||
var end = cursor;
|
var end = cursor;
|
||||||
begin.move_begin();
|
begin.move_begin();
|
||||||
|
|
|
@ -365,7 +365,7 @@ pub fn egc_chunk_width(self: *const Plane, chunk_: []const u8, abs_col_: usize)
|
||||||
return colcount;
|
return colcount;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn metrix(self: *const Plane) Buffer.Metrix {
|
pub fn metrics(self: *const Plane) Buffer.Metrics {
|
||||||
return .{
|
return .{
|
||||||
.ctx = self,
|
.ctx = self,
|
||||||
.egc_length = struct {
|
.egc_length = struct {
|
||||||
|
|
|
@ -109,8 +109,8 @@ pub const CurSel = struct {
|
||||||
sel.normalize();
|
sel.normalize();
|
||||||
sel.begin.move_begin();
|
sel.begin.move_begin();
|
||||||
if (!(sel.end.row > sel.begin.row and sel.end.col == 0)) {
|
if (!(sel.end.row > sel.begin.row and sel.end.col == 0)) {
|
||||||
sel.end.move_end(root, plane.metrix());
|
sel.end.move_end(root, plane.metrics());
|
||||||
sel.end.move_right(root, plane.metrix()) catch {};
|
sel.end.move_right(root, plane.metrics()) catch {};
|
||||||
}
|
}
|
||||||
return sel;
|
return sel;
|
||||||
}
|
}
|
||||||
|
@ -560,7 +560,7 @@ pub const Editor = struct {
|
||||||
fn find_first_non_ws(root: Buffer.Root, row: usize, plane: Plane) usize {
|
fn find_first_non_ws(root: Buffer.Root, row: usize, plane: Plane) usize {
|
||||||
const Ctx = struct {
|
const Ctx = struct {
|
||||||
col: usize = 0,
|
col: usize = 0,
|
||||||
fn walker(ctx_: *anyopaque, egc: []const u8, wcwidth: usize, _: Buffer.Metrix) Buffer.Walker {
|
fn walker(ctx_: *anyopaque, egc: []const u8, wcwidth: usize, _: Buffer.Metrics) Buffer.Walker {
|
||||||
const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_)));
|
const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_)));
|
||||||
if (egc[0] == ' ' or egc[0] == '\t') {
|
if (egc[0] == ' ' or egc[0] == '\t') {
|
||||||
ctx.col += wcwidth;
|
ctx.col += wcwidth;
|
||||||
|
@ -570,7 +570,7 @@ pub const Editor = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var ctx: Ctx = .{};
|
var ctx: Ctx = .{};
|
||||||
root.walk_egc_forward(row, Ctx.walker, &ctx, plane.metrix()) catch return 0;
|
root.walk_egc_forward(row, Ctx.walker, &ctx, plane.metrics()) catch return 0;
|
||||||
return ctx.col;
|
return ctx.col;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,7 +590,7 @@ pub const Editor = struct {
|
||||||
sel: Selection,
|
sel: Selection,
|
||||||
writer: Writer,
|
writer: Writer,
|
||||||
wcwidth: usize = 0,
|
wcwidth: usize = 0,
|
||||||
fn walker(ctx_: *anyopaque, egc: []const u8, wcwidth: usize, _: Buffer.Metrix) Buffer.Walker {
|
fn walker(ctx_: *anyopaque, egc: []const u8, wcwidth: usize, _: Buffer.Metrics) Buffer.Walker {
|
||||||
const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_)));
|
const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_)));
|
||||||
if (ctx.col < ctx.sel.begin.col) {
|
if (ctx.col < ctx.sel.begin.col) {
|
||||||
ctx.col += wcwidth;
|
ctx.col += wcwidth;
|
||||||
|
@ -617,7 +617,7 @@ pub const Editor = struct {
|
||||||
ctx.sel.normalize();
|
ctx.sel.normalize();
|
||||||
if (sel.begin.eql(sel.end))
|
if (sel.begin.eql(sel.end))
|
||||||
return;
|
return;
|
||||||
root.walk_egc_forward(sel.begin.row, Ctx.walker, &ctx, plane_.metrix()) catch |e| return map_error(e, @errorReturnTrace());
|
root.walk_egc_forward(sel.begin.row, Ctx.walker, &ctx, plane_.metrics()) catch |e| return map_error(e, @errorReturnTrace());
|
||||||
if (wcwidth_) |p| p.* = ctx.wcwidth;
|
if (wcwidth_) |p| p.* = ctx.wcwidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -657,7 +657,7 @@ pub const Editor = struct {
|
||||||
theme: *const Widget.Theme,
|
theme: *const Widget.Theme,
|
||||||
hl_row: ?usize,
|
hl_row: ?usize,
|
||||||
|
|
||||||
fn walker(ctx_: *anyopaque, leaf: *const Buffer.Leaf, _: Buffer.Metrix) Buffer.Walker {
|
fn walker(ctx_: *anyopaque, leaf: *const Buffer.Leaf, _: Buffer.Metrics) Buffer.Walker {
|
||||||
const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_)));
|
const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_)));
|
||||||
const self_ = ctx.self;
|
const self_ = ctx.self;
|
||||||
const view = self_.view;
|
const view = self_.view;
|
||||||
|
@ -750,7 +750,7 @@ pub const Editor = struct {
|
||||||
if (hl_row) |_|
|
if (hl_row) |_|
|
||||||
self.render_line_highlight(&self.get_primary().cursor, theme) catch {};
|
self.render_line_highlight(&self.get_primary().cursor, theme) catch {};
|
||||||
self.plane.home();
|
self.plane.home();
|
||||||
_ = root.walk_from_line_begin_const(self.view.row, ctx.walker, &ctx_, self.plane.metrix()) catch {};
|
_ = root.walk_from_line_begin_const(self.view.row, ctx.walker, &ctx_, self.plane.metrics()) catch {};
|
||||||
}
|
}
|
||||||
self.render_syntax(theme, cache, root) catch {};
|
self.render_syntax(theme, cache, root) catch {};
|
||||||
self.render_diagnostics(theme, hl_row) catch {};
|
self.render_diagnostics(theme, hl_row) catch {};
|
||||||
|
@ -1440,7 +1440,7 @@ pub const Editor = struct {
|
||||||
if (self.syntax) |syn| {
|
if (self.syntax) |syn| {
|
||||||
const root = self.buf_root() catch return;
|
const root = self.buf_root() catch return;
|
||||||
var start_byte: usize = 0;
|
var start_byte: usize = 0;
|
||||||
_ = root.get_range(.{ .begin = .{}, .end = nudge.begin }, null, &start_byte, null, self.plane.metrix()) catch return;
|
_ = root.get_range(.{ .begin = .{}, .end = nudge.begin }, null, &start_byte, null, self.plane.metrics()) catch return;
|
||||||
syn.edit(.{
|
syn.edit(.{
|
||||||
.start_byte = @intCast(start_byte),
|
.start_byte = @intCast(start_byte),
|
||||||
.old_end_byte = @intCast(start_byte),
|
.old_end_byte = @intCast(start_byte),
|
||||||
|
@ -1472,7 +1472,7 @@ pub const Editor = struct {
|
||||||
cursel.cursor = sel.begin;
|
cursel.cursor = sel.begin;
|
||||||
cursel.selection = null;
|
cursel.selection = null;
|
||||||
var size: usize = 0;
|
var size: usize = 0;
|
||||||
const root_ = try root.delete_range(sel, a, &size, self.plane.metrix());
|
const root_ = try root.delete_range(sel, a, &size, self.plane.metrics());
|
||||||
self.nudge_delete(sel, cursel, size);
|
self.nudge_delete(sel, cursel, size);
|
||||||
return root_;
|
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 {
|
fn is_word_char_at_cursor(root: Buffer.Root, cursor: *const Cursor, plane: Plane) bool {
|
||||||
return cursor.test_at(root, is_word_char, plane.metrix());
|
return cursor.test_at(root, is_word_char, plane.metrics());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_non_word_char_at_cursor(root: Buffer.Root, cursor: *const Cursor, plane: Plane) bool {
|
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.metrix());
|
return cursor.test_at(root, is_not_word_char, plane.metrics());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_word_boundary_left(root: Buffer.Root, cursor: *const Cursor, plane: Plane) bool {
|
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))
|
if (is_non_word_char_at_cursor(root, cursor, plane))
|
||||||
return false;
|
return false;
|
||||||
var next = cursor.*;
|
var next = cursor.*;
|
||||||
next.move_left(root, plane.metrix()) catch return true;
|
next.move_left(root, plane.metrics()) catch return true;
|
||||||
if (is_non_word_char_at_cursor(root, &next, plane))
|
if (is_non_word_char_at_cursor(root, &next, plane))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
|
@ -1564,33 +1564,33 @@ pub const Editor = struct {
|
||||||
if (is_word_char_at_cursor(root, cursor, plane))
|
if (is_word_char_at_cursor(root, cursor, plane))
|
||||||
return false;
|
return false;
|
||||||
var next = cursor.*;
|
var next = cursor.*;
|
||||||
next.move_left(root, plane.metrix()) catch return true;
|
next.move_left(root, plane.metrics()) catch return true;
|
||||||
if (is_word_char_at_cursor(root, &next, plane))
|
if (is_word_char_at_cursor(root, &next, plane))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_word_boundary_right(root: Buffer.Root, cursor: *const Cursor, plane: Plane) bool {
|
fn is_word_boundary_right(root: Buffer.Root, cursor: *const Cursor, plane: Plane) bool {
|
||||||
const line_width = root.line_width(cursor.row, plane.metrix()) catch return true;
|
const line_width = root.line_width(cursor.row, plane.metrics()) catch return true;
|
||||||
if (cursor.col >= line_width)
|
if (cursor.col >= line_width)
|
||||||
return true;
|
return true;
|
||||||
if (is_non_word_char_at_cursor(root, cursor, plane))
|
if (is_non_word_char_at_cursor(root, cursor, plane))
|
||||||
return false;
|
return false;
|
||||||
var next = cursor.*;
|
var next = cursor.*;
|
||||||
next.move_right(root, plane.metrix()) catch return true;
|
next.move_right(root, plane.metrics()) catch return true;
|
||||||
if (is_non_word_char_at_cursor(root, &next, plane))
|
if (is_non_word_char_at_cursor(root, &next, plane))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_non_word_boundary_right(root: Buffer.Root, cursor: *const Cursor, plane: Plane) bool {
|
fn is_non_word_boundary_right(root: Buffer.Root, cursor: *const Cursor, plane: Plane) bool {
|
||||||
const line_width = root.line_width(cursor.row, plane.metrix()) catch return true;
|
const line_width = root.line_width(cursor.row, plane.metrics()) catch return true;
|
||||||
if (cursor.col >= line_width)
|
if (cursor.col >= line_width)
|
||||||
return true;
|
return true;
|
||||||
if (is_word_char_at_cursor(root, cursor, plane))
|
if (is_word_char_at_cursor(root, cursor, plane))
|
||||||
return false;
|
return false;
|
||||||
var next = cursor.*;
|
var next = cursor.*;
|
||||||
next.move_right(root, plane.metrix()) catch return true;
|
next.move_right(root, plane.metrics()) catch return true;
|
||||||
if (is_word_char_at_cursor(root, &next, plane))
|
if (is_word_char_at_cursor(root, &next, plane))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
|
@ -1603,14 +1603,14 @@ pub const Editor = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_eol_right(root: Buffer.Root, cursor: *const Cursor, plane: Plane) bool {
|
fn is_eol_right(root: Buffer.Root, cursor: *const Cursor, plane: Plane) bool {
|
||||||
const line_width = root.line_width(cursor.row, plane.metrix()) catch return true;
|
const line_width = root.line_width(cursor.row, plane.metrics()) catch return true;
|
||||||
if (cursor.col >= line_width)
|
if (cursor.col >= line_width)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_eol_right_vim(root: Buffer.Root, cursor: *const Cursor, plane: Plane) bool {
|
fn is_eol_right_vim(root: Buffer.Root, cursor: *const Cursor, plane: Plane) bool {
|
||||||
const line_width = root.line_width(cursor.row, plane.metrix()) catch return true;
|
const line_width = root.line_width(cursor.row, plane.metrics()) catch return true;
|
||||||
if (line_width == 0) return true;
|
if (line_width == 0) return true;
|
||||||
if (cursor.col >= line_width - 1)
|
if (cursor.col >= line_width - 1)
|
||||||
return true;
|
return true;
|
||||||
|
@ -1618,7 +1618,7 @@ pub const Editor = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_cursor_left(root: Buffer.Root, cursor: *Cursor, plane: Plane) error{Stop}!void {
|
fn move_cursor_left(root: Buffer.Root, cursor: *Cursor, plane: Plane) error{Stop}!void {
|
||||||
try cursor.move_left(root, plane.metrix());
|
try cursor.move_left(root, plane.metrics());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_cursor_left_until(root: Buffer.Root, cursor: *Cursor, pred: cursor_predicate, plane: Plane) void {
|
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 {
|
fn smart_move_cursor_begin(root: Buffer.Root, cursor: *Cursor, plane: Plane) !void {
|
||||||
const first = find_first_non_ws(root, cursor.row, plane);
|
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.metrix());
|
return if (cursor.col == first) cursor.move_begin() else cursor.move_to(root, cursor.row, first, plane.metrics());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_cursor_right(root: Buffer.Root, cursor: *Cursor, plane: Plane) error{Stop}!void {
|
fn move_cursor_right(root: Buffer.Root, cursor: *Cursor, plane: Plane) error{Stop}!void {
|
||||||
try cursor.move_right(root, plane.metrix());
|
try cursor.move_right(root, plane.metrics());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_cursor_right_until(root: Buffer.Root, cursor: *Cursor, pred: cursor_predicate, plane: Plane) void {
|
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 {
|
fn move_cursor_end(root: Buffer.Root, cursor: *Cursor, plane: Plane) !void {
|
||||||
cursor.move_end(root, plane.metrix());
|
cursor.move_end(root, plane.metrics());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_cursor_up(root: Buffer.Root, cursor: *Cursor, plane: Plane) !void {
|
fn move_cursor_up(root: Buffer.Root, cursor: *Cursor, plane: Plane) !void {
|
||||||
try cursor.move_up(root, plane.metrix());
|
try cursor.move_up(root, plane.metrics());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_cursor_down(root: Buffer.Root, cursor: *Cursor, plane: Plane) !void {
|
fn move_cursor_down(root: Buffer.Root, cursor: *Cursor, plane: Plane) !void {
|
||||||
try cursor.move_down(root, plane.metrix());
|
try cursor.move_down(root, plane.metrics());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_cursor_buffer_begin(_: Buffer.Root, cursor: *Cursor, _: Plane) !void {
|
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 {
|
fn move_cursor_buffer_end(root: Buffer.Root, cursor: *Cursor, plane: Plane) !void {
|
||||||
cursor.move_buffer_end(root, plane.metrix());
|
cursor.move_buffer_end(root, plane.metrics());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_cursor_page_up(root: Buffer.Root, cursor: *Cursor, view: *const View, plane: Plane) !void {
|
fn move_cursor_page_up(root: Buffer.Root, cursor: *Cursor, view: *const View, plane: Plane) !void {
|
||||||
cursor.move_page_up(root, view, plane.metrix());
|
cursor.move_page_up(root, view, plane.metrics());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_cursor_page_down(root: Buffer.Root, cursor: *Cursor, view: *const View, plane: Plane) !void {
|
fn move_cursor_page_down(root: Buffer.Root, cursor: *Cursor, view: *const View, plane: Plane) !void {
|
||||||
cursor.move_page_down(root, view, plane.metrix());
|
cursor.move_page_down(root, view, plane.metrics());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn primary_click(self: *Self, y: c_int, x: c_int) !void {
|
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;
|
self.selection_mode = .char;
|
||||||
try self.send_editor_jump_source();
|
try self.send_editor_jump_source();
|
||||||
const root = self.buf_root() catch return;
|
const root = self.buf_root() catch return;
|
||||||
primary.cursor.move_abs(root, &self.view, @intCast(y), @intCast(x), self.plane.metrix()) catch return;
|
primary.cursor.move_abs(root, &self.view, @intCast(y), @intCast(x), self.plane.metrics()) catch return;
|
||||||
self.clamp_mouse();
|
self.clamp_mouse();
|
||||||
try self.send_editor_jump_destination();
|
try self.send_editor_jump_destination();
|
||||||
if (self.jump_mode) try self.goto_definition(.{});
|
if (self.jump_mode) try self.goto_definition(.{});
|
||||||
|
@ -1703,7 +1703,7 @@ pub const Editor = struct {
|
||||||
primary.selection = null;
|
primary.selection = null;
|
||||||
self.selection_mode = .word;
|
self.selection_mode = .word;
|
||||||
const root = self.buf_root() catch return;
|
const root = self.buf_root() catch return;
|
||||||
primary.cursor.move_abs(root, &self.view, @intCast(y), @intCast(x), self.plane.metrix()) catch return;
|
primary.cursor.move_abs(root, &self.view, @intCast(y), @intCast(x), self.plane.metrics()) catch return;
|
||||||
_ = try self.select_word_at_cursor(primary);
|
_ = try self.select_word_at_cursor(primary);
|
||||||
self.clamp_mouse();
|
self.clamp_mouse();
|
||||||
}
|
}
|
||||||
|
@ -1713,7 +1713,7 @@ pub const Editor = struct {
|
||||||
primary.selection = null;
|
primary.selection = null;
|
||||||
self.selection_mode = .line;
|
self.selection_mode = .line;
|
||||||
const root = self.buf_root() catch return;
|
const root = self.buf_root() catch return;
|
||||||
primary.cursor.move_abs(root, &self.view, @intCast(y), @intCast(x), self.plane.metrix()) catch return;
|
primary.cursor.move_abs(root, &self.view, @intCast(y), @intCast(x), self.plane.metrics()) catch return;
|
||||||
try self.select_line_at_cursor(primary);
|
try self.select_line_at_cursor(primary);
|
||||||
self.clamp_mouse();
|
self.clamp_mouse();
|
||||||
}
|
}
|
||||||
|
@ -1724,7 +1724,7 @@ pub const Editor = struct {
|
||||||
const primary = self.get_primary();
|
const primary = self.get_primary();
|
||||||
const sel = primary.enable_selection();
|
const sel = primary.enable_selection();
|
||||||
const root = self.buf_root() catch return;
|
const root = self.buf_root() catch return;
|
||||||
sel.end.move_abs(root, &self.view, @intCast(y_), @intCast(x_), self.plane.metrix()) catch return;
|
sel.end.move_abs(root, &self.view, @intCast(y_), @intCast(x_), self.plane.metrics()) catch return;
|
||||||
switch (self.selection_mode) {
|
switch (self.selection_mode) {
|
||||||
.char => {},
|
.char => {},
|
||||||
.word => if (sel.begin.right_of(sel.end))
|
.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 {
|
fn copy_selection(root: Buffer.Root, sel: Selection, text_a: Allocator, plane: Plane) ![]const u8 {
|
||||||
var size: usize = 0;
|
var size: usize = 0;
|
||||||
_ = try root.get_range(sel, null, &size, null, plane.metrix());
|
_ = try root.get_range(sel, null, &size, null, plane.metrics());
|
||||||
const buf__ = try text_a.alloc(u8, size);
|
const buf__ = try text_a.alloc(u8, size);
|
||||||
return (try root.get_range(sel, buf__, null, null, plane.metrix())).?;
|
return (try root.get_range(sel, buf__, null, null, plane.metrics())).?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_selection(self: *const Self, sel: Selection, text_a: Allocator) ![]const u8 {
|
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;
|
var root_ = if (cursel.selection) |_| try self.delete_selection(root, cursel, a) else root;
|
||||||
const cursor = &cursel.cursor;
|
const cursor = &cursel.cursor;
|
||||||
const begin = cursel.cursor;
|
const begin = cursel.cursor;
|
||||||
cursor.row, cursor.col, root_ = try root_.insert_chars(cursor.row, cursor.col, s, a, self.plane.metrix());
|
cursor.row, cursor.col, root_ = try root_.insert_chars(cursor.row, cursor.col, s, a, self.plane.metrics());
|
||||||
cursor.target = cursor.col;
|
cursor.target = cursor.col;
|
||||||
self.nudge_insert(.{ .begin = begin, .end = cursor.* }, cursel, s.len);
|
self.nudge_insert(.{ .begin = begin, .end = cursor.* }, cursel, s.len);
|
||||||
return root_;
|
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 {
|
fn move_cursor_word_left_space(root: Buffer.Root, cursor: *Cursor, plane: Plane) error{Stop}!void {
|
||||||
try move_cursor_left(root, cursor, plane);
|
try move_cursor_left(root, cursor, plane);
|
||||||
var next = cursor.*;
|
var next = cursor.*;
|
||||||
next.move_left(root, plane.metrix()) catch
|
next.move_left(root, plane.metrics()) catch
|
||||||
return move_cursor_left_until(root, cursor, is_word_boundary_left, plane);
|
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))
|
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)
|
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 {
|
pub fn move_cursor_word_right_space(root: Buffer.Root, cursor: *Cursor, plane: Plane) error{Stop}!void {
|
||||||
var next = cursor.*;
|
var next = cursor.*;
|
||||||
next.move_right(root, plane.metrix()) catch {
|
next.move_right(root, plane.metrics()) catch {
|
||||||
move_cursor_right_until(root, cursor, is_word_boundary_right, plane);
|
move_cursor_right_until(root, cursor, is_word_boundary_right, plane);
|
||||||
try move_cursor_right(root, cursor, plane);
|
try move_cursor_right(root, cursor, plane);
|
||||||
return;
|
return;
|
||||||
|
@ -2182,7 +2182,7 @@ pub const Editor = struct {
|
||||||
return error.Stop;
|
return error.Stop;
|
||||||
try move_cursor_left(root, cursor, plane);
|
try move_cursor_left(root, cursor, plane);
|
||||||
while (true) {
|
while (true) {
|
||||||
const curr_egc, _, _ = root.ecg_at(cursor.row, cursor.col, plane.metrix()) catch return error.Stop;
|
const curr_egc, _, _ = root.ecg_at(cursor.row, cursor.col, plane.metrics()) catch return error.Stop;
|
||||||
if (std.mem.eql(u8, curr_egc, egc))
|
if (std.mem.eql(u8, curr_egc, egc))
|
||||||
return;
|
return;
|
||||||
if (is_eol_left(root, cursor, plane))
|
if (is_eol_left(root, cursor, plane))
|
||||||
|
@ -2197,7 +2197,7 @@ pub const Editor = struct {
|
||||||
return error.Stop;
|
return error.Stop;
|
||||||
try move_cursor_right(root, cursor, plane);
|
try move_cursor_right(root, cursor, plane);
|
||||||
while (true) {
|
while (true) {
|
||||||
const curr_egc, _, _ = root.ecg_at(cursor.row, cursor.col, plane.metrix()) catch return error.Stop;
|
const curr_egc, _, _ = root.ecg_at(cursor.row, cursor.col, plane.metrics()) catch return error.Stop;
|
||||||
if (std.mem.eql(u8, curr_egc, egc))
|
if (std.mem.eql(u8, curr_egc, egc))
|
||||||
return;
|
return;
|
||||||
if (is_eol_right(root, cursor, plane))
|
if (is_eol_right(root, cursor, plane))
|
||||||
|
@ -2258,7 +2258,7 @@ pub const Editor = struct {
|
||||||
const root = self.buf_root() catch return;
|
const root = self.buf_root() catch return;
|
||||||
primary.selection = match.to_selection();
|
primary.selection = match.to_selection();
|
||||||
match.has_selection = true;
|
match.has_selection = true;
|
||||||
primary.cursor.move_to(root, match.end.row, match.end.col, self.plane.metrix()) catch return;
|
primary.cursor.move_to(root, match.end.row, match.end.col, self.plane.metrics()) catch return;
|
||||||
}
|
}
|
||||||
self.clamp();
|
self.clamp();
|
||||||
try self.send_editor_jump_destination();
|
try self.send_editor_jump_destination();
|
||||||
|
@ -2273,7 +2273,7 @@ pub const Editor = struct {
|
||||||
const root = self.buf_root() catch return;
|
const root = self.buf_root() catch return;
|
||||||
primary.selection = match.to_selection();
|
primary.selection = match.to_selection();
|
||||||
match.has_selection = true;
|
match.has_selection = true;
|
||||||
primary.cursor.move_to(root, match.end.row, match.end.col, self.plane.metrix()) catch return;
|
primary.cursor.move_to(root, match.end.row, match.end.col, self.plane.metrics()) catch return;
|
||||||
}
|
}
|
||||||
self.clamp();
|
self.clamp();
|
||||||
try self.send_editor_jump_destination();
|
try self.send_editor_jump_destination();
|
||||||
|
@ -2292,7 +2292,7 @@ pub const Editor = struct {
|
||||||
.col = 0,
|
.col = 0,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
new_cursel.*.?.cursor.move_end(root, self.plane.metrix());
|
new_cursel.*.?.cursor.move_end(root, self.plane.metrics());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2314,13 +2314,13 @@ pub const Editor = struct {
|
||||||
const cut_text = copy_selection(root, sel.*, sfa.get(), self.plane) catch return error.Stop;
|
const cut_text = copy_selection(root, sel.*, sfa.get(), self.plane) catch return error.Stop;
|
||||||
defer a.free(cut_text);
|
defer a.free(cut_text);
|
||||||
root = try self.delete_selection(root, cursel, a);
|
root = try self.delete_selection(root, cursel, a);
|
||||||
try cursel.cursor.move_up(root, self.plane.metrix());
|
try cursel.cursor.move_up(root, self.plane.metrics());
|
||||||
root = self.insert(root, cursel, cut_text, a) catch return error.Stop;
|
root = self.insert(root, cursel, cut_text, a) catch return error.Stop;
|
||||||
cursel.* = saved;
|
cursel.* = saved;
|
||||||
try cursel.cursor.move_up(root, self.plane.metrix());
|
try cursel.cursor.move_up(root, self.plane.metrics());
|
||||||
if (cursel.selection) |*sel_| {
|
if (cursel.selection) |*sel_| {
|
||||||
try sel_.begin.move_up(root, self.plane.metrix());
|
try sel_.begin.move_up(root, self.plane.metrics());
|
||||||
try sel_.end.move_up(root, self.plane.metrix());
|
try sel_.end.move_up(root, self.plane.metrics());
|
||||||
}
|
}
|
||||||
return root;
|
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;
|
const cut_text = copy_selection(root, sel.*, sfa.get(), self.plane) catch return error.Stop;
|
||||||
defer a.free(cut_text);
|
defer a.free(cut_text);
|
||||||
root = try self.delete_selection(root, cursel, a);
|
root = try self.delete_selection(root, cursel, a);
|
||||||
try cursel.cursor.move_down(root, self.plane.metrix());
|
try cursel.cursor.move_down(root, self.plane.metrics());
|
||||||
root = self.insert(root, cursel, cut_text, a) catch return error.Stop;
|
root = self.insert(root, cursel, cut_text, a) catch return error.Stop;
|
||||||
cursel.* = saved;
|
cursel.* = saved;
|
||||||
try cursel.cursor.move_down(root, self.plane.metrix());
|
try cursel.cursor.move_down(root, self.plane.metrics());
|
||||||
if (cursel.selection) |*sel_| {
|
if (cursel.selection) |*sel_| {
|
||||||
try sel_.begin.move_down(root, self.plane.metrix());
|
try sel_.begin.move_down(root, self.plane.metrics());
|
||||||
try sel_.end.move_down(root, self.plane.metrix());
|
try sel_.end.move_down(root, self.plane.metrics());
|
||||||
}
|
}
|
||||||
return root;
|
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 {
|
fn dupe_cursel_up(self: *Self, root_: Buffer.Root, cursel: *CurSel, a: Allocator) error{Stop}!Buffer.Root {
|
||||||
var root = root_;
|
var root = root_;
|
||||||
const sel: Selection = if (cursel.selection) |sel_| sel_ else Selection.line_from_cursor(cursel.cursor, root, self.plane.metrix());
|
const sel: Selection = if (cursel.selection) |sel_| sel_ else Selection.line_from_cursor(cursel.cursor, root, self.plane.metrics());
|
||||||
cursel.selection = null;
|
cursel.selection = null;
|
||||||
var sfa = std.heap.stackFallback(4096, self.a);
|
var sfa = std.heap.stackFallback(4096, self.a);
|
||||||
const text = copy_selection(root, sel, sfa.get(), self.plane) catch return error.Stop;
|
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 {
|
fn dupe_cursel_down(self: *Self, root_: Buffer.Root, cursel: *CurSel, a: Allocator) error{Stop}!Buffer.Root {
|
||||||
var root = root_;
|
var root = root_;
|
||||||
const sel: Selection = if (cursel.selection) |sel_| sel_ else Selection.line_from_cursor(cursel.cursor, root, self.plane.metrix());
|
const sel: Selection = if (cursel.selection) |sel_| sel_ else Selection.line_from_cursor(cursel.cursor, root, self.plane.metrics());
|
||||||
cursel.selection = null;
|
cursel.selection = null;
|
||||||
var sfa = std.heap.stackFallback(4096, self.a);
|
var sfa = std.heap.stackFallback(4096, self.a);
|
||||||
const text = copy_selection(root, sel, sfa.get(), self.plane) catch return error.Stop;
|
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;
|
var newroot = root;
|
||||||
defer {
|
defer {
|
||||||
cursel.* = saved;
|
cursel.* = saved;
|
||||||
cursel.cursor.clamp_to_buffer(newroot, self.plane.metrix());
|
cursel.cursor.clamp_to_buffer(newroot, self.plane.metrics());
|
||||||
}
|
}
|
||||||
cursel.selection = null;
|
cursel.selection = null;
|
||||||
cursel.cursor = cursor;
|
cursel.cursor = cursor;
|
||||||
|
@ -2474,8 +2474,8 @@ pub const Editor = struct {
|
||||||
const cols = if (off == 0) 4 else off;
|
const cols = if (off == 0) 4 else off;
|
||||||
const sel = cursel.enable_selection();
|
const sel = cursel.enable_selection();
|
||||||
sel.begin.move_begin();
|
sel.begin.move_begin();
|
||||||
try sel.end.move_to(root, sel.end.row, cols, self.plane.metrix());
|
try sel.end.move_to(root, sel.end.row, cols, self.plane.metrics());
|
||||||
if (cursel.cursor.col < cols) try cursel.cursor.move_to(root, cursel.cursor.row, cols, self.plane.metrix());
|
if (cursel.cursor.col < cols) try cursel.cursor.move_to(root, cursel.cursor.row, cols, self.plane.metrics());
|
||||||
newroot = try self.delete_selection(root, cursel, a);
|
newroot = try self.delete_selection(root, cursel, a);
|
||||||
return newroot;
|
return newroot;
|
||||||
}
|
}
|
||||||
|
@ -2589,7 +2589,7 @@ pub const Editor = struct {
|
||||||
try self.send_editor_jump_source();
|
try self.send_editor_jump_source();
|
||||||
self.cancel_all_selections();
|
self.cancel_all_selections();
|
||||||
const root = self.buf_root() catch return;
|
const root = self.buf_root() catch return;
|
||||||
self.get_primary().cursor.move_buffer_end(root, self.plane.metrix());
|
self.get_primary().cursor.move_buffer_end(root, self.plane.metrics());
|
||||||
self.clamp();
|
self.clamp();
|
||||||
try self.send_editor_jump_destination();
|
try self.send_editor_jump_destination();
|
||||||
}
|
}
|
||||||
|
@ -2928,7 +2928,7 @@ pub const Editor = struct {
|
||||||
const primary = self.get_primary();
|
const primary = self.get_primary();
|
||||||
var tree = std.ArrayList(u8).init(self.a);
|
var tree = std.ArrayList(u8).init(self.a);
|
||||||
defer tree.deinit();
|
defer tree.deinit();
|
||||||
root.debug_render_chunks(primary.cursor.row, &tree, self.plane.metrix()) catch |e|
|
root.debug_render_chunks(primary.cursor.row, &tree, self.plane.metrics()) catch |e|
|
||||||
return self.logger.print("line {d}: {any}", .{ primary.cursor.row, 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) });
|
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 root = self.buf_root() catch return;
|
||||||
const begin_line = begin_line_ - 1;
|
const begin_line = begin_line_ - 1;
|
||||||
const end_line = end_line_ - 1;
|
const end_line = end_line_ - 1;
|
||||||
const begin_pos = root.pos_to_width(begin_line, begin_pos_, self.plane.metrix()) catch return;
|
const begin_pos = root.pos_to_width(begin_line, begin_pos_, self.plane.metrics()) catch return;
|
||||||
const end_pos = root.pos_to_width(end_line, end_pos_, self.plane.metrix()) catch return;
|
const end_pos = root.pos_to_width(end_line, end_pos_, self.plane.metrics()) catch return;
|
||||||
var match: Match = .{ .begin = .{ .row = begin_line, .col = begin_pos }, .end = .{ .row = end_line, .col = end_pos } };
|
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))
|
if (match.end.eql(self.get_primary().cursor))
|
||||||
match.has_selection = true;
|
match.has_selection = true;
|
||||||
|
@ -3241,7 +3241,7 @@ pub const Editor = struct {
|
||||||
if (self.scan_prev_match(cursor)) |match| return match;
|
if (self.scan_prev_match(cursor)) |match| return match;
|
||||||
const root = self.buf_root() catch return null;
|
const root = self.buf_root() catch return null;
|
||||||
var cursor_ = cursor;
|
var cursor_ = cursor;
|
||||||
cursor_.move_buffer_end(root, self.plane.metrix());
|
cursor_.move_buffer_end(root, self.plane.metrics());
|
||||||
return self.scan_prev_match(cursor_);
|
return self.scan_prev_match(cursor_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3253,7 +3253,7 @@ pub const Editor = struct {
|
||||||
match_.has_selection = false;
|
match_.has_selection = false;
|
||||||
};
|
};
|
||||||
primary.selection = match.to_selection();
|
primary.selection = match.to_selection();
|
||||||
primary.cursor.move_to(root, match.end.row, match.end.col, self.plane.metrix()) catch return;
|
primary.cursor.move_to(root, match.end.row, match.end.col, self.plane.metrics()) catch return;
|
||||||
self.clamp();
|
self.clamp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3280,7 +3280,7 @@ pub const Editor = struct {
|
||||||
};
|
};
|
||||||
primary.selection = match.to_selection();
|
primary.selection = match.to_selection();
|
||||||
primary.selection.?.reverse();
|
primary.selection.?.reverse();
|
||||||
primary.cursor.move_to(root, match.begin.row, match.begin.col, self.plane.metrix()) catch return;
|
primary.cursor.move_to(root, match.begin.row, match.begin.col, self.plane.metrics()) catch return;
|
||||||
self.clamp();
|
self.clamp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3327,7 +3327,7 @@ pub const Editor = struct {
|
||||||
const primary = self.get_primary();
|
const primary = self.get_primary();
|
||||||
try self.send_editor_jump_source();
|
try self.send_editor_jump_source();
|
||||||
self.cancel_all_selections();
|
self.cancel_all_selections();
|
||||||
try primary.cursor.move_to(root, diag.sel.begin.row, diag.sel.begin.col, self.plane.metrix());
|
try primary.cursor.move_to(root, diag.sel.begin.row, diag.sel.begin.col, self.plane.metrics());
|
||||||
self.clamp();
|
self.clamp();
|
||||||
try self.send_editor_jump_destination();
|
try self.send_editor_jump_destination();
|
||||||
}
|
}
|
||||||
|
@ -3352,7 +3352,7 @@ pub const Editor = struct {
|
||||||
const root = self.buf_root() catch return;
|
const root = self.buf_root() catch return;
|
||||||
self.cancel_all_selections();
|
self.cancel_all_selections();
|
||||||
const primary = self.get_primary();
|
const primary = self.get_primary();
|
||||||
try primary.cursor.move_to(root, @intCast(if (line < 1) 0 else line - 1), primary.cursor.col, self.plane.metrix());
|
try primary.cursor.move_to(root, @intCast(if (line < 1) 0 else line - 1), primary.cursor.col, self.plane.metrics());
|
||||||
self.clamp();
|
self.clamp();
|
||||||
try self.send_editor_jump_destination();
|
try self.send_editor_jump_destination();
|
||||||
}
|
}
|
||||||
|
@ -3363,7 +3363,7 @@ pub const Editor = struct {
|
||||||
return error.InvalidArgument;
|
return error.InvalidArgument;
|
||||||
const root = self.buf_root() catch return;
|
const root = self.buf_root() catch return;
|
||||||
const primary = self.get_primary();
|
const primary = self.get_primary();
|
||||||
try primary.cursor.move_to(root, primary.cursor.row, @intCast(if (column < 1) 0 else column - 1), self.plane.metrix());
|
try primary.cursor.move_to(root, primary.cursor.row, @intCast(if (column < 1) 0 else column - 1), self.plane.metrics());
|
||||||
self.clamp();
|
self.clamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3396,7 +3396,7 @@ pub const Editor = struct {
|
||||||
root,
|
root,
|
||||||
@intCast(if (line < 1) 0 else line - 1),
|
@intCast(if (line < 1) 0 else line - 1),
|
||||||
@intCast(if (column < 1) 0 else column - 1),
|
@intCast(if (column < 1) 0 else column - 1),
|
||||||
self.plane.metrix(),
|
self.plane.metrics(),
|
||||||
);
|
);
|
||||||
if (have_sel) primary.selection = sel;
|
if (have_sel) primary.selection = sel;
|
||||||
if (self.view.is_visible(&primary.cursor))
|
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 self.write_range(state.before_root, sel, buffer.writer(), tp.exit_error, null, self.plane);
|
||||||
try buffer.flush();
|
try buffer.flush();
|
||||||
self.logger.print("filter: sent", .{});
|
self.logger.print("filter: sent", .{});
|
||||||
state.work_root = try state.work_root.delete_range(sel, buf_a_, null, self.plane.metrix());
|
state.work_root = try state.work_root.delete_range(sel, buf_a_, null, self.plane.metrics());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter_stdout(self: *Self, bytes: []const u8) !void {
|
fn filter_stdout(self: *Self, bytes: []const u8) !void {
|
||||||
|
@ -3549,7 +3549,7 @@ pub const Editor = struct {
|
||||||
try buf.appendSlice(bytes);
|
try buf.appendSlice(bytes);
|
||||||
} else {
|
} else {
|
||||||
const cursor = &state.pos.cursor;
|
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.metrix());
|
cursor.row, cursor.col, state.work_root = try state.work_root.insert_chars(cursor.row, cursor.col, bytes, buf_a_, self.plane.metrics());
|
||||||
state.bytes += bytes.len;
|
state.bytes += bytes.len;
|
||||||
state.chunks += 1;
|
state.chunks += 1;
|
||||||
}
|
}
|
||||||
|
@ -3582,7 +3582,7 @@ pub const Editor = struct {
|
||||||
primary.cursor = sel.end;
|
primary.cursor = sel.end;
|
||||||
}
|
}
|
||||||
try self.update_buf(state.work_root);
|
try self.update_buf(state.work_root);
|
||||||
primary.cursor.clamp_to_buffer(state.work_root, self.plane.metrix());
|
primary.cursor.clamp_to_buffer(state.work_root, self.plane.metrics());
|
||||||
self.logger.print("filter: done (bytes:{d} chunks:{d})", .{ state.bytes, state.chunks });
|
self.logger.print("filter: done (bytes:{d} chunks:{d})", .{ state.bytes, state.chunks });
|
||||||
self.reset_syntax();
|
self.reset_syntax();
|
||||||
self.clamp();
|
self.clamp();
|
||||||
|
@ -3879,10 +3879,10 @@ pub const PosToWidthCache = struct {
|
||||||
self.cache.clearRetainingCapacity();
|
self.cache.clearRetainingCapacity();
|
||||||
self.cached_line = start.row;
|
self.cached_line = start.row;
|
||||||
self.cached_root = root;
|
self.cached_root = root;
|
||||||
root.get_line_width_map(self.cached_line, &self.cache, plane.metrix()) catch return null;
|
root.get_line_width_map(self.cached_line, &self.cache, plane.metrics()) catch return null;
|
||||||
}
|
}
|
||||||
const start_col = if (start.column < self.cache.items.len) self.cache.items[start.column] else start.column;
|
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.metrix()) 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.metrics()) catch end.column;
|
||||||
return .{ .begin = .{ .row = start.row, .col = start_col }, .end = .{ .row = end.row, .col = end_col } };
|
return .{ .begin = .{ .row = start.row, .col = start_col }, .end = .{ .row = end.row, .col = end_col } };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 {
|
fn get_buffer_text(self: *Self, buf: []u8, sel: Buffer.Selection) ?[]const u8 {
|
||||||
const root = self.editor.get_current_root() orelse return null;
|
const root = self.editor.get_current_root() orelse return null;
|
||||||
return root.get_range(sel, buf, null, null, self.plane.metrix()) catch return null;
|
return root.get_range(sel, buf, null, null, self.plane.metrics()) 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 {
|
fn dump_highlight(self: *Self, range: syntax.Range, scope: []const u8, id: u32, _: usize, ast_node: *const syntax.Node) error{Stop}!void {
|
||||||
|
|
|
@ -4,7 +4,7 @@ const Buffer = @import("Buffer");
|
||||||
const ArrayList = std.ArrayList;
|
const ArrayList = std.ArrayList;
|
||||||
const a = std.testing.allocator;
|
const a = std.testing.allocator;
|
||||||
|
|
||||||
fn metrics() Buffer.Metrix {
|
fn metrics() Buffer.Metrics {
|
||||||
return .{
|
return .{
|
||||||
.ctx = undefined,
|
.ctx = undefined,
|
||||||
.egc_length = struct {
|
.egc_length = struct {
|
||||||
|
|
Loading…
Add table
Reference in a new issue