feat: add Buffer.Node.byte_offset_to_line_and_col and testcase
This commit is contained in:
parent
1658c9e3b4
commit
935b178d89
2 changed files with 70 additions and 0 deletions
|
@ -794,6 +794,35 @@ const Node = union(enum) {
|
||||||
return if (found) ctx.result else error.NotFound;
|
return if (found) ctx.result else error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn byte_offset_to_line_and_col(self: *const Node, pos: usize, metrics: Metrics, eol_mode: EolMode) Cursor {
|
||||||
|
const ctx_ = struct {
|
||||||
|
pos: usize,
|
||||||
|
line: usize = 0,
|
||||||
|
col: usize = 0,
|
||||||
|
eol_mode: EolMode,
|
||||||
|
fn walker(ctx_: *anyopaque, egc: []const u8, wcwidth: usize, _: Metrics) Walker {
|
||||||
|
const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_)));
|
||||||
|
if (egc[0] == '\n') {
|
||||||
|
ctx.pos -= switch (ctx.eol_mode) {
|
||||||
|
.lf => 1,
|
||||||
|
.crlf => @min(2, ctx.pos),
|
||||||
|
};
|
||||||
|
if (ctx.pos == 0) return Walker.stop;
|
||||||
|
ctx.line += 1;
|
||||||
|
ctx.col = 0;
|
||||||
|
} else {
|
||||||
|
ctx.pos -= @min(egc.len, ctx.pos);
|
||||||
|
if (ctx.pos == 0) return Walker.stop;
|
||||||
|
ctx.col += wcwidth;
|
||||||
|
}
|
||||||
|
return Walker.keep_walking;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var ctx: ctx_ = .{ .pos = pos + 1, .eol_mode = eol_mode };
|
||||||
|
self.walk_egc_forward(0, ctx_.walker, &ctx, metrics) catch {};
|
||||||
|
return .{ .row = ctx.line, .col = ctx.col };
|
||||||
|
}
|
||||||
|
|
||||||
pub fn insert_chars(
|
pub fn insert_chars(
|
||||||
self_: *const Node,
|
self_: *const Node,
|
||||||
line_: usize,
|
line_: usize,
|
||||||
|
|
|
@ -414,3 +414,44 @@ test "get_from_pos" {
|
||||||
const result3 = buffer.root.get_from_pos(.{ .row = 1, .col = 5 }, &result_buf, metrics());
|
const result3 = buffer.root.get_from_pos(.{ .row = 1, .col = 5 }, &result_buf, metrics());
|
||||||
try std.testing.expectEqualDeep(result3[0 .. line1.len - 4], line1[4..]);
|
try std.testing.expectEqualDeep(result3[0 .. line1.len - 4], line1[4..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "byte_offset_to_line_and_col" {
|
||||||
|
const doc: []const u8 =
|
||||||
|
\\All your
|
||||||
|
\\ropes
|
||||||
|
\\are belong to
|
||||||
|
\\us!
|
||||||
|
\\All your
|
||||||
|
\\ropes
|
||||||
|
\\are belong to
|
||||||
|
\\us!
|
||||||
|
\\All your
|
||||||
|
\\ropes
|
||||||
|
\\are belong to
|
||||||
|
\\us!
|
||||||
|
;
|
||||||
|
var eol_mode: Buffer.EolMode = .lf;
|
||||||
|
var sanitized: bool = false;
|
||||||
|
const buffer = try Buffer.create(a);
|
||||||
|
defer buffer.deinit();
|
||||||
|
buffer.update(try buffer.load_from_string(doc, &eol_mode, &sanitized));
|
||||||
|
|
||||||
|
try std.testing.expectEqual(Buffer.Cursor{ .row = 0, .col = 0 }, buffer.root.byte_offset_to_line_and_col(0, metrics(), eol_mode));
|
||||||
|
try std.testing.expectEqual(Buffer.Cursor{ .row = 0, .col = 8 }, buffer.root.byte_offset_to_line_and_col(8, metrics(), eol_mode));
|
||||||
|
try std.testing.expectEqual(Buffer.Cursor{ .row = 1, .col = 0 }, buffer.root.byte_offset_to_line_and_col(9, metrics(), eol_mode));
|
||||||
|
try std.testing.expectEqual(Buffer.Cursor{ .row = 1, .col = 2 }, buffer.root.byte_offset_to_line_and_col(11, metrics(), eol_mode));
|
||||||
|
try std.testing.expectEqual(Buffer.Cursor{ .row = 4, .col = 0 }, buffer.root.byte_offset_to_line_and_col(33, metrics(), eol_mode));
|
||||||
|
try std.testing.expectEqual(Buffer.Cursor{ .row = 8, .col = 0 }, buffer.root.byte_offset_to_line_and_col(66, metrics(), eol_mode));
|
||||||
|
try std.testing.expectEqual(Buffer.Cursor{ .row = 11, .col = 2 }, buffer.root.byte_offset_to_line_and_col(97, metrics(), eol_mode));
|
||||||
|
|
||||||
|
eol_mode = .crlf;
|
||||||
|
|
||||||
|
try std.testing.expectEqual(Buffer.Cursor{ .row = 0, .col = 0 }, buffer.root.byte_offset_to_line_and_col(0, metrics(), eol_mode));
|
||||||
|
try std.testing.expectEqual(Buffer.Cursor{ .row = 0, .col = 8 }, buffer.root.byte_offset_to_line_and_col(8, metrics(), eol_mode));
|
||||||
|
try std.testing.expectEqual(Buffer.Cursor{ .row = 0, .col = 8 }, buffer.root.byte_offset_to_line_and_col(9, metrics(), eol_mode));
|
||||||
|
try std.testing.expectEqual(Buffer.Cursor{ .row = 1, .col = 0 }, buffer.root.byte_offset_to_line_and_col(10, metrics(), eol_mode));
|
||||||
|
try std.testing.expectEqual(Buffer.Cursor{ .row = 1, .col = 2 }, buffer.root.byte_offset_to_line_and_col(12, metrics(), eol_mode));
|
||||||
|
try std.testing.expectEqual(Buffer.Cursor{ .row = 4, .col = 0 }, buffer.root.byte_offset_to_line_and_col(37, metrics(), eol_mode));
|
||||||
|
try std.testing.expectEqual(Buffer.Cursor{ .row = 8, .col = 0 }, buffer.root.byte_offset_to_line_and_col(74, metrics(), eol_mode));
|
||||||
|
try std.testing.expectEqual(Buffer.Cursor{ .row = 11, .col = 2 }, buffer.root.byte_offset_to_line_and_col(108, metrics(), eol_mode));
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue