Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions packages/core/src/renderables/EditBufferRenderable.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,28 @@ describe("EditBufferRenderable", () => {
expect(textarea.cursorOffset).toBe(6)
})

test("tracks the cursor and viewport past 65535 columns", async () => {
const textarea = new TextareaRenderable(renderer, {
width: 20,
height: 3,
wrapMode: "none",
})

renderer.root.add(textarea)
await renderOnce()

const length = 70000
textarea.insertText("x".repeat(length))
await renderOnce()

expect(textarea.logicalCursor).toMatchObject({ row: 0, col: length, offset: length })
expect(textarea.visualCursor.offset).toBe(length)

const viewport = textarea.editorView.getViewport()
expect(viewport.offsetX).toBeLessThanOrEqual(length)
expect(viewport.offsetX + viewport.width).toBeGreaterThan(length)
})

test("goes to exact current line boundaries through renderable api", async () => {
const textarea = new TextareaRenderable(renderer, {
width: 20,
Expand Down
8 changes: 2 additions & 6 deletions packages/core/src/zig/bench/text-chunk-graphemes_bench.zig
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,11 @@ fn benchGetGraphemes(
else => false,
};

// Create TextChunk
// Width is approximate - clamped to u16 max
const approx_width: u16 = @intCast(@min(text.len, std.math.maxInt(u16)));
var chunk: TextChunk = .{
.mem_id = mem_id,
.byte_start = 0,
.byte_end = @intCast(text.len),
.width = approx_width,
.width = @intCast(text.len),
.flags = if (is_ascii) TextChunk.Flags.ASCII_ONLY else 0,
};

Expand Down Expand Up @@ -186,12 +183,11 @@ fn computeBenchName(allocator: std.mem.Allocator, size: usize, text_type: TextTy
.ascii => true,
else => false,
};
const approx_width: u16 = @intCast(@min(text.len, std.math.maxInt(u16)));
var chunk: TextChunk = .{
.mem_id = mem_id,
.byte_start = 0,
.byte_end = @intCast(text.len),
.width = approx_width,
.width = @intCast(text.len),
.flags = if (is_ascii) TextChunk.Flags.ASCII_ONLY else 0,
};

Expand Down
21 changes: 19 additions & 2 deletions packages/core/src/zig/tests/text-buffer_test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1559,8 +1559,25 @@ test "TextBuffer setText - CRLF at SIMD boundary" {
try std.testing.expectEqual(expected_len, written);
}

test "TextBuffer setText - line with multiple u16-sized chunks (SKIPPED)" {
return error.SkipZigTest;
test "TextBuffer setText - line width past u16 maximum" {
const pool = gp.initGlobalPool(std.testing.allocator);
defer gp.deinitGlobalPool();
const link_pool = link.initGlobalLinkPool(std.testing.allocator);
defer link.deinitGlobalLinkPool();

var tb = try TextBuffer.init(std.testing.allocator, pool, link_pool, .unicode);
defer tb.deinit();

const length: u32 = std.math.maxInt(u16) + 1;
const text = try std.testing.allocator.alloc(u8, length);
defer std.testing.allocator.free(text);
@memset(text, 'x');

try tb.setText(text);

try std.testing.expectEqual(length, iter_mod.lineWidthAt(tb.rope(), 0));
try std.testing.expectEqual(length, iter_mod.coordsToOffset(tb.rope(), 0, length).?);
try std.testing.expectEqual(iter_mod.Coords{ .row = 0, .col = length }, iter_mod.offsetToCoords(tb.rope(), length).?);
}

test "TextBuffer setText - validate rope structure is correct" {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/zig/text-buffer-segment.zig
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub const TextChunk = struct {
mem_id: u8,
byte_start: u32,
byte_end: u32,
width: u16,
width: u32,
flags: u8 = 0,
graphemes: ?[]GraphemeInfo = null,
wrap_offsets: ?[]utf8.WrapBreak = null,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/zig/text-buffer-view.zig
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ pub const UnifiedTextBufferView = struct {
fn calculateChunkFitWord(self: *const Self, chunk: *const TextChunk, char_offset_in_chunk: u32, max_width: u32) tb.ChunkFitResult {
if (max_width == 0) return .{ .char_count = 0, .width = 0 };

const total_width = @as(u32, chunk.width) - char_offset_in_chunk;
const total_width = chunk.width - char_offset_in_chunk;
if (total_width == 0) return .{ .char_count = 0, .width = 0 };
if (total_width <= max_width) return .{ .char_count = total_width, .width = total_width };

Expand Down
4 changes: 1 addition & 3 deletions packages/core/src/zig/text-buffer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -524,13 +524,11 @@ pub const UnifiedTextBuffer = struct {
flags |= TextChunk.Flags.ASCII_ONLY;
}

const chunk_width: u16 = @intCast(@min(65535, utf8.calculateTextWidth(chunk_bytes, self.tab_width, is_ascii, self.width_method)));

return .{
.mem_id = mem_id,
.byte_start = byte_start,
.byte_end = byte_end,
.width = chunk_width,
.width = utf8.calculateTextWidth(chunk_bytes, self.tab_width, is_ascii, self.width_method),
.flags = flags,
};
}
Expand Down
Loading