or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

changes.mdcharacter-utils.mdeditor-state.mdextensions.mdindex.mdrange-sets.mdselection.mdtext.mdtransactions.md
tile.json

text.mddocs/

Text Document

Immutable text document data structure with efficient operations for large documents and line-based access.

Capabilities

Text Class

The abstract Text class provides an immutable representation of document content with efficient operations for large documents.

/**
 * The data structure for documents. All instances are immutable.
 */
abstract class Text {
  /** Create a Text instance from an array of lines */
  static of(text: string[]): Text;
  
  /** Create an empty text document */
  static empty: Text;
  
  /** The length of the string */
  readonly length: number;
  
  /** The number of lines in the string (always >= 1) */
  readonly lines: number;
  
  /** Get the line description around the given position */
  lineAt(pos: number): Line;
  
  /** Get the description for the given (1-based) line number */
  line(n: number): Line;
  
  /** Replace a range of the text with the given content */
  replace(from: number, to: number, text: Text): Text;
  
  /** Append another document to this one */
  append(other: Text): Text;
  
  /** Retrieve the text between the given points */
  slice(from: number, to?: number): Text;
  
  /** Retrieve a part of the document as a string */
  sliceString(from: number, to?: number, lineSep?: string): string;
  
  /** Test whether this text is equal to another instance */
  eq(other: Text): boolean;
  
  /** Iterate over the document content */
  [Symbol.iterator](): Iterator<string>;
}

interface Line {
  /** The start position of the line */
  readonly from: number;
  /** The end position of the line (excluding line break) */
  readonly to: number;
  /** The 1-based line number */
  readonly number: number;
  /** The text content of the line (excluding line break) */
  readonly text: string;
}

Usage Examples:

import { Text } from "@codemirror/state";

// Create text from lines
const doc = Text.of([
  "First line",
  "Second line",
  "Third line"
]);

console.log(doc.length); // Total character count
console.log(doc.lines);  // 3

// Access lines
const firstLine = doc.line(1);
console.log(firstLine.text); // "First line"
console.log(firstLine.from); // 0
console.log(firstLine.to);   // 10

// Get line at position
const lineAtPos = doc.lineAt(15);
console.log(lineAtPos.number); // 2
console.log(lineAtPos.text);   // "Second line"

// Extract text content
const substring = doc.sliceString(0, 10);
console.log(substring); // "First line"

// Replace content
const newDoc = doc.replace(0, 5, Text.of(["Hello"]));
console.log(newDoc.sliceString(0, 20)); // "Hello line\nSecond line"

Text Operations

Methods for manipulating and querying text content.

/**
 * Replace a range of the text with the given content
 * @param from Start position
 * @param to End position  
 * @param text Replacement text
 */
replace(from: number, to: number, text: Text): Text;

/**
 * Append another document to this one
 * @param other Text to append
 */
append(other: Text): Text;

/**
 * Retrieve the text between the given points
 * @param from Start position (default: 0)
 * @param to End position (default: document length)
 */
slice(from: number, to?: number): Text;

/**
 * Retrieve a part of the document as a string
 * @param from Start position (default: 0)
 * @param to End position (default: document length)
 * @param lineSep Line separator to use in output
 */
sliceString(from: number, to?: number, lineSep?: string): string;

/**
 * Test whether this text is equal to another instance
 * @param other Text to compare with
 */
eq(other: Text): boolean;

Usage Examples:

const doc = Text.of(["Hello", "world"]);

// Replace text
const replaced = doc.replace(0, 5, Text.of(["Hi"]));
console.log(replaced.toString()); // "Hi\nworld"

// Append text
const appended = doc.append(Text.of(["!", "More text"]));
console.log(appended.toString()); // "Hello\nworld\n!\nMore text"

// Slice text
const slice = doc.slice(2, 8);
console.log(slice.toString()); // "llo\nwo"

// Get string representation
const str = doc.sliceString(0, 5, " | ");
console.log(str); // "Hello"

// Compare texts
const doc2 = Text.of(["Hello", "world"]);
console.log(doc.eq(doc2)); // true

Line Access

Methods for accessing line information within the document.

/**
 * Get the line description around the given position
 * @param pos Character position within the document
 */
lineAt(pos: number): Line;

/**
 * Get the description for the given (1-based) line number
 * @param n Line number (1-based)
 */
line(n: number): Line;

Usage Examples:

const doc = Text.of([
  "First line",
  "Second line with more content",
  "Third line"
]);

// Access by line number
const line2 = doc.line(2);
console.log(line2.text);   // "Second line with more content"
console.log(line2.number); // 2
console.log(line2.from);   // 11 (position after "First line\n")
console.log(line2.to);     // 39 (end of second line)

// Access by position
const lineAtPos = doc.lineAt(15); // Position within second line
console.log(lineAtPos.number); // 2
console.log(lineAtPos.text);   // "Second line with more content"

// First line
const firstLine = doc.lineAt(0);
console.log(firstLine.number); // 1
console.log(firstLine.from);   // 0
console.log(firstLine.to);     // 10

Text Iteration

The Text class implements the Iterable interface for iterating over document content.

/**
 * Text iterator iterates over a sequence of strings. When iterating over a Text document,
 * result values will either be lines or line breaks.
 */
interface TextIterator extends Iterator<string> {
  /** Retrieve the next string */
  next(skip?: number): this;
  /** The current string */
  value: string;
  /** Whether the end of the iteration has been reached */
  done: boolean;
  /** Whether the current string represents a line break */
  lineBreak: boolean;
}

Usage Examples:

const doc = Text.of(["Line 1", "Line 2", "Line 3"]);

// Iterate using for...of
for (const chunk of doc) {
  console.log(chunk); // "Line 1", "\n", "Line 2", "\n", "Line 3"
}

// Manual iteration
const iter = doc[Symbol.iterator]() as TextIterator;
let result = iter.next();
while (!result.done) {
  console.log(`Content: "${result.value}", LineBreak: ${result.lineBreak}`);
  result = iter.next();
}

Types

/**
 * Information about a line in a document
 */
interface Line {
  /** The start position of the line in the document */
  readonly from: number;
  /** The end position of the line (not including the line break) */
  readonly to: number;
  /** The 1-based line number */
  readonly number: number;
  /** The text content of the line (not including the line break) */
  readonly text: string;
}

/**
 * A text iterator for iterating over document content
 */
interface TextIterator extends Iterator<string>, Iterable<string> {
  next(skip?: number): this;
  value: string;
  done: boolean;
  lineBreak: boolean;
}