Release everything the buffer owns.
since 0.31.0
#import "Extensions/Text_Buffer";
An editable UTF-8 text buffer with undo, for editors. A jaic extension, not official Jai: other Jai compilers have no such module, and it may change between jaic releases. See docs/extensions/text-buffer.md.
The text lives in a piece table: the loaded file is never copied or modified, typed text is appended to a second buffer, and the document is a list of pieces pointing into the two. Editing splits and trims pieces, so inserting or deleting in a large file costs the number of pieces, not the size of the file. Line starts are kept in a sorted array, so lines are found by binary search.
#import "Extensions/Text_Buffer";
buffer: Text_Buffer;
defer free_buffer(*buffer);
set_text(*buffer, "hello\nworld");
insert(*buffer, 5, ", there"); // "hello, there\nworld"
erase(*buffer, 0, 1); // "ello, there\nworld"
line := line_text(*buffer, 1); // "world", a view into the buffer
undo(*buffer); // back to "hello, there\nworld"Show moreShow less
Offsets are byte offsets. Positions inside a UTF-8 sequence are the caller's concern: use
next_grapheme and previous_grapheme (graphemes.jai) to move on character boundaries.
Procedures#
General#
Replace the whole text (and forget undo history). The text is copied.
Number of lines: one more than the newlines, so an empty buffer has one empty line.
Offset of the first byte of line (clamped to the last line).
Offset just past the last byte of line, before its newline.
The line that contains offset (the last line for an offset at the end).
The byte at offset, or 0 outside the text.
The text of line without its line break. It points into the buffer when the line lies within
one piece, and is a copy in temporary storage otherwise; either way it is valid only until the
next edit.
The bytes start to end (exclusive). Points into the buffer when the range lies within one
piece, otherwise a copy in temporary storage; valid until the next edit.
A copy of the bytes start to end (exclusive) made with allocator.
The whole text as a new string made with allocator.
Insert text at offset (clamped to the text). Recorded for undo; typing one character after
another merges into a single undo step.
Delete count bytes starting at offset (clamped to the text). Recorded for undo.
Replace count bytes at offset with text as one undo step.
Search for needle from from; returns the offset of the first match or -1. Matches across
pieces are found.
Graphemes#
The byte offset after the grapheme cluster that starts at index in text. Returns
text.count at the end, and index itself when it is already there.
The byte offset where the grapheme cluster that ends at index starts. Returns 0 at the start.
The class of a code point for word movement: runs of one class are a word.
The byte offset where the word to the right of index ends: spaces are skipped, then a run of
word characters or of punctuation. Stops at the end of the text; line breaks are the caller's.
The byte offset where the word to the left of index starts.
Number of grapheme clusters in text.
Decode the code point at index: its value and its length in bytes. Malformed bytes decode as
U+FFFD, one byte at a time, so scanning always advances.
Start of the code point that ends at index.
History#
Release the history's stacks and the text of every edit in them.
Start an undo group: every edit until the matching end_group undoes as one step. Groups nest.
End the group started by begin_group.
Stop the next typed character from merging into the previous undo step. Call it when the cursor moves, so undo steps follow what the user did.
Whether undo has anything to undo.
Whether redo has anything to redo.
Undo the last step. Returns whether anything was undone and the offset the cursor belongs at.
Redo the last undone step. Returns whether anything was redone and the offset the cursor belongs at.
Types#
A run of bytes in one of the buffer's two backing arrays; the text is the pieces in order.
The text being edited. Zero is an empty buffer; release it with free_buffer.
What a code point counts as when moving by words.
One recorded change: removed was replaced by inserted at offset. Edits with the same
group undo together.
A buffer's undo and redo stacks; zero is empty. Use undo, redo, begin_group and
end_group rather than reading it.