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

index.mddocs/

CodeMirror State

CodeMirror State provides immutable data structures for representing editor state in the CodeMirror code editor. It implements the core state management system including document content, selections, and extensions through a functional, transaction-based architecture.

Package Information

  • Package Name: @codemirror/state
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @codemirror/state

Core Imports

import { 
  EditorState, 
  EditorSelection, 
  Transaction, 
  Text,
  ChangeSet,
  StateField,
  Facet
} from "@codemirror/state";

For CommonJS:

const { 
  EditorState, 
  EditorSelection, 
  Transaction, 
  Text,
  ChangeSet,
  StateField,
  Facet
} = require("@codemirror/state");

Basic Usage

import { EditorState, EditorSelection, Text } from "@codemirror/state";

// Create an initial editor state
const state = EditorState.create({
  doc: "Hello, world!\nThis is CodeMirror.",
  selection: EditorSelection.single(0)
});

// Create a transaction to modify the state
const transaction = state.update({
  changes: { from: 0, to: 5, insert: "Hi" },
  selection: EditorSelection.single(2)
});

// Apply the transaction to get a new state
const newState = transaction.state;

console.log(newState.doc.toString()); // "Hi, world!\nThis is CodeMirror."
console.log(newState.selection.main.head); // 2

Architecture

CodeMirror State is built around several key architectural principles:

  • Immutability: All state objects are immutable; updates create new instances
  • Transaction Model: Changes are batched into transactions that can include multiple modifications
  • Extension System: Facets and StateFields provide a flexible plugin architecture
  • Functional Updates: State changes are described functionally rather than imperatively
  • Position Mapping: Automatic position tracking through document changes
  • Range Sets: Efficient data structures for managing document decorations and markers

Capabilities

Editor State Management

Core editor state functionality for creating and managing immutable editor states with document content, selections, and configuration.

class EditorState {
  static create(config?: EditorStateConfig): EditorState;
  update(...specs: readonly TransactionSpec[]): Transaction;
  readonly doc: Text;
  readonly selection: EditorSelection;
}

interface EditorStateConfig {
  doc?: string | Text;
  selection?: EditorSelection | {anchor: number, head?: number};
  extensions?: Extension;
}

Editor State

Document Text Management

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

abstract class Text {
  static of(text: string[]): Text;
  readonly length: number;
  readonly lines: number;
  lineAt(pos: number): Line;
  line(n: number): Line;
  sliceString(from: number, to?: number, lineSep?: string): string;
}

interface Line {
  readonly from: number;
  readonly to: number;
  readonly number: number;
  readonly text: string;
}

Text Document

Selection Management

Selection system supporting single and multiple selection ranges with cursor positioning and range operations.

class EditorSelection {
  static single(pos: number): EditorSelection;
  static cursor(pos: number, assoc?: number, bidiLevel?: number, goalColumn?: number): EditorSelection;
  static range(anchor: number, head?: number, goalColumn?: number, bidiLevel?: number): EditorSelection;
  static create(ranges: readonly SelectionRange[], mainIndex?: number): EditorSelection;
  readonly ranges: readonly SelectionRange[];
  readonly main: SelectionRange;
  map(change: ChangeDesc, assoc?: number): EditorSelection;
}

class SelectionRange {
  readonly from: number;
  readonly to: number;
  readonly anchor: number;
  readonly head: number;
  readonly empty: boolean;
}

Selection Management

Transaction System

Transaction-based state updates that bundle document changes, selection updates, and side effects into atomic operations.

class Transaction {
  readonly startState: EditorState;
  readonly state: EditorState;
  readonly changes: ChangeSet;
  readonly selection: EditorSelection;
  readonly effects: readonly StateEffect<any>[];
  readonly annotations: readonly Annotation<any>[];
  readonly docChanged: boolean;
  readonly reconfigured: boolean;
}

interface TransactionSpec {
  changes?: ChangeSpec;
  selection?: EditorSelection | {anchor: number, head?: number};
  effects?: StateEffect<any> | readonly StateEffect<any>[];
  annotations?: Annotation<any> | readonly Annotation<any>[];
  scrollIntoView?: boolean;
  filter?: boolean;
}

Transaction System

Change Management

Document change system with immutable change sets, position mapping, and change composition for collaborative editing.

class ChangeSet extends ChangeDesc {
  static of(changes: ChangeSpec, length: number, lineSep?: string): ChangeSet;
  static empty(length: number): ChangeSet;
  apply(doc: Text): Text;
  map(other: ChangeDesc, before?: boolean): ChangeSet;
  compose(other: ChangeSet): ChangeSet;
  invert(doc: Text): ChangeSet;
}

class ChangeDesc {
  readonly length: number;
  readonly newLength: number;
  readonly empty: boolean;
  mapPos(pos: number, assoc?: number, mode?: MapMode): number | null;
  touchesRange(from: number, to?: number): boolean | "cover";
}

enum MapMode {
  Simple,
  TrackDel,
  TrackBefore,
  TrackAfter
}

Change Management

Extension System

Flexible extension architecture using facets and state fields for configurable editor behavior and plugin development.

class Facet<Input, Output = readonly Input[]> {
  static define<Input, Output = readonly Input[]>(config?: FacetConfig<Input, Output>): Facet<Input, Output>;
  of(value: Input): Extension;
  compute(deps: readonly Slot<any>[], get: (state: EditorState) => Input): Extension;
  from<T>(field: StateField<T>, get?: (value: T) => Input): Extension;
}

class StateField<Value> {
  static define<Value>(config: StateFieldSpec<Value>): StateField<Value>;
  init(create: (state: EditorState) => Value): Extension;
}

class Compartment {
  of(ext: Extension): Extension;
  reconfigure(content: Extension): StateEffect<unknown>;
  get(state: EditorState): Extension | undefined;
}

Extension System

Range Sets

Efficient data structures for managing non-overlapping ranges with associated values, used for decorations and markers.

class RangeSet<T extends RangeValue> {
  static of<T extends RangeValue>(ranges: readonly Range<T>[] | Range<T>, sort?: boolean): RangeSet<T>;
  static empty: RangeSet<any>;
  update(updateSpec: RangeSetUpdateSpec<T>): RangeSet<T>;
  map(changes: ChangeDesc): RangeSet<T>;
  between(from: number, to: number, f: (from: number, to: number, value: T) => void | false): void;
  iter(from?: number): RangeCursor<T>;
}

abstract class RangeValue {
  range(from: number, to?: number): Range<this>;
  startSide: number;
  endSide: number;
  point: boolean;
  mapMode: MapMode;
}

class Range<T extends RangeValue> {
  readonly from: number;
  readonly to: number;
  readonly value: T;
}

Range Sets

Character and Text Utilities

Unicode-aware character processing utilities for handling grapheme clusters, code points, and text categorization.

function findClusterBreak(str: string, pos: number, forward?: boolean, includeExtending?: boolean): number;
function codePointAt(str: string, pos: number): number;
function fromCodePoint(code: number): string;
function codePointSize(code: number): 1 | 2;
function countColumn(string: string, tabSize: number, to?: number): number;
function findColumn(string: string, col: number, tabSize: number, strict?: boolean): number;

enum CharCategory {
  Word,
  Space,
  Other
}

Character Utilities

Configuration Utilities

Utility functions for combining and merging configuration objects.

function combineConfig<Config extends object>(
  configs: readonly Partial<Config>[],
  defaults: Partial<Config>,
  combine?: {[P in keyof Config]?: (first: Config[P], second: Config[P]) => Config[P]}
): Config;

Usage Example:

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

interface MyConfig {
  theme: string;
  tabSize: number;
  readOnly: boolean;
}

const configs = [
  { theme: "dark", tabSize: 2 },
  { theme: "light" }, // Conflict with theme
  { readOnly: true }
];

const defaults = { tabSize: 4, readOnly: false };

// This would throw due to theme conflict
try {
  const merged = combineConfig(configs, defaults);
} catch (e) {
  console.log("Config conflict detected");
}

// Resolve conflicts with combine functions
const resolved = combineConfig(configs, defaults, {
  theme: (first, second) => second || first // Last value wins
});