Editing Trees โ
What you'll learn โ
- The six fields of
InputEditand what each one means. - How
applyEditshifts stored positions.
The six fields โ
| Field | Meaning |
|---|---|
start_byte | Where the change begins (old and new text agree before this) |
old_end_byte | Where the replaced old text ended |
new_end_byte | Where the replacement new text ends |
start_point | Row/column of start_byte |
old_end_point | Row/column of old_end_byte in the old text |
new_end_point | Row/column of new_end_byte in the new text |
For a pure insertion, start_byte == old_end_byte. For a pure deletion, start_byte == new_end_byte.
Complete example โ
zig
treesitter.applyEdit(&tree, .{
.start_byte = 0,
.old_end_byte = 0,
.new_end_byte = 4,
.start_point = .{},
.old_end_point = .{},
.new_end_point = .{ .row = 0, .column = 4 },
});
// tree.rootNode().startByte() == 4, endByte() == 9How it works โ
applyEdit rewrites every stored node position through the edit:
- Bytes before
start_byteare untouched. - Bytes at or after
old_end_byteshift bynew โ oldlength delta. - Bytes inside the edited span clamp to the new span.
- Points translate with the same rules, row-aware: positions before the start point keep their row, positions after the old end shift rows, and columns on the edited rows rebase onto the new end column.
When to use this โ
Call applyEdit when you keep a tree around while its source changes and want its positions to stay meaningful โ for example, to map cursor positions before reparsing. Parser.parse does its own translation internally, so the edit-and-reparse flow does not require a prior applyEdit.
