Unicode & Positions β
What you'll learn β
- Why byte offsets are the source of truth and how points relate to them.
Byte offset, code point, row, column β
These are four different things:
| Concept | Meaning | Example in "aΓ©δΈb" |
|---|---|---|
| Byte offset | Index into the UTF-8 bytes | Γ© starts at 1, δΈ at 3, b at 6 |
| Code point | One Unicode scalar value | 4 code points, 7 bytes |
| Row | Zero-based line number | Newlines increment it |
| Column | Byte offset within the line | Counts bytes, not characters |
The parser tracks bytes exactly and advances points per byte (\n starts a new row). It never decodes the whole source up front; UTF-8 is decoded only where character semantics are needed.
Complete example β
const unicode = treesitter.unicode_types;
const r = try unicode.decodeOne("Γ©"); // code_point 0xE9, len 2
var buf: [4]u8 = undefined;
const enc = unicode.encodeOne(0x20AC, &buf); // "β¬", 3 bytesInvalid sequences (Truncated, InvalidStart, InvalidContinuation, Overlong, Surrogate, TooLarge) are reported as errors; the lexer substitutes the replacement character and continues.
UTF-16 input β
Input values may carry .utf16_le / .utf16_be encodings. UTF-16 is transcoded to UTF-8 up front (matching BOM stripped, conflicting BOM rejected as UnexpectedBOM, lone surrogates and truncation rejected) β tree offsets then refer to the UTF-8 form. .custom is treated as raw UTF-8 bytes. Run zig build run-utf16_parse:
parsed utf16: 1 + 2 error=falseSee treesitter.transcodeUtf16ToUtf8 and Input.
