TextApi

TextDocument

The central document model. Backed by a piece table for O(log n) mutations with minimal allocation. Every edit is tracked for undo/redo.

Navigation: Overview API Reference Examples Cursors

Construction

// Default constructor — empty document, plain-text tokenizer
var doc = new TextDocument();

// With a custom syntax tokenizer
var doc = new TextDocument(myTokeniser);

Loading Content

Method Description
Load(string content, string? filePath = null) Load from a string. Resets undo stack and change tracker. Throws ArgumentNullException if content is null.
async Task LoadFileAsync(string path, Encoding? enc = null) Load from a file. Auto-detects encoding (BOM, UTF-8, Latin-1) and EOL style (LF, CRLF, CR) unless overridden.
doc.Load("Hello\nWorld");
await doc.LoadFileAsync("/path/to/file.cs");

Properties

Property Type Description
Length int Total character count (not bytes).
LineCount int Number of lines.
IsModified bool True if the document has unsaved changes.
FilePath string? Path set during LoadFileAsync or passed to Load.
LanguageId string Language identifier from the active tokenizer (e.g. "csharp").
OriginalEolStyle EolStyle EOL style detected on load.
SaveEolStyle EolStyle EOL style used when saving. Defaults to OriginalEolStyle.
DetectedEncoding DetectedEncoding? Encoding detected on load (null for string loads).
HasBom bool True if the loaded file had a BOM.
SaveEncoding Encoding? Override the save encoding. Null = preserve original.
EnforceReadOnly bool If true, mutations inside read-only regions throw ReadOnlyViolationException. Default: true.

Reading Text

Method Description
GetText() Full document text (normalised LF).
GetText(int offset, int length) Substring of the document.
GetTextWithEol() Full text using the document’s original/save EOL style.
GetLine(int lineIndex) Text of line lineIndex (0-based), without the newline character.

Position Conversion

// offset → (line, column) — both zero-based
var (line, col) = doc.OffsetToPosition(42);

// (line, column) → offset
int offset = doc.PositionToOffset(2, 5);

Mutations

All mutations are recorded for undo/redo. Single-grapheme edits are coalesced into groups automatically (like a keyboard-driven editor). Multi-character programmatic edits create their own undo step.

Method Description
Insert(int offset, string text) Insert text at a byte offset. Throws ArgumentNullException if text is null.
Delete(int offset, int length) Delete length characters starting at offset.
Replace(int offset, int deleteLength, string insertText) Delete then insert in a single undo unit. Throws ArgumentNullException if insertText is null.
ReplaceAll(string pattern, string replacement, SearchOptions? opts) Global find-and-replace. Returns replacement count. O(n) via Boyer-Moore-Horspool.
ExecuteComposite(string description, IEnumerable<IEditorCommand> commands) Run multiple editor commands as a single named undo unit.

Undo / Redo

if (doc.CanUndo) doc.Undo();
if (doc.CanRedo) doc.Redo();

// Inspect available undo/redo steps
foreach (var desc in doc.UndoDescriptions)
	Console.WriteLine(desc);

doc.FlushUndoGroup(); // close the current coalescing group

See Undo / Redo for full details.

var opts = new SearchOptions { CaseSensitive = false, UseRegex = true };

// Find all matches
foreach (var m in doc.FindAll(@"\bTODO\b", opts))
	Console.WriteLine($"  at offset {m.Offset}, length {m.Length}");

// Find next / prev from a position
var next = doc.FindNext("hello", fromOffset: 0);
var prev = doc.FindPrev("hello", beforeOffset: doc.Length);

// Count without returning matches
int count = doc.CountMatches("TODO");

See Search for the full API.

Saving

// Save to stream (preserves detected encoding + EOL by default)
await doc.SaveAsync(stream);

// Save to file path (uses FilePath if path is null)
await doc.SaveFileAsync("/output/file.txt");

// Override encoding for this save only
doc.SaveEncoding = System.Text.Encoding.UTF8;
await doc.SaveFileAsync();

Decorations

using TextAPI.Core.Decorations;

Guid id = doc.AddDecoration(start: 0, end: 5, DecorationType.ErrorSquiggle, tag: "CS0101");
doc.RemoveDecoration(id);

foreach (var d in doc.GetDecorationsInRange(0, 100))
	Console.WriteLine($"{d.Type} [{d.Start},{d.End})");

See Decorations.

Statistics

var stats = doc.GetStats();
// stats.CharCount, WordCount, LineCount, ParagraphCount, ...

Performance Notes