@citisen/litearea 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +1 -1
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +1 -1
- package/dist/react.js.map +1 -1
- package/dist/types/dom/editor.d.ts +8 -3
- package/dist/types/dom/editor.d.ts.map +1 -1
- package/docs/completion.md +10 -2
- package/package.json +1 -1
- package/src/dom/editor.ts +14 -4
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/format.ts","../src/core/text.ts","../src/core/vocabulary.ts","../src/core/scan.ts","../src/core/inspect.ts","../src/core/segments.ts","../src/core/rank.ts","../src/core/complete.ts","../src/core/hover.ts","../src/core/grammar.ts","../src/styles.ts","../src/dom/support.ts","../src/dom/editing.ts","../src/dom/mirror.ts","../src/dom/overlay.ts","../src/dom/popup.ts","../src/dom/tooltip.ts","../src/dom/editor.ts","../src/dom/create.ts"],"names":["range","index","previousScope","match","scopeClass","decorationClass","severityClass","complete","head","rest","written"],"mappings":"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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgItB,YAAY;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;A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","file":"index.cjs","sourcesContent":["// ─── format: the small string helpers the messages share ────────────────────\n//\n// Kept apart from the vocabulary so that a grammar can raise its own diagnostics\n// with the same phrasing the built-in ones use, and so that a translated host can\n// reuse the substitution instead of writing a second one.\n\n/** The most members a message will name before it stops counting. */\nconst DEFAULT_LIST_LIMIT = 12\n\n/**\n * Substitute `{name}` placeholders in a template.\n *\n * A placeholder with no matching key is left exactly as it was rather than\n * blanked: a visible `{allowed}` in a message is a bug report, and an empty gap\n * is a mystery.\n * @param template - the template, with `{name}` placeholders.\n * @param values - the substitutions.\n * @returns the filled text.\n */\nexport function fillTemplate(template: string, values: Readonly<Record<string, string>>): string {\n return String(template).replace(/\\{(\\w+)\\}/g, (match, key: string) =>\n Object.hasOwn(values, key) ? String(values[key]) : match,\n )\n}\n\n/**\n * A readable list: `a`, `a or b`, `a, b, or c`.\n *\n * The conjunction is a parameter because the same list reads differently as\n * \"expected one of X, Y, or Z\" and as \"X, Y, and Z are installed\".\n * @param items - the members.\n * @param options - `conjunction` (`'or'` by default) and `limit`, the most\n * members to name before summarising the rest as `… and N more`.\n * @returns the phrase.\n */\nexport function listPhrase(\n items: readonly string[],\n options?: { conjunction?: string; limit?: number },\n): string {\n const conjunction = options?.conjunction ?? 'or'\n const limit = options?.limit ?? DEFAULT_LIST_LIMIT\n const shown = items.slice(0, limit)\n const rest = items.length - shown.length\n if (shown.length === 0) return ''\n if (shown.length === 1) {\n return rest > 0 ? `${String(shown[0])} and ${String(rest)} more` : String(shown[0])\n }\n // Two members take no comma before the conjunction. \"circle, or square\" is not how\n // anyone writes it, and every diagnostic that lists a two-member vocabulary would\n // have said it that way.\n if (shown.length === 2) {\n const pair = `${String(shown[0])} ${conjunction} ${String(shown[1])}`\n return rest > 0 ? `${pair}, and ${String(rest)} more` : pair\n }\n const head = shown.slice(0, -1).join(', ')\n const tail = shown[shown.length - 1]\n const phrase = `${head}, ${conjunction} ${String(tail)}`\n return rest > 0 ? `${phrase}, and ${String(rest)} more` : phrase\n}\n\n/**\n * Collapse the whitespace in a snippet of user text so it can be quoted inside a\n * one-line message.\n * @param text - the text.\n * @param limit - the longest result, ellipsised beyond it.\n * @returns the excerpt.\n */\nexport function excerpt(text: string, limit = 24): string {\n const flat = text.replace(/\\s+/g, ' ').trim()\n return flat.length <= limit ? flat : `${flat.slice(0, limit - 1)}…`\n}\n","// ─── text: offsets, lines, and words ────────────────────────────────────────\n//\n// The engine counts in character offsets and nothing else. Not rows, not\n// columns, not pixels: every position that crosses a module boundary in litearea\n// is an offset into the document string, so there is exactly one coordinate\n// system to get wrong instead of three that must be kept in step.\n//\n// Pixels enter only in `src/dom/`, only to place the popup, and never travel\n// back inward. That boundary is the fix for a whole family of bugs in the\n// editors this library replaces, where a caret was tracked as a character index\n// in one place and read back as a screen position in another.\n\nimport type { LineInfo, Range, Token, WordInfo } from './types.js'\n\n/** Keeps a number inside a range, which every caller here needs and none should repeat. */\nexport function clamp(value: number, low: number, high: number): number {\n return value < low ? low : value > high ? high : value\n}\n\n/** Whether a value is a usable offset: a finite, non-negative integer. */\nexport function isOffset(value: unknown): value is number {\n return typeof value === 'number' && Number.isInteger(value) && value >= 0\n}\n\n/**\n * The offset each line starts at, in order. The first entry is always `0`.\n *\n * `\\r\\n`, `\\n`, and a lone `\\r` all end a line, because this text is typed by\n * hand into a textarea and a paste from a Windows editor must not read as one\n * long line. The terminator itself belongs to no line: a line's text excludes it\n * so that column arithmetic never has to reason about a stray carriage return.\n * @param source - the document.\n * @returns one offset per line, ascending.\n */\nexport function lineStarts(source: string): number[] {\n const starts = [0]\n for (let index = 0; index < source.length; index += 1) {\n const code = source.charCodeAt(index)\n if (code === 10) {\n starts.push(index + 1)\n } else if (code === 13) {\n if (source.charCodeAt(index + 1) === 10) index += 1\n starts.push(index + 1)\n }\n }\n return starts\n}\n\n/**\n * The index of the line an offset falls on.\n * @param starts - the result of {@link lineStarts}.\n * @param offset - a character offset.\n * @returns a zero-based line index.\n */\nexport function lineIndexAt(starts: readonly number[], offset: number): number {\n let low = 0\n let high = starts.length - 1\n while (low < high) {\n const middle = Math.ceil((low + high) / 2)\n if ((starts[middle] ?? 0) <= offset) low = middle\n else high = middle - 1\n }\n return low\n}\n\n/**\n * The line an offset falls on, with the offset expressed inside it.\n *\n * `before` and `after` are the line's own text split at the caret, which is what\n * completion and the indentation rules actually want; handing them out here\n * means neither has to re-derive the split and get it subtly different.\n * @param source - the document.\n * @param offset - a character offset; clamped into the document.\n * @param starts - the result of {@link lineStarts}, when the caller already has it.\n * @returns the line, its bounds, and the caret's place in it.\n */\nexport function lineAt(source: string, offset: number, starts?: readonly number[]): LineInfo {\n const position = clamp(offset, 0, source.length)\n const boundaries = starts ?? lineStarts(source)\n const index = lineIndexAt(boundaries, position)\n const from = boundaries[index] ?? 0\n const rawTo = boundaries[index + 1] ?? source.length\n // The next line's start sits after the terminator, so the last character of\n // the raw slice is the terminator itself — one character, or two for `\\r\\n`.\n let to = rawTo\n while (to > from) {\n const code = source.charCodeAt(to - 1)\n if (code === 10 || code === 13) to -= 1\n else break\n }\n const text = source.slice(from, to)\n const column = clamp(position - from, 0, text.length)\n return {\n from,\n to,\n text,\n number: index,\n column,\n before: text.slice(0, column),\n after: text.slice(column),\n }\n}\n\n/**\n * Whether a character is part of a word.\n *\n * The predicate is supplied by the grammar because it decides three things at\n * once — what a completion replaces, what a diagnostic underlines, and where a\n * double click puts the selection — and a language whose names contain a hyphen\n * must say so or every completion will replace one segment of a name instead of\n * the name.\n * @param char - one character, or the empty string at the end of the document.\n * @param wordChars - a single-character test.\n * @returns whether the character continues a word.\n */\nexport function isWordChar(char: string, wordChars: RegExp): boolean {\n return char !== '' && wordChars.test(char)\n}\n\n/**\n * The word at an offset.\n *\n * The word is found by expanding in BOTH directions from the offset rather than\n * by requiring the offset to be strictly inside a word. Completion needs the\n * second reading: a caret sitting at `Geist|` is at the end of the word, and the\n * word it is completing is still `Geist` — a lookup that insisted the offset be\n * interior would find nothing at exactly the moment the user wants a list.\n * @param source - the document.\n * @param offset - a character offset; clamped into the document.\n * @param wordChars - a single-character test.\n * @returns the word, its range, and the text either side of the caret.\n */\nexport function wordInfoAt(source: string, offset: number, wordChars: RegExp): WordInfo {\n const position = clamp(offset, 0, source.length)\n let from = position\n let to = position\n while (from > 0 && isWordChar(source.charAt(from - 1), wordChars)) from -= 1\n while (to < source.length && isWordChar(source.charAt(to), wordChars)) to += 1\n const text = source.slice(from, to)\n const column = position - from\n return {\n from,\n to,\n text,\n prefix: text.slice(0, column),\n suffix: text.slice(column),\n }\n}\n\n/** Whether a range is empty. */\nexport function isEmptyRange(range: Range): boolean {\n return range.to <= range.from\n}\n\n/** Whether an offset lies inside a range, with `to` exclusive. */\nexport function containsOffset(range: Range, offset: number): boolean {\n return offset >= range.from && offset < range.to\n}\n\n// ─── reading the token stream ───────────────────────────────────────────────\n\n/**\n * The token covering an offset.\n *\n * Zero-length tokens are skipped, so a caret at a boundary resolves to the token\n * it is *inside* rather than to an empty marker sitting on the seam.\n * @param tokens - the scanned tokens, ascending.\n * @param offset - a character offset.\n * @returns the covering token, or undefined in whitespace.\n */\nexport function tokenAt(tokens: readonly Token[], offset: number): Token | undefined {\n for (const token of tokens) {\n if (token.from <= offset && offset < token.to) return token\n if (token.from > offset) break\n }\n return undefined\n}\n\n/**\n * The scope painted at an offset, when there is one.\n * @param tokens - the scanned tokens, ascending.\n * @param offset - a character offset.\n * @returns the scope, or undefined in whitespace.\n */\nexport function scopeAt(tokens: readonly Token[], offset: number): string | undefined {\n return tokenAt(tokens, offset)?.scope\n}\n\n/**\n * The nearest token that ends at or before an offset, skipping whitespace.\n *\n * Whitespace is skipped because every caller is asking a question about\n * structure — \"which slot is this word in?\" — and a space is never an answer.\n * @param tokens - the scanned tokens, ascending.\n * @param offset - a character offset.\n * @returns the token, or undefined at the start of the document.\n */\nexport function tokenBefore(tokens: readonly Token[], offset: number): Token | undefined {\n let found\n for (const token of tokens) {\n if (token.to > offset) break\n if (token.text.trim() !== '') found = token\n }\n return found\n}\n\n/**\n * The nearest token that starts at or after an offset, skipping whitespace.\n * @param tokens - the scanned tokens, ascending.\n * @param offset - a character offset.\n * @returns the token, or undefined at the end of the document.\n */\nexport function tokenAfter(tokens: readonly Token[], offset: number): Token | undefined {\n for (const token of tokens) {\n if (token.to <= offset) continue\n if (token.text.trim() !== '') return token\n }\n return undefined\n}\n\n/**\n * The non-whitespace tokens on one line, in order.\n *\n * Completion and diagnostics both ask \"what is on this line so far\", and both\n * must ignore the indentation and the gaps between words. Returning the tokens\n * rather than the words means a grammar can ask what they *were* (their scopes)\n * and not only what they said.\n * @param tokens - the scanned tokens, ascending.\n * @param line - a line number, or a line record.\n * @returns the tokens on that line.\n */\nexport function tokensOnLine(\n tokens: readonly Token[],\n line: number | LineInfo,\n): Token[] {\n const number = typeof line === 'number' ? line : line.number\n return tokens.filter((token) => token.line === number && token.text.trim() !== '')\n}\n","// ─── vocabulary: the four facts that must agree ─────────────────────────────\n//\n// A closed set of words appears four times in a language-aware editor: as the\n// syntax that accepts it, as the colour it is painted in, as the message a typo\n// earns, and as the documentation a hover shows. Written out four times they\n// drift — a word added to the parser and forgotten by the highlighter is the\n// ordinary way a grammar rots — and the drift is invisible until someone types\n// the new word and watches the editor get it wrong.\n//\n// So they are declared once. `defineVocabulary` returns an object the engine\n// already knows how to consume: hand it to a `words` rule and it paints, accepts,\n// rejects, and documents without being mentioned again.\n//\n// const SHAPES = defineVocabulary({\n// id: 'shape',\n// words: ['circle', 'rounded', 'square', 'none'],\n// unknownMessage: '\"{word}\" is not a shape — expected one of {allowed}.',\n// docs: { circle: 'A full disc, the background for a busy state.' },\n// })\n//\n// { kind: 'words', words: SHAPES }\n\nimport type {\n ResolvedVocabulary,\n Scope,\n Severity,\n VocabularyContext,\n VocabularyEntry,\n WordsSource,\n} from './types.js'\nimport { fillTemplate, listPhrase } from './format.js'\n\n/** What a vocabulary is told about the document it is being resolved for. */\nexport interface VocabularySpec<State = unknown> {\n /** A stable id, used in the diagnostic code and for debugging. */\n id: string\n /**\n * The members.\n *\n * A function is how a set that lives outside the document reaches the grammar\n * without the grammar holding mutable state: the installed fonts, the states\n * the host actually has. It is called once per scan.\n */\n words: readonly string[] | ((context: VocabularyContext<State>) => readonly string[])\n /** The scope a member is painted with. Defaults to `vocabulary:<id>`. */\n scope?: Scope | ((word: string) => Scope)\n /** The scope a rejected word is painted with. Defaults to `'invalid'`. */\n unknownScope?: Scope\n /**\n * The message a rejected word earns.\n *\n * Present, a word-shaped token outside the set is reported; absent, it is\n * reported by nobody and the grammar is the poorer for it. `{word}` and\n * `{allowed}` are substituted, the latter as a readable list.\n */\n unknownMessage?: string | ((word: string, allowed: readonly string[]) => string)\n /** How loudly a rejected word complains. Default `'error'`. */\n unknownSeverity?: Severity\n /** A stable code for the rejection. Defaults to `vocabulary:<id>`. */\n unknownCode?: string\n /**\n * What each member explains about itself, for hover. A bare string is taken as\n * the body.\n */\n docs?: Readonly<Record<string, string | VocabularyEntry>>\n /** A dimmed line shown beside a member in the completion list. */\n detail?: (word: string) => string | undefined\n /** Whether membership is case-sensitive. Default `false`. */\n caseSensitive?: boolean\n /**\n * How a member is written into the document when it is accepted.\n *\n * Separate from the word itself because a member is not always insertable as\n * typed: a font family containing a space has to be quoted, even though the\n * vocabulary calls it `IBM Plex Mono`.\n */\n format?: (word: string) => string\n}\n\n/**\n * Build a vocabulary: the set, its colour, its rejection, and its documentation.\n * @param spec - the declaration.\n * @returns a resolved vocabulary, ready for a `words` rule.\n */\nexport function defineVocabulary<State = unknown>(\n spec: VocabularySpec<State>,\n): ResolvedVocabulary<State> {\n const caseSensitive = spec.caseSensitive === true\n const unknownScope = spec.unknownScope ?? 'invalid'\n const defaultScope = `vocabulary:${spec.id}`\n const unknownCode = spec.unknownCode ?? `vocabulary:${spec.id}`\n const unknownSeverity = spec.unknownSeverity ?? 'error'\n /** Fold a word for lookup, honouring the vocabulary's case rule. */\n const fold = (word: string): string => (caseSensitive ? word : word.toLowerCase())\n /** Find the member a word names, preserving the declared spelling. */\n const memberOf = (word: string, allowed: readonly string[]): string | undefined => {\n const needle = fold(word)\n return allowed.find((candidate) => fold(candidate) === needle)\n }\n /** The declaration for one member, whichever of the two shapes it took. */\n const docOf = (word: string): VocabularyEntry | undefined => {\n if (spec.docs === undefined) return undefined\n for (const [key, value] of Object.entries(spec.docs)) {\n if (fold(key) !== fold(word)) continue\n return typeof value === 'string' ? { body: value } : value\n }\n return undefined\n }\n\n return {\n id: spec.id,\n caseSensitive,\n resolve: (context) => {\n const words = typeof spec.words === 'function' ? spec.words(context) : spec.words\n return Array.isArray(words) ? words : []\n },\n has: (word, context) => {\n const words = typeof spec.words === 'function' ? spec.words(context) : spec.words\n return memberOf(word, Array.isArray(words) ? words : []) !== undefined\n },\n scopeFor: (word) => {\n if (typeof spec.scope === 'function') return spec.scope(memberOf(word, [word]) ?? word)\n return spec.scope ?? defaultScope\n },\n unknownScope,\n reject: (word, context) => {\n if (spec.unknownMessage === undefined) return undefined\n const allowed = typeof spec.words === 'function' ? spec.words(context) : spec.words\n const members = Array.isArray(allowed) ? allowed : []\n const message =\n typeof spec.unknownMessage === 'function'\n ? spec.unknownMessage(word, members)\n : fillTemplate(spec.unknownMessage, {\n word,\n allowed: listPhrase(members, { conjunction: 'or' }),\n })\n return { message, severity: unknownSeverity, code: unknownCode }\n },\n entryFor: (word) => docOf(word),\n format: (word) => (spec.format === undefined ? word : spec.format(word)),\n }\n}\n\n/**\n * The members of a vocabulary, resolved for a document.\n *\n * A helper for the common case of a caller that has a vocabulary and wants its\n * words, without reaching through to `resolve` and re-supplying the context.\n * @param vocabulary - a resolved vocabulary.\n * @param context - the document it is being resolved for.\n * @returns the members, in declaration order.\n */\nexport function vocabularyWords<State>(\n vocabulary: ResolvedVocabulary<State>,\n context: VocabularyContext<State>,\n): readonly string[] {\n return vocabulary.resolve(context)\n}\n\n/**\n * Recognize a vocabulary among the shapes a `WordsSource` may take.\n *\n * The test is structural rather than `instanceof`, so a grammar may hand over its\n * own object as long as it carries the four facts — which is what lets a host\n * wrap a vocabulary in logging, caching, or a translation layer without the\n * engine needing to know.\n * @param source - a words source.\n * @returns the vocabulary, or undefined when the source is a bare list or function.\n */\nexport function asResolvedVocabulary<State>(\n source: WordsSource<State>,\n): ResolvedVocabulary<State> | undefined {\n if (typeof source !== 'object' || source === null || Array.isArray(source)) return undefined\n const candidate = source as { resolve?: unknown }\n return typeof candidate.resolve === 'function' ? (source as ResolvedVocabulary<State>) : undefined\n}\n\n/**\n * The members any words source stands for, whichever shape it took.\n * @param source - a bare list, a vocabulary, or a function.\n * @param context - the document it is being resolved for.\n * @returns the members, or an empty list when the source resolved to nothing.\n */\nexport function resolveWordsSource<State>(\n source: WordsSource<State>,\n context: VocabularyContext<State>,\n): readonly string[] {\n const vocabulary = asResolvedVocabulary(source)\n const raw =\n vocabulary !== undefined\n ? vocabulary.resolve(context)\n : typeof source === 'function'\n ? source(context)\n : source\n return Array.isArray(raw) ? raw.filter((word) => word !== '') : []\n}\n","// ─── scan: text in, painted tokens out ──────────────────────────────────────\n//\n// One left-to-right pass. At each position the rules are tried in the order the\n// grammar declared them and the first one that matches wins, which is the whole\n// of the precedence model: to make a rule win, put it higher.\n//\n// A few decisions here are what keep a hand-written grammar honest.\n//\n// A rule may never match the empty string. A pattern that can, such as `/\\w*/`,\n// is treated as if it did not match, so the scan cannot stall on one position\n// forever. An infinite loop in a highlighter looks exactly like a frozen page.\n//\n// Consecutive tokens with the same scope are merged. Whitespace is most of a\n// document, and one span per space would mean thousands of DOM nodes for a file\n// nobody is looking at. Merging stops at a newline, because a token's line and\n// column describe where it starts and a span across two lines would make that a\n// lie.\n//\n// A non-nested region is found in one search rather than tested character by\n// character, and its contents are painted as a single span without the rule list\n// ever running inside it. That is what makes a string a string: the word\n// `running` inside a quoted font name is text, not a state.\n\nimport type {\n Diagnostic,\n Grammar,\n LineInfo,\n RegionRule,\n Rule,\n RuleContext,\n RuleMatch,\n Scope,\n ScopeSpec,\n Token,\n VocabularyContext,\n WordsRule,\n WordsSource,\n} from './types.js'\nimport { listPhrase } from './format.js'\nimport { clamp, isWordChar, lineAt, lineIndexAt, lineStarts } from './text.js'\nimport { asResolvedVocabulary } from './vocabulary.js'\n\n/** A grammar with its defaults filled in and its patterns made safe to reuse. */\nexport interface ResolvedGrammar<State = unknown> {\n /**\n * Marks this value as already resolved.\n *\n * Present so the two shapes can be told apart without guessing. The obvious test\n * — \"does it have a `fallbackScope`?\" — is wrong, because a plain grammar is\n * allowed to declare one, and the mistake surfaces as the engine reading `.grammar`\n * off a value that has no such field and crashing at the first keystroke.\n */\n readonly __resolved: true\n grammar: Grammar<State>\n rules: readonly Rule<State>[]\n /** The scope a character no rule claimed is painted with. */\n fallbackScope: Scope\n /** The single-character test that decides where words begin and end. */\n wordChars: RegExp\n}\n\n/**\n * Whether a value is a resolved grammar rather than one as written.\n * @param value - the grammar, either shape.\n * @returns whether it is already resolved.\n */\nexport function isResolvedGrammar<State>(\n value: Grammar<State> | ResolvedGrammar<State>,\n): value is ResolvedGrammar<State> {\n return (value as { __resolved?: unknown }).__resolved === true\n}\n\n/** The whole result of one scan: the paint, what the scan noticed, and the analysis. */\nexport interface ScanResult<State = unknown> {\n tokens: Token[]\n /**\n * What the lexical pass itself found: a word a vocabulary rejected, a region\n * that never closed. A grammar's own `checks` and `validate` are added by\n * `diagnose`, which builds on this.\n */\n diagnostics: Diagnostic[]\n /** Whatever `Grammar.analyze` returned, or `initialState`. */\n state: State\n}\n\n/** The word predicate a grammar that does not declare one gets. */\nconst DEFAULT_WORD_CHARS = /[\\p{L}\\p{N}_$]/u\n\n/**\n * A pattern that can be run at a position without ever skipping ahead.\n *\n * The sticky flag is added rather than demanded: a grammar author writing\n * `/foo/` means \"foo here\", and one who forgot the `y` would otherwise get a\n * pattern that quietly matches anywhere later in the document and paints the\n * wrong text. Compiled patterns are cached per source pattern, so a scan does not\n * recompile one per position.\n */\nconst stickyCache = new WeakMap<RegExp, RegExp>()\n\n/**\n * A pattern that runs at a position and cannot skip ahead.\n * @param pattern - the rule's pattern.\n * @returns the same pattern with the sticky flag, cached.\n */\nfunction sticky(pattern: RegExp): RegExp {\n const cached = stickyCache.get(pattern)\n if (cached !== undefined) return cached\n const flags = pattern.flags.replace(/[gy]/g, '')\n const compiled = new RegExp(pattern.source, `${flags}y`)\n stickyCache.set(pattern, compiled)\n return compiled\n}\n\n/** Run a pattern at an exact position, or report that it did not match there. */\nfunction execAt(pattern: RegExp, source: string, index: number): RegExpExecArray | null {\n pattern.lastIndex = index\n const match = pattern.exec(source)\n return match !== null && match.index === index ? match : null\n}\n\n/**\n * Strip the flags that would make a pattern stateful across calls.\n *\n * `RegExp.prototype.test` advances `lastIndex` on a global pattern, so a word\n * predicate carrying one would answer correctly for the first character and then\n * for every other one — a bug that looks like a typo in the grammar and cannot be\n * seen by reading it.\n * @param pattern - the grammar's pattern, if it declared one.\n * @returns a pattern safe to call repeatedly.\n */\nfunction withoutStatefulFlags(pattern: RegExp): RegExp {\n const flags = pattern.flags.replace(/[gy]/g, '')\n return flags === pattern.flags ? pattern : new RegExp(pattern.source, flags)\n}\n\n/**\n * Fill in a grammar's defaults and make its patterns safe.\n * @param grammar - the grammar as written.\n * @returns the grammar the scanner runs.\n */\nexport function resolveGrammar<State>(grammar: Grammar<State>): ResolvedGrammar<State> {\n return {\n __resolved: true,\n grammar,\n rules: grammar.rules,\n fallbackScope: grammar.fallbackScope ?? 'text',\n wordChars: withoutStatefulFlags(grammar.wordChars ?? DEFAULT_WORD_CHARS),\n }\n}\n\n/** What a words source resolves to, once per scan. */\ninterface ResolvedWords {\n list: readonly string[]\n /** Folded member text, for lookup. */\n set: Set<string>\n /**\n * Members containing a character the word predicate rejects, longest first.\n * They cannot be reached by reading a word in, so they are matched literally.\n */\n literal: readonly string[]\n caseSensitive: boolean\n}\n\n/**\n * Scan a document into tokens.\n * @param source - the document.\n * @param grammar - the language, as written or already resolved.\n * @returns the tokens, the lexical diagnostics, and the analysis.\n */\nexport function scan<State>(\n source: string,\n grammar: Grammar<State> | ResolvedGrammar<State>,\n): ScanResult<State> {\n const resolved: ResolvedGrammar<State> = isResolvedGrammar(grammar)\n ? grammar\n : resolveGrammar(grammar)\n const { rules, fallbackScope, wordChars } = resolved\n const declared = resolved.grammar\n const sourceId = declared.id\n const state: State =\n declared.analyze === undefined ? (declared.initialState as State) : declared.analyze(source)\n const vocabularyContext: VocabularyContext<State> = { text: source, state }\n\n const tokens: Token[] = []\n const diagnostics: Diagnostic[] = []\n const starts = lineStarts(source)\n const length = source.length\n\n // ── per-scan caches ───────────────────────────────────────────────────────\n // The vocabulary context is constant for a whole scan, so a vocabulary is\n // resolved once rather than at every position that tests a word.\n const wordsCache = new Map<WordsSource<State>, ResolvedWords>()\n /**\n * The line last asked for, so the scan does not re-slice per token.\n *\n * Only the line's BOUNDS are cached, never its column. A column depends on the\n * position being asked about while the bounds do not, and caching the pair\n * together is a bug with a very specific smell: the first token on a line caches\n * column 0, every later token on that line reads it back, and every rule guarded\n * by `firstOnLine` starts matching the whole line.\n */\n let cachedLineNumber = -1\n let cachedLineBounds: { from: number; to: number; text: string } | undefined\n /** Compiled `prevNot` character classes, per rule context. */\n const prevNotCache = new WeakMap<RuleContext, RegExp>()\n\n /** The line record for a position, with the column computed for that position. */\n const lineInfoAt = (position: number): LineInfo => {\n const number = lineIndexAt(starts, position)\n if (number !== cachedLineNumber || cachedLineBounds === undefined) {\n const info = lineAt(source, position, starts)\n cachedLineBounds = { from: info.from, to: info.to, text: info.text }\n cachedLineNumber = number\n }\n const column = clamp(position - cachedLineBounds.from, 0, cachedLineBounds.text.length)\n return {\n from: cachedLineBounds.from,\n to: cachedLineBounds.to,\n text: cachedLineBounds.text,\n number,\n column,\n before: cachedLineBounds.text.slice(0, column),\n after: cachedLineBounds.text.slice(column),\n }\n }\n\n /** Resolve a words source, once per scan. */\n const resolveWords = (from: WordsSource<State>): ResolvedWords => {\n const cached = wordsCache.get(from)\n if (cached !== undefined) return cached\n const vocabulary = asResolvedVocabulary(from)\n const caseSensitive = vocabulary?.caseSensitive === true\n const raw =\n vocabulary !== undefined\n ? vocabulary.resolve(vocabularyContext)\n : typeof from === 'function'\n ? from(vocabularyContext)\n : from\n const list = Array.isArray(raw) ? raw.filter((word) => word !== '') : []\n const fold = (word: string): string => (caseSensitive ? word : word.toLowerCase())\n const entry: ResolvedWords = {\n list,\n set: new Set(list.map(fold)),\n literal: list\n .filter((word) => [...word].some((char) => !isWordChar(char, wordChars)))\n .slice()\n .sort((left, right) => right.length - left.length),\n caseSensitive,\n }\n wordsCache.set(from, entry)\n return entry\n }\n\n /** Name a match: a fixed scope, or the grammar's function. */\n const scopeOf = (\n spec: ScopeSpec<State> | undefined,\n match: RuleMatch<State>,\n fallback: Scope,\n ): Scope => (spec === undefined ? fallback : typeof spec === 'function' ? spec(match) : spec)\n\n /** Whether every predicate a rule declared holds at this position. */\n const contextHolds = (\n when: RuleContext | undefined,\n index: number,\n previousScope: Scope | undefined,\n ): boolean => {\n if (when === undefined) return true\n const info = lineInfoAt(index)\n if (when.firstOnLine === true && info.text.slice(0, info.column).trim() !== '') return false\n if (when.after !== undefined) {\n if (previousScope === undefined || !when.after.includes(previousScope)) return false\n }\n if (when.notAfter !== undefined && previousScope !== undefined) {\n if (when.notAfter.includes(previousScope)) return false\n }\n if (when.line !== undefined && !when.line.test(info.text)) return false\n if (when.minColumn !== undefined && info.column < when.minColumn) return false\n if (when.maxColumn !== undefined && info.column > when.maxColumn) return false\n if (when.prevNot !== undefined && index > 0) {\n let pattern = prevNotCache.get(when)\n if (pattern === undefined) {\n pattern = new RegExp(`[${when.prevNot}]`)\n prevNotCache.set(when, pattern)\n }\n // `prevNot` names characters that must NOT precede the match, so a hit here is\n // a failure. At offset zero there is nothing in front of the match, so the\n // predicate holds — a rule guarded this way is not meant to be disabled at the\n // start of the document, which is what returning early there would do.\n if (pattern.test(source.charAt(index - 1))) return false\n }\n return true\n }\n\n // ── emitting ─────────────────────────────────────────────────────────────\n\n /** The scope of the innermost enclosing region, for a token's `region`. */\n let regionScope: Scope | undefined\n /** The scope of the nearest preceding non-whitespace token, maintained as we go. */\n let previousScope: Scope | undefined\n\n /**\n * Append a token, merging it into the previous one when that is invisible.\n * @param scope - the scope to paint.\n * @param from - the first offset.\n * @param to - the offset after the last.\n * @param region - overrides the enclosing region scope, for a fast-path region.\n */\n const push = (scope: Scope, from: number, to: number, region?: Scope): void => {\n if (to <= from) return\n const text = source.slice(from, to)\n const last = tokens[tokens.length - 1]\n if (\n last !== undefined &&\n last.scope === scope &&\n last.to === from &&\n last.region === region &&\n !/[\\r\\n]/.test(text) &&\n !/[\\r\\n]/.test(last.text)\n ) {\n last.to = to\n last.text = source.slice(last.from, to)\n } else {\n const info = lineInfoAt(from)\n tokens.push({ from, to, scope, text, line: info.number, column: from - info.from, region })\n }\n if (text.trim() !== '') previousScope = scope\n }\n\n /** Raise a diagnostic, stamping the grammar's id on it. */\n const report = (problem: {\n from: number\n to: number\n message: string\n severity?: Diagnostic['severity']\n code?: string\n }): void => {\n diagnostics.push({\n from: problem.from,\n to: problem.to,\n message: problem.message,\n severity: problem.severity ?? 'error',\n code: problem.code ?? 'lexical',\n source: sourceId,\n })\n }\n\n /** The `RuleMatch` a scope function is handed. */\n const ruleMatch = (\n text: string,\n from: number,\n groups: readonly (string | undefined)[],\n ): RuleMatch<State> => ({ text, source, from, groups, state })\n\n // ── reading words ────────────────────────────────────────────────────────\n\n /** The offset after the run of word characters starting at a position. */\n const readWordRun = (index: number): number => {\n let to = index\n while (to < length && isWordChar(source.charAt(to), wordChars)) to += 1\n return to\n }\n\n /**\n * The whitespace-separated segments a phrase may span.\n *\n * A phrase never crosses a line: a name split over two lines is two names, and\n * letting a vocabulary reach across the break would paint a paragraph as one\n * font.\n */\n const readSegments = (index: number, limit: number): Array<{ from: number; to: number }> => {\n const segments: Array<{ from: number; to: number }> = []\n let cursor = index\n while (segments.length < limit && cursor < length) {\n const to = readWordRun(cursor)\n if (to === cursor) break\n segments.push({ from: cursor, to })\n cursor = to\n const gap = /^[^\\S\\r\\n]+/.exec(source.slice(cursor))?.[0]\n if (gap === undefined) break\n cursor += gap.length\n }\n return segments\n }\n\n /** The longest member a position spells, or undefined when it spells none. */\n const matchWords = (\n rule: WordsRule<State>,\n words: ResolvedWords,\n index: number,\n ): { to: number; member: string } | undefined => {\n const fold = (word: string): string => (words.caseSensitive ? word : word.toLowerCase())\n const firstTo = readWordRun(index)\n if (firstTo > index) {\n if (rule.phrase !== undefined) {\n const segments = readSegments(index, Math.max(rule.phrase.max ?? 4, 1))\n // Longest first, so a catalogue holding both `IBM Plex` and `IBM Plex\n // Mono` resolves the longer name.\n for (let count = segments.length; count >= 1; count -= 1) {\n const texts = segments.slice(0, count).map((segment) => source.slice(segment.from, segment.to))\n const candidate = texts.join(' ')\n if (words.set.has(fold(candidate))) {\n const last = segments[count - 1]\n if (last !== undefined) return { to: last.to, member: candidate }\n }\n }\n } else {\n const candidate = source.slice(index, firstTo)\n if (words.set.has(fold(candidate))) return { to: firstTo, member: candidate }\n }\n }\n // A member the word predicate cannot read, matched as written. Only tried when reading\n // a word in failed, so the ordinary path pays nothing.\n for (const member of words.literal) {\n // A member containing whitespace is reachable through the phrase path, and matching\n // it literally would ignore `phrase.max` — a cap that only applies on one of the two\n // routes to the same member is not a cap.\n if (rule.phrase !== undefined && /\\s/.test(member)) continue\n if (source.startsWith(member, index)) return { to: index + member.length, member }\n }\n return undefined\n }\n\n /** Whether any rule would claim a position, which is what ends an unclaimed run. */\n const anyRuleClaims = (index: number, previous: Scope | undefined): boolean => {\n // A nested region's closing delimiter is a claim even though no rule mentions\n // it at this position. Without this the run would swallow the delimiter, the\n // region would never close, and a perfectly well-formed document would be\n // reported as unterminated.\n const openRegion = openRegions[openRegions.length - 1]\n if (openRegion !== undefined) {\n const endMatch = execAt(sticky(openRegion.rule.end), source, index)\n if (endMatch !== null && endMatch[0].length > 0) return true\n }\n for (const rule of rules) {\n if (!contextHolds(rule.when, index, previous)) continue\n if (rule.kind === 'region') {\n const match = execAt(sticky(rule.begin), source, index)\n if (match !== null && match[0].length > 0) return true\n continue\n }\n if (rule.kind === 'words') {\n if (matchWords(rule, resolveWords(rule.words), index) !== undefined) return true\n // A rule that reports what it rejects also claims what it rejects:\n // otherwise the word would be swallowed as plain text and the rejection\n // would never be reached.\n if (rule.unknown !== undefined && readWordRun(index) > index) return true\n continue\n }\n const match = execAt(sticky(rule.pattern), source, index)\n if (match !== null && match[0].length > 0) return true\n }\n return false\n }\n\n // ── the main loop ────────────────────────────────────────────────────────\n\n /** The regions currently open, innermost last. Only a nested region uses the stack. */\n const openRegions: Array<{\n rule: RegionRule<State>\n scope: Scope\n /** Where the opening delimiter was, so an unterminated region can be reported. */\n beginFrom: number\n beginTo: number\n }> = []\n\n let index = 0\n while (index < length) {\n const open = openRegions[openRegions.length - 1]\n\n if (open !== undefined) {\n // The region's own end is always what is tried first, whatever else the rule allows.\n const endMatch = execAt(sticky(open.rule.end), source, index)\n if (endMatch !== null && endMatch[0].length > 0) {\n const closeScope = scopeOf(\n open.rule.closeScope ?? open.rule.scope,\n ruleMatch(endMatch[0], index, [...endMatch]),\n open.scope,\n )\n push(closeScope, index, index + endMatch[0].length, open.scope)\n index += endMatch[0].length\n openRegions.pop()\n regionScope = openRegions[openRegions.length - 1]?.scope\n continue\n }\n\n // ── an opaque region recognises nothing but its own delimiters ───────\n // This is what makes a string a string: the word `running` inside a quoted name is\n // text, not a state. Nesting does NOT lift it — a comment that nests is still a\n // comment all the way down, and a language whose comments behave otherwise would be\n // one nobody could write a comment in.\n if (open.rule.transparent !== true) {\n if (open.rule.nested === true) {\n const inner = execAt(sticky(open.rule.begin), source, index)\n if (inner !== null && inner[0].length > 0) {\n const innerMatch = ruleMatch(inner[0], index, [...inner])\n push(\n scopeOf(open.rule.openScope ?? open.rule.scope, innerMatch, open.scope),\n index,\n index + inner[0].length,\n open.scope,\n )\n openRegions.push({\n rule: open.rule,\n scope: open.scope,\n beginFrom: index,\n beginTo: index + inner[0].length,\n })\n index += inner[0].length\n continue\n }\n }\n push(open.scope, index, index + 1, open.scope)\n index += 1\n continue\n }\n // A transparent region falls through: the rule list runs inside it, which is the\n // whole meaning of the flag.\n }\n\n let matched = false\n\n for (const rule of rules) {\n if (!contextHolds(rule.when, index, previousScope)) continue\n\n if (rule.kind === 'region') {\n const begin = execAt(sticky(rule.begin), source, index)\n if (begin === null || begin[0].length === 0) continue\n const beginMatch = ruleMatch(begin[0], index, [...begin])\n const scope = scopeOf(rule.scope, beginMatch, 'text')\n const openScope = scopeOf(rule.openScope ?? rule.scope, beginMatch, scope)\n const contentScope = scopeOf(rule.contentScope ?? rule.scope, beginMatch, scope)\n const closeScope = scopeOf(rule.closeScope ?? rule.scope, beginMatch, scope)\n const beginEnd = index + begin[0].length\n push(openScope, index, beginEnd, regionScope)\n\n // A region that only nests, or that is transparent, is tracked on the stack; the\n // stack is what its end is matched against, and what an unterminated one is reported\n // from. Everything else takes the fast path below.\n if (rule.nested === true || rule.transparent === true) {\n openRegions.push({ rule, scope: contentScope, beginFrom: index, beginTo: beginEnd })\n regionScope = contentScope\n index = beginEnd\n matched = true\n break\n }\n\n // The common case: find the end in one search rather than re-testing at\n // every character, and paint the whole middle as a single span.\n const close = findRegionEnd(rule.end, source, beginEnd)\n if (close === undefined) {\n // An unterminated region may be painted apart from a terminated one: `unclosed.scope`\n // is what lets a grammar say \"this is not a string, it is a broken string\", which is\n // the difference between a reader trusting the colours and being misled by them.\n push(\n scopeOf(rule.unclosed?.scope === undefined ? undefined : rule.unclosed.scope, beginMatch, contentScope),\n beginEnd,\n length,\n scope,\n )\n report({\n from: index,\n to: beginEnd,\n message:\n rule.unclosed?.message === undefined\n ? `Unterminated ${scope}.`\n : typeof rule.unclosed.message === 'function'\n ? rule.unclosed.message(beginMatch)\n : rule.unclosed.message,\n severity: rule.unclosed?.severity ?? 'error',\n code: rule.unclosed?.code ?? 'unclosed-region',\n })\n index = length\n matched = true\n break\n }\n push(contentScope, beginEnd, close.from, scope)\n push(closeScope, close.from, close.to, scope)\n index = close.to\n matched = true\n break\n }\n\n if (rule.kind === 'words') {\n const words = resolveWords(rule.words)\n const vocabulary = asResolvedVocabulary(rule.words)\n const hit = matchWords(rule, words, index)\n if (hit !== undefined) {\n const text = source.slice(index, hit.to)\n const match = ruleMatch(text, index, [text])\n const scope =\n rule.scope !== undefined\n ? scopeOf(rule.scope, match, 'word')\n : vocabulary?.scopeFor !== undefined\n ? vocabulary.scopeFor(hit.member)\n : 'word'\n push(scope, index, hit.to, regionScope)\n index = hit.to\n matched = true\n break\n }\n if (rule.unknown === undefined) continue\n // Only the first word is consumed. The scanner has no way to know how far\n // a name it has never seen was meant to reach, and guessing would swallow\n // the words that follow it; a multi-word name that is merely misspelled is\n // the grammar's validator's business, where the structure is known.\n const candidateTo = readWordRun(index)\n if (candidateTo <= index) continue\n const word = source.slice(index, candidateTo)\n const rejected = vocabulary?.reject?.(word, vocabularyContext)\n const message =\n rule.unknown.message === undefined\n ? rejected?.message\n : typeof rule.unknown.message === 'function'\n ? rule.unknown.message(word, ruleMatch(word, index, [word]))\n : rule.unknown.message\n .replace(/\\{word\\}/g, word)\n .replace(/\\{allowed\\}/g, listPhrase(words.list))\n push(rule.unknown.scope ?? vocabulary?.unknownScope ?? 'invalid', index, candidateTo, regionScope)\n if (message !== undefined) {\n report({\n from: index,\n to: candidateTo,\n message,\n severity: rule.unknown.severity ?? rejected?.severity ?? 'error',\n code: rule.unknown.code ?? rejected?.code ?? 'unknown-word',\n })\n }\n index = candidateTo\n matched = true\n break\n }\n\n const match = execAt(sticky(rule.pattern), source, index)\n if (match === null || match[0].length === 0) continue\n const matchInfo = ruleMatch(match[0], index, [...match])\n push(scopeOf(rule.scope, matchInfo, fallbackScope), index, index + match[0].length, regionScope)\n index += match[0].length\n matched = true\n break\n }\n\n if (matched) continue\n\n // ── nothing claimed this character ─────────────────────────────────────\n // A run of unclaimed characters is taken at once. Whitespace is by far the\n // most common thing no rule claims, and pushing it one character at a time\n // would be both slower and a great many spans.\n //\n // The run carries its own `previous`: once it has consumed a non-whitespace\n // character, the nearest preceding token is the run itself, not whatever came\n // before it. Without that, a rule guarded by `after` would be asked the wrong\n // question part way through and could let the run swallow a word it wanted.\n // Inside a nested region, a character no rule claims is still region content, so\n // it is painted with that region's scope rather than with the document fallback.\n const unclaimed = regionScope ?? fallbackScope\n let to = index\n let runPrevious = previousScope\n while (to < length) {\n const char = source.charAt(to)\n if (char === '\\n' || char === '\\r') break\n if (anyRuleClaims(to, runPrevious)) break\n if (/\\S/.test(char)) runPrevious = unclaimed\n to += 1\n }\n // `anyRuleClaims(index, ...)` is false here by construction, so this always\n // advances; the guard is against a rule list that disagrees with itself.\n push(unclaimed, index, Math.max(to, index + 1), regionScope)\n index = Math.max(to, index + 1)\n }\n\n // ── regions the document ended inside ───────────────────────────────────\n // A nested region is closed by the stack, not by a search, so running off the end of the\n // document leaves its frame open with nothing said. Reporting it here is the same fact\n // the opaque path reports when its search fails: a delimiter was opened and never closed.\n // Innermost first, because that is the one the reader has to fix first.\n for (let frame = openRegions.length - 1; frame >= 0; frame -= 1) {\n const open = openRegions[frame]\n if (open === undefined) continue\n const message =\n open.rule.unclosed?.message === undefined\n ? `Unterminated ${open.scope}.`\n : typeof open.rule.unclosed.message === 'function'\n ? open.rule.unclosed.message(ruleMatch('', open.beginFrom, ['']))\n : open.rule.unclosed.message\n report({\n from: open.beginFrom,\n to: open.beginTo,\n message,\n severity: open.rule.unclosed?.severity ?? 'error',\n code: open.rule.unclosed?.code ?? 'unclosed-region',\n })\n }\n\n return { tokens, diagnostics, state }\n}\n\n/**\n * Find a region's closing delimiter at or after a position.\n *\n * The search runs over the rest of the document rather than character by\n * character. The pattern is deliberately stripped of the sticky flag for this one\n * call: the end of a region is *searched for*, not anchored, which is the\n * difference between a string and a string that must begin exactly where the last\n * one ended.\n * @param pattern - the rule's `end` pattern.\n * @param source - the document.\n * @param from - where to start looking.\n * @returns the closing range, or undefined when the region never closes.\n */\nfunction findRegionEnd(\n pattern: RegExp,\n source: string,\n from: number,\n): { from: number; to: number } | undefined {\n const probe = new RegExp(pattern.source, `${pattern.flags.replace(/[gy]/g, '')}g`)\n probe.lastIndex = from\n const match = probe.exec(source)\n if (match === null || match[0].length === 0) return undefined\n return { from: match.index, to: match.index + match[0].length }\n}\n","// ─── inspect: the one call the editor makes per keystroke ───────────────────\n//\n// Everything the editor needs to know about a document is computed here, once,\n// from one grammar. The paint, the squiggles, the semantic decorations, and the\n// structural analysis come out of a single call and are stored together, so the\n// completion list and the coloured text cannot be looking at different documents.\n//\n// That is a deliberate inversion of how the editors this library replaces were\n// built. Each of them re-derived the tokens, the parse, and the suggestions\n// separately, from the same string, in three places — and the three drifted, so\n// a word could be painted as a valid value while the completer thought it was\n// unknown and the diagnostic pointed at a range that had already moved.\n\nimport type {\n CheckRule,\n Decoration,\n DiagnoseContext,\n Diagnostic,\n Grammar,\n Token,\n} from './types.js'\nimport { listPhrase } from './format.js'\nimport { isResolvedGrammar, resolveGrammar, scan, type ResolvedGrammar } from './scan.js'\nimport { resolveWordsSource } from './vocabulary.js'\n\n/** Everything one pass over a document produced. */\nexport interface Inspection<State = unknown> {\n /** The text this was computed from, kept so nothing has to guess its version. */\n text: string\n tokens: Token[]\n /** Lexical problems, the grammar's `checks`, and its `validate`, together. */\n diagnostics: Diagnostic[]\n /** Semantic ranges that are not tokens. */\n decorations: Decoration[]\n /** Whatever `Grammar.analyze` returned. */\n state: State\n}\n\n/**\n * Run a grammar's declarative checks over the tokens.\n *\n * A check is the shape most vocabulary mistakes actually take — \"this token is\n * one of these words or it is wrong\" — and expressing it declaratively means the\n * message, the severity, and the code are declared once instead of being\n * reassembled by hand at every site.\n * @param source - the document.\n * @param grammar - the resolved grammar.\n * @param tokens - the scanned tokens.\n * @param state - the analysis, so a check may consult a vocabulary the machine supplied.\n * @returns the diagnostics the checks raised.\n */\nfunction runChecks<State>(\n source: string,\n grammar: ResolvedGrammar<State>,\n tokens: readonly Token[],\n state: State,\n): Diagnostic[] {\n const checks = grammar.grammar.checks\n if (checks === undefined || checks.length === 0) return []\n const diagnostics: Diagnostic[] = []\n // The ANALYSIS, not `initialState`. A `WordsSource` function is documented as receiving\n // the grammar's analysis, and the point of a dynamic vocabulary is that it comes from\n // outside the document — so a check whose allowed set is resolved from `analyze` must\n // see it, or the two halves of one declaration would disagree about what is legal.\n const context = { text: source, state }\n\n for (const check of checks as readonly CheckRule<State>[]) {\n const members = check.allow === undefined ? undefined : resolveWordsSource(check.allow, context)\n const vocabulary = check.allow === undefined ? undefined : check.allow\n const caseSensitive =\n typeof vocabulary === 'object' && vocabulary !== null && !Array.isArray(vocabulary)\n ? (vocabulary as { caseSensitive?: boolean }).caseSensitive === true\n : false\n const fold = (word: string): string => (caseSensitive ? word : word.toLowerCase())\n const set =\n members === undefined ? undefined : new Set(members.map((member) => fold(member)))\n /** Lines already reported, for a check that only wants one complaint each. */\n const reportedLines = new Set<number>()\n\n for (const token of tokens) {\n // Whitespace is a token like any other, which means a check written against `'*'` would\n // otherwise underline every space and report it as a misspelling. No one has ever\n // wanted a diagnostic about a space.\n if (token.text.trim() === '') continue\n if (!check.scopes.includes('*') && !check.scopes.includes(token.scope)) continue\n if (check.except !== undefined && check.except.test(token.text)) continue\n if (set !== undefined && set.has(fold(token.text))) continue\n if (check.perLine === true) {\n if (reportedLines.has(token.line)) continue\n reportedLines.add(token.line)\n }\n diagnostics.push({\n from: token.from,\n to: token.to,\n severity: check.severity ?? 'error',\n message: check.message\n .replace(/\\{word\\}/g, token.text)\n .replace(/\\{allowed\\}/g, listPhrase(members ?? [])),\n code: check.code,\n detail: check.detail,\n source: grammar.grammar.id,\n })\n }\n }\n return diagnostics\n}\n\n/**\n * Inspect a document: paint, problems, decorations, and structure in one pass.\n * @param source - the document.\n * @param grammar - the language, as written or already resolved.\n * @returns everything the editor needs for one text.\n */\nexport function inspect<State>(\n source: string,\n grammar: Grammar<State> | ResolvedGrammar<State>,\n): Inspection<State> {\n const resolved = isResolvedGrammar(grammar) ? grammar : resolveGrammar(grammar)\n const scanned = scan(source, resolved)\n const declared = resolved.grammar\n const diagnostics: Diagnostic[] = [...scanned.diagnostics]\n\n diagnostics.push(...runChecks(source, resolved, scanned.tokens, scanned.state))\n\n if (declared.validate !== undefined) {\n const context: DiagnoseContext<State> = {\n text: source,\n tokens: scanned.tokens,\n state: scanned.state,\n report: (problem) => {\n diagnostics.push({\n from: problem.from,\n to: problem.to,\n severity: problem.severity ?? 'error',\n message: problem.message,\n code: problem.code ?? 'validate',\n detail: problem.detail,\n source: declared.id,\n })\n },\n }\n declared.validate(context)\n }\n\n const decorations = declared.decorate === undefined ? [] : [...declared.decorate(source, scanned.state)]\n\n return {\n text: source,\n tokens: scanned.tokens,\n diagnostics: normalizeDiagnostics(diagnostics),\n decorations: normalizeDecorations(decorations, source.length),\n state: scanned.state,\n }\n}\n\n/**\n * Sort diagnostics by position and drop duplicates.\n *\n * Two rules can legitimately notice the same mistake — a vocabulary's own\n * rejection and a grammar's validator both know that `nope` is not a colour —\n * and drawing the underline twice makes it darker rather than more informative.\n * Duplicates are compared on position, code, and message, so two genuinely\n * different complaints about one word both survive.\n * @param diagnostics - the collected diagnostics.\n * @returns the deduplicated, ordered list.\n */\nexport function normalizeDiagnostics(diagnostics: readonly Diagnostic[]): Diagnostic[] {\n const seen = new Set<string>()\n const out: Diagnostic[] = []\n for (const diagnostic of diagnostics) {\n const key = `${diagnostic.from}:${diagnostic.to}:${diagnostic.code ?? ''}:${diagnostic.message}`\n if (seen.has(key)) continue\n seen.add(key)\n out.push(diagnostic)\n }\n return out.sort((left, right) => left.from - right.from || left.to - right.to)\n}\n\n/**\n * Clamp decorations into the document and drop the ones that came out empty.\n *\n * A grammar computing decorations from a stale parse can hand over a range that\n * no longer exists, and a decoration outside the text would only produce a span\n * nobody can see.\n * @param decorations - the declared decorations.\n * @param length - the document's length.\n * @returns the usable decorations, ordered.\n */\nfunction normalizeDecorations(decorations: readonly Decoration[], length: number): Decoration[] {\n const out: Decoration[] = []\n for (const decoration of decorations) {\n const from = Math.max(0, Math.min(decoration.from, length))\n const to = Math.max(from, Math.min(decoration.to, length))\n if (to <= from) continue\n out.push({ ...decoration, from, to })\n }\n return out.sort((left, right) => left.from - right.from || left.to - right.to)\n}\n","// ─── segments: one pass over the document, for the painter ──────────────────\n//\n// The painted layer has to cover every character exactly once, in order, and it\n// has to do it while three independent things want to say something about those\n// characters: the scope that colours them, the decoration that marks them, and the\n// diagnostic that underlines them.\n//\n// The naive way is three layers, and it does not work. Each would have to position\n// its spans itself, so each would need its own idea of where a range starts, and a\n// span positioned by measuring is a span that drifts as soon as the font, the\n// wrapping, or the padding is even slightly different from what was measured.\n//\n// So they are merged into ONE stream of adjacent segments, and the renderer emits\n// them back to back with no positioning at all: the characters lay out where the\n// characters lay out, and the colours follow. Alignment stops being something the\n// code maintains and becomes something the layout cannot get wrong.\n//\n// This is pure — text and ranges in, segments out — which is why the trickiest\n// part of the painter is testable without a browser.\n\nimport type { Decoration, Diagnostic, Severity, Token } from './types.js'\n\n/** One run of characters that all share the same presentation. */\nexport interface PaintSegment {\n from: number\n to: number\n /** The characters themselves, so the painter never re-slices. */\n text: string\n /** The scope that colours them. */\n scope: string\n /** The decoration kinds that mark them, in declaration order. */\n decorations: string[]\n /** The loudest diagnostic covering them, when one does. */\n severity: Severity | undefined\n /** A hover title donated by a decoration, when it has one. */\n title: string | undefined\n}\n\n/** What a segment builder needs: the three range lists and nothing else. */\nexport interface SegmentInput {\n tokens: readonly Token[]\n decorations: readonly Decoration[]\n diagnostics: readonly Diagnostic[]\n}\n\n/**\n * The order severities outrank each other.\n *\n * One segment shows one squiggle, because two underlines on the same characters\n * only make a messier line rather than a more informative one. The loudest wins,\n * which is also the one a reader needs to see first.\n */\nconst SEVERITY_RANK: Record<Severity, number> = { error: 4, warning: 3, info: 2, hint: 1 }\n\n/**\n * Merge a scope, a decoration, and a diagnostic into adjacent segments.\n *\n * @param text - the document the ranges refer to.\n * @param input - the three range lists.\n * @param fallbackScope - the scope for characters no token covers.\n * @returns the segments, in order, covering the whole document.\n */\nexport function buildSegments(\n text: string,\n input: SegmentInput,\n fallbackScope = 'text',\n): PaintSegment[] {\n const length = text.length\n if (length === 0) return []\n\n // ── the cut points ────────────────────────────────────────────────────────\n // Every range boundary is a potential change of presentation, so they are the\n // only places a segment can begin or end.\n const cuts = new Set<number>([0, length])\n for (const token of input.tokens) {\n cuts.add(Math.max(0, Math.min(token.from, length)))\n cuts.add(Math.max(0, Math.min(token.to, length)))\n }\n for (const decoration of input.decorations) {\n cuts.add(Math.max(0, Math.min(decoration.from, length)))\n cuts.add(Math.max(0, Math.min(decoration.to, length)))\n }\n for (const diagnostic of input.diagnostics) {\n cuts.add(Math.max(0, Math.min(diagnostic.from, length)))\n cuts.add(Math.max(0, Math.min(diagnostic.to, length)))\n }\n const bounds = [...cuts].sort((left, right) => left - right)\n\n const segments: PaintSegment[] = []\n for (let index = 0; index < bounds.length - 1; index += 1) {\n const from = bounds[index] ?? 0\n const to = bounds[index + 1] ?? 0\n if (to <= from) continue\n\n const scope = coverScope(input.tokens, from, fallbackScope)\n const decorations = coverDecorations(input.decorations, from, to)\n const severity = coverSeverity(input.diagnostics, from, to)\n const title = input.decorations.find(\n (decoration) => decoration.title !== undefined && from >= decoration.from && to <= decoration.to,\n )?.title\n\n const last = segments[segments.length - 1]\n if (\n last !== undefined &&\n last.scope === scope &&\n last.severity === severity &&\n last.title === title &&\n sameList(last.decorations, decorations)\n ) {\n // Extending the previous segment keeps the DOM small without changing what\n // is drawn, which is the only reason the merge exists.\n last.to = to\n last.text = text.slice(last.from, to)\n continue\n }\n segments.push({ from, to, text: text.slice(from, to), scope, decorations, severity, title })\n }\n return segments\n}\n\n/** The scope of the token covering a position, or the fallback. */\nfunction coverScope(tokens: readonly Token[], offset: number, fallback: string): string {\n for (const token of tokens) {\n if (token.from > offset) break\n if (offset >= token.from && offset < token.to) return token.scope\n }\n return fallback\n}\n\n/** The decoration kinds covering a range, in the order they were declared. */\nfunction coverDecorations(decorations: readonly Decoration[], from: number, to: number): string[] {\n const kinds: string[] = []\n for (const decoration of decorations) {\n if (decoration.from <= from && to <= decoration.to) kinds.push(decoration.kind)\n }\n return kinds\n}\n\n/** The loudest diagnostic severity covering a range. */\nfunction coverSeverity(\n diagnostics: readonly Diagnostic[],\n from: number,\n to: number,\n): Severity | undefined {\n let loudest: Severity | undefined\n for (const diagnostic of diagnostics) {\n if (diagnostic.from > from || diagnostic.to < to) continue\n if (loudest === undefined || SEVERITY_RANK[diagnostic.severity] > SEVERITY_RANK[loudest]) {\n loudest = diagnostic.severity\n }\n }\n return loudest\n}\n\n/** Whether two short lists say the same thing, in the same order. */\nfunction sameList(left: readonly string[], right: readonly string[]): boolean {\n if (left.length !== right.length) return false\n for (let index = 0; index < left.length; index += 1) {\n if (left[index] !== right[index]) return false\n }\n return true\n}\n\n/**\n * The class attribute for a segment.\n *\n * Order matters for a stylesheet author's sanity rather than for the cascade: the\n * scope comes first so a rule can target `scope + mark` if it ever needs to.\n * @param segment - the segment.\n * @param scopeClass - how a scope becomes a class.\n * @param decorationClass - how a decoration kind becomes a class.\n * @param severityClass - how a severity becomes a class.\n * @returns the class list.\n */\nexport function segmentClasses(\n segment: PaintSegment,\n scopeClass: (scope: string) => string,\n decorationClass: (kind: string) => string,\n severityClass: (severity: string) => string,\n): string[] {\n const classes = [scopeClass(segment.scope)]\n for (const kind of segment.decorations) classes.push(decorationClass(kind))\n if (segment.severity !== undefined) classes.push(severityClass(segment.severity))\n return classes\n}\n","// ─── rank: how a completion list is ordered and filtered ────────────────────\n//\n// Two jobs that are easy to conflate and must not be. \"Which rows does this\n// needle match?\" is a filter, and a row either matches or does not. \"In what\n// order?\" is a ranking, and it is where the feel of a completer actually lives:\n// typing `inter` should put `Inter` above `Inter Tight` above `Plex Inter`, and\n// nothing about the matching itself decides that.\n//\n// The ranking is expressed as a TIER plus a local score rather than as one\n// arithmetic blend. A single blend is the classic mistake — add enough bonuses\n// and a longer subsequence eventually outscores an exact match, so the obvious\n// answer sinks below a coincidence — and it is also untestable, because no one\n// can say what the number 47.3 means. Tiers make the precedence a list you can\n// read and a set of cases you can assert:\n//\n// exact, case-sensitive `Inter` → `Inter`\n// exact, any case `inter` → `Inter`\n// prefix `inte` → `Inter`\n// word-boundary `fm` → `Fira Mono`, `IPM` → `IBM Plex Mono`\n// substring `lex` → `Plex Inter`\n// subsequence `jbmo` → `JetBrains Mono`\n//\n// Nothing here knows anything about any language. A needle and a label go in, a\n// score and the matched offsets come out, which is why this module has no import\n// of the grammar contract at all.\n\n/** The most of a score a local bonus may contribute, so a tier always dominates. */\nconst TIER_STRIDE = 1_000_000\n\n/**\n * The precedence tiers, highest first. The numbers are grades, not weights: a\n * tier only has to be larger than the one below it.\n */\nconst TIER = {\n /** The needle is the label, in the same case. */\n exact: 5,\n /** The needle is the label, ignoring case. */\n exactFold: 4,\n /** The label starts with the needle. */\n prefix: 3,\n /**\n * Every needle character either starts a word or continues one the match has\n * already started. This is what makes initials work: `fm` finds `Fira Mono` and\n * `IPM` finds `IBM Plex Mono`, without `IPM` being a substring of anything.\n */\n boundary: 2,\n /** The needle appears as one unbroken run inside the label. */\n substring: 1,\n /** The needle's characters appear in order, with gaps. */\n subsequence: 0,\n} as const\n\n/** Characters that make the character after them the start of a word. */\nconst SEPARATORS = /[\\s\\-_./:@()+[\\]]/\n\n/** A needle and the positions in the label it matched. */\nexport interface FuzzyMatch {\n /** The ranking score. Higher is a better match. */\n score: number\n /** The matched offsets into the label, ascending, for showing what matched. */\n indices: number[]\n /** The tier the match reached, for tests and for explaining a ranking. */\n tier: number\n}\n\n/**\n * Whether a position in a label starts a word.\n *\n * Three things start one: the beginning, a separator, and a lower-to-upper\n * transition. The third is what makes camelCase names searchable by their humps,\n * and it is why `NotoSans` and `Noto Sans` behave the same way under a needle\n * like `ns`.\n * @param label - the text being searched.\n * @param index - a position in it.\n * @returns whether a word starts there.\n */\nexport function isWordStart(label: string, index: number): boolean {\n if (index <= 0) return index === 0\n const previous = label.charAt(index - 1)\n if (SEPARATORS.test(previous)) return true\n const current = label.charAt(index)\n return previous === previous.toLowerCase() && current !== current.toLowerCase()\n}\n\n/** Whether a needle wants case-sensitive matching: it does when it has any uppercase. */\nfunction wantsExactCase(needle: string): boolean {\n return needle !== needle.toLowerCase()\n}\n\n/** A local bonus for a matched character. Never large enough to cross a tier. */\nfunction localScore(\n label: string,\n needle: string,\n indices: readonly number[],\n exactCase: boolean,\n): number {\n let score = 0\n for (let position = 0; position < indices.length; position += 1) {\n const index = indices[position]\n if (index === undefined) continue\n if (index === 0) score += 24\n else if (isWordStart(label, index)) score += 14\n if (position > 0 && index === (indices[position - 1] ?? -2) + 1) score += 10\n if (exactCase && label.charAt(index) === needle.charAt(position)) score += 4\n }\n const first = indices[0] ?? 0\n const last = indices[indices.length - 1] ?? 0\n // Gaps inside the matched span hurt, starting late hurts, and a short label\n // beats a long one that matched equally well — the same tie-break a reader\n // makes when two rows look alike.\n score -= (last - first + 1 - needle.length) * 1.5\n score -= first * 2\n score -= label.length * 0.05\n return score\n}\n\n/**\n * Match a needle against a label.\n *\n * Case follows the needle: a needle with an uppercase character is matched\n * case-sensitively, so `Inter` does not quietly match `inter`, while an\n * all-lowercase needle matches anything. That is the same \"smart case\" a\n * terminal has used for decades and the one VSCode applies.\n * @param needle - what the user has typed.\n * @param label - what is being searched.\n * @returns the score and matched offsets, or undefined when the needle does not match.\n */\nexport function fuzzyMatch(needle: string, label: string): FuzzyMatch | undefined {\n if (needle === '') return { score: 0, indices: [], tier: 0 }\n const exactCase = wantsExactCase(needle)\n const haystack = exactCase ? label : label.toLowerCase()\n const query = exactCase ? needle : needle.toLowerCase()\n\n // ── the cheap wins, in the order they should be believed ────────────────\n if (label === needle) {\n return { score: TIER.exact * TIER_STRIDE + localScore(label, needle, range(needle.length), true), indices: range(needle.length), tier: TIER.exact }\n }\n if (label.toLowerCase() === query) {\n const indices = range(needle.length)\n return {\n score: TIER.exactFold * TIER_STRIDE + localScore(label, needle, indices, exactCase),\n indices,\n tier: TIER.exactFold,\n }\n }\n if (haystack.startsWith(query)) {\n const indices = range(needle.length)\n return {\n score: TIER.prefix * TIER_STRIDE + localScore(label, needle, indices, exactCase),\n indices,\n tier: TIER.prefix,\n }\n }\n\n // ── the candidates ──────────────────────────────────────────────────────\n // A contiguous run is not automatically the best answer, which is why every\n // candidate is scored and the best one wins rather than the first one found.\n // `ns` against `notoSans` matches contiguously at the end and as two humps at the\n // start; only the second is what the typist meant, and a scorer that returned on\n // the first contiguous hit would never see it.\n let best: FuzzyMatch | undefined\n const consider = (candidate: FuzzyMatch): void => {\n if (best === undefined || candidate.score > best.score) best = candidate\n }\n\n for (let at = haystack.indexOf(query); at >= 0; at = haystack.indexOf(query, at + 1)) {\n const indices = range(needle.length, at)\n const tier = isWordStart(label, at) ? TIER.boundary : TIER.substring\n consider({ score: tier * TIER_STRIDE + localScore(label, needle, indices, exactCase), indices, tier })\n }\n\n // Every position the first character could have started at is tried, rather than\n // only the first one. Greedy-from-the-first-hit looks right and is wrong: `IPM`\n // against `IBM Plex Mono` would take the `P` of `Plex` and then fail to find an\n // `M`, when the `M` of `Mono` was available all along.\n for (let start = 0; start < haystack.length; start += 1) {\n if (haystack.charAt(start) !== query.charAt(0)) continue\n const indices: number[] = [start]\n let cursor = start + 1\n let complete = true\n for (let position = 1; position < query.length; position += 1) {\n const found = haystack.indexOf(query.charAt(position), cursor)\n if (found < 0) {\n complete = false\n break\n }\n indices.push(found)\n cursor = found + 1\n }\n if (!complete) continue\n // A match whose characters all start or continue a word reads as initials and\n // outranks one that merely happens to appear in order.\n const tier = indicesAreBoundaryish(label, indices) ? TIER.boundary : TIER.subsequence\n consider({ score: tier * TIER_STRIDE + localScore(label, needle, indices, exactCase), indices, tier })\n }\n return best\n}\n\n/**\n * Whether every matched position either starts a word or continues the run before it.\n * @param label - the searched text.\n * @param indices - the matched offsets.\n * @returns whether the match reads as initials rather than as scattered letters.\n */\nfunction indicesAreBoundaryish(label: string, indices: readonly number[]): boolean {\n for (let position = 0; position < indices.length; position += 1) {\n const index = indices[position]\n if (index === undefined) continue\n if (isWordStart(label, index)) continue\n if (position > 0 && index === (indices[position - 1] ?? -2) + 1) continue\n return false\n }\n return true\n}\n\n/** `[from, from + count)`, as an array. */\nfunction range(count: number, from = 0): number[] {\n const out: number[] = []\n for (let index = 0; index < count; index += 1) out.push(from + index)\n return out\n}\n\n/** One row of a ranked list, with the evidence for its position. */\nexport interface Ranked<T> {\n item: T\n score: number\n /** The offsets in the label that matched, for emphasising them in the list. */\n indices: number[]\n}\n\n/** How to read a row while ranking it. */\nexport interface RankOptions<T> {\n /** The text shown to the user. */\n label(item: T): string\n /** The text matched against the needle, when it differs from the label. */\n filterText?(item: T): string\n /**\n * The primary sort key, as VSCode's `sortText` is: rows are ordered by it\n * first and by match score only within an equal key. It is how a grammar puts\n * a whole group on top — the value already in effect, say — without pretending\n * its label starts with a `0`.\n */\n sortText?(item: T): string | undefined\n}\n\n/**\n * Filter and order rows for a needle.\n *\n * An empty needle keeps every row in the order the grammar declared, which is\n * what Ctrl+Space should show: the whole vocabulary, grouped the way the grammar\n * thinks about it, not alphabetised by a scorer that has nothing to go on.\n * @param items - the candidate rows.\n * @param needle - what the user has typed.\n * @param options - how to read a row.\n * @returns the matching rows, best first.\n */\nexport function rank<T>(items: readonly T[], needle: string, options: RankOptions<T>): Ranked<T>[] {\n const out: Ranked<T>[] = []\n for (const item of items) {\n if (needle === '') {\n out.push({ item, score: 0, indices: [] })\n continue\n }\n const label = options.label(item)\n const subject = options.filterText?.(item) ?? label\n const match = fuzzyMatch(needle, subject)\n if (match === undefined) continue\n // The offsets are only meaningful against the label, so a row matched on\n // different text is ranked without an emphasis rather than with the wrong one.\n out.push({ item, score: match.score, indices: subject === label ? match.indices : [] })\n }\n\n if (options.sortText === undefined) {\n // Sorting by score alone, on a stable sort, keeps the order the grammar\n // declared for everything the needle does not separate. That is load-bearing:\n // an empty needle must show a catalogue in catalogue order, and an alphabetical\n // tie-break would quietly rearrange a list the grammar had already ranked.\n out.sort((left, right) => right.score - left.score)\n return out\n }\n return out.sort((left, right) => {\n const leftKey = options.sortText?.(left.item) ?? options.label(left.item)\n const rightKey = options.sortText?.(right.item) ?? options.label(right.item)\n return leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : right.score - left.score\n })\n}\n\n/**\n * Split a label around the characters a needle matched, for the list to emphasise.\n *\n * Returned as segments rather than as a marked-up string because the caller is\n * building DOM nodes, not HTML: a font family called `<b>` must be shown as\n * `<b>`, and a completer that returns markup has to escape what it was given or\n * it is wrong about a real font.\n * @param label - the row's text.\n * @param indices - the matched offsets, ascending.\n * @returns alternating plain and matched segments, in order.\n */\nexport function highlightSegments(\n label: string,\n indices: readonly number[],\n): Array<{ text: string; matched: boolean }> {\n if (indices.length === 0) return label === '' ? [] : [{ text: label, matched: false }]\n const marked = new Set(indices)\n const segments: Array<{ text: string; matched: boolean }> = []\n let current: { text: string; matched: boolean } | undefined\n for (let index = 0; index < label.length; index += 1) {\n const matched = marked.has(index)\n if (current === undefined || current.matched !== matched) {\n if (current !== undefined) segments.push(current)\n current = { text: '', matched }\n }\n current.text += label.charAt(index)\n }\n if (current !== undefined) segments.push(current)\n return segments\n}\n","// ─── complete: turning a caret into a list, and a list into an edit ─────────\n//\n// Two pure functions, deliberately separated, because they fail in different\n// ways and only one of them is interesting to a user.\n//\n// `complete` answers \"what could go here?\" and returns rows. `applyCompletion`\n// answers \"what does the document become?\" and returns text plus a caret. Keeping\n// them apart is what makes the hard half — the interaction — testable in Node\n// without a browser, and it is why the two bugs that make a completer feel broken\n// have somewhere to live:\n//\n// A SOURCE that swaps mid-typing loses the thread. The list opens over a family\n// name, the user types `=` and it becomes a value list, and the row they were\n// looking at is gone. So once a source has answered, it keeps answering for as long\n// as it stays eligible, and the priority order only decides which source OPENS the\n// list.\n//\n// A range that does not grow leaves text behind. The range is recomputed from the\n// caret on every filter, never reused: type `ru`, accept `running`, and the\n// replacement must cover both letters. Holding the range resolved when the list\n// opened replaces only the `r` and produces `running u` — a bug worth naming,\n// because it is invisible in a test that only ever types one character before\n// accepting.\n\nimport type {\n Completion,\n CompletionContext,\n CompletionSource,\n CompletionTrigger,\n Grammar,\n Range,\n SuggestionItem,\n} from './types.js'\nimport type { Inspection } from './inspect.js'\nimport { rank, type Ranked } from './rank.js'\nimport { clamp, lineAt, lineStarts, scopeAt, tokenBefore, tokensOnLine, wordInfoAt } from './text.js'\nimport { isResolvedGrammar, resolveGrammar, type ResolvedGrammar } from './scan.js'\n\n/** The most rows a completion will carry, so a huge catalogue cannot stall a list. */\nconst DEFAULT_LIMIT = 100\n\n/** What the editor knows when it asks for a list. */\nexport interface CompletionRequest {\n text: string\n caret: number\n trigger: CompletionTrigger\n /**\n * The source that answered last time, when a list is already open.\n *\n * Passing it is what keeps a list stable while the user types: the same source answers\n * again for as long as it stays eligible, so typing a character that makes a different\n * source eligible does not swap the rows out from under the reader. Only the SOURCE is\n * held — the range is recomputed from the caret every time, so it grows with the word.\n */\n previousSourceId?: string | undefined\n /** The most rows to return. */\n limit?: number\n}\n\n/**\n * Resolve a completion for a caret.\n *\n * @param inspection - the current inspection of the document.\n * @param grammar - the language.\n * @param request - the caret, the trigger, and any list already open.\n * @returns the range and the rows, or undefined when nothing applies.\n */\nexport function complete<State>(\n inspection: Inspection<State>,\n grammar: Grammar<State> | ResolvedGrammar<State>,\n request: CompletionRequest,\n): Completion | undefined {\n const resolved = isResolvedGrammar(grammar) ? grammar : resolveGrammar(grammar)\n const sources = resolved.grammar.compose\n if (sources === undefined || sources.length === 0) return undefined\n\n const text = request.text\n const caret = clamp(request.caret, 0, text.length)\n const context = completionContext(inspection, resolved, caret, request.trigger)\n\n const eligible = sources.filter((source) => source.when === undefined || source.when(context))\n if (eligible.length === 0) return undefined\n\n // ── which source, and over what range ────────────────────────────────────\n // Ordered by priority, and the range comes from the winner because two sources\n // disagreeing about the range have no coherent shared answer.\n // ── which source ────────────────────────────────────────────────────────\n // Priority decides which source OPENS the list; after that the source that answered\n // keeps answering while it remains eligible, so the rows do not change identity under\n // the reader's hands. The range is not part of this: it is computed fresh below, from\n // the caret as it is now.\n const ordered = [...eligible].sort((left, right) => (right.priority ?? 0) - (left.priority ?? 0))\n const reopening =\n request.previousSourceId === undefined\n ? undefined\n : ordered.find((source) => source.id === request.previousSourceId)\n const winner = reopening ?? ordered[0]\n if (winner === undefined) return undefined\n const range = resolveRange(winner, context)\n\n // ── the rows ─────────────────────────────────────────────────────────────\n const merged: SuggestionItem[] = [...winner.items(context)]\n for (const source of ordered) {\n if (source === winner || source.merge !== true) continue\n merged.push(...source.items(context))\n }\n if (merged.length === 0) return undefined\n\n // The needle is what the user has typed INSIDE the range, which is the only reading\n // that stays meaningful when the range is an entry rather than a word. It is clamped\n // to the range at both ends: a caret can sit past the range — after the trailing space\n // of an entry, say — and slicing to the caret there would pull a separator into the\n // needle and filter the list by a character the user did not mean to search for.\n const needleFrom = clamp(range.from, 0, caret)\n const needleTo = clamp(caret, needleFrom, Math.max(range.to, needleFrom))\n const needle = text.slice(needleFrom, needleTo)\n const ranked: Ranked<SuggestionItem>[] = rank(merged, needle, {\n label: (item) => item.label,\n ...(merged.some((item) => item.filterText !== undefined)\n ? { filterText: (item: SuggestionItem) => item.filterText ?? item.label }\n : {}),\n ...(merged.some((item) => item.sortText !== undefined)\n ? { sortText: (item: SuggestionItem) => item.sortText }\n : {}),\n })\n const limit = request.limit ?? DEFAULT_LIMIT\n\n return {\n range,\n rows: ranked.slice(0, limit).map((entry) => ({\n item: entry.item,\n score: entry.score,\n indices: entry.indices,\n })),\n needle,\n sourceId: winner.id,\n }\n}\n\n/** Resolve a source's range, whether it declared one or computes it. */\nfunction resolveRange<State>(\n source: CompletionSource<State>,\n context: CompletionContext<State>,\n): Range {\n if (typeof source.range !== 'function') return source.range\n const range = source.range(context)\n return {\n from: Math.min(range.from, range.to),\n to: Math.max(range.from, range.to),\n }\n}\n\n/**\n * Build everything a completion source may look at.\n * @param inspection - the current inspection.\n * @param resolved - the resolved grammar.\n * @param caret - the caret offset.\n * @param trigger - how the list came to be open.\n * @returns the context.\n */\nfunction completionContext<State>(\n inspection: Inspection<State>,\n resolved: ResolvedGrammar<State>,\n caret: number,\n trigger: CompletionTrigger,\n): CompletionContext<State> {\n const { text, tokens, diagnostics, state } = inspection\n const line = lineAt(text, caret, lineStarts(text))\n const lineTokens = tokensOnLine(tokens, line.number)\n const word = wordInfoAt(text, caret, resolved.wordChars)\n return {\n text,\n caret,\n word,\n line,\n tokens,\n diagnostics,\n state,\n scope: scopeAt(tokens, caret),\n scopeBefore: tokenBefore(tokens, caret)?.scope,\n // \"First on line\" means only whitespace precedes the caret, which is a question\n // about the caret and not about the token under it: a caret in the indentation of\n // a line that already has content is not first on that line. `lineTokens` is what\n // tells the difference, so the tokens are read even though the answer looks like a\n // string test.\n firstOnLine: line.before.trim() === '' && !lineTokens.some((token) => token.to <= caret),\n // \"First word\" additionally allows the rest of the word the caret is in, which is\n // what keeps a line-head completion alive while the head is being typed.\n firstWord: line.text.slice(0, Math.max(0, word.from - line.from)).trim() === '',\n firstToken: lineTokens[0],\n trigger,\n }\n}\n\n/** An edit produced by accepting a row. */\nexport interface AppliedCompletion {\n /** The document after the edit. */\n text: string\n /** Where the caret belongs in it. */\n caret: number\n /**\n * What changed, in the NEW document. The editor uses it to scroll the result\n * into view and to describe the edit to a host.\n */\n range: Range\n /**\n * The offset the edit starts at in the ORIGINAL document.\n *\n * Exposed alongside `insert` because an editor must write only the range that\n * changed. Assigning the whole recomputed `text` would be simpler and would throw\n * away the browser's undo history, which is the one thing this library exists to\n * protect.\n */\n from: number\n /** The offset the edit ends at in the original document. */\n to: number\n /** The text written between those two offsets. */\n insert: string\n}\n\n/**\n * Apply a chosen row to a document.\n *\n * The row decides three things: what is written, whether it is written over the\n * range or in front of it, and how much text follows it. `append` is the\n * grammar's business and not the engine's — inviting another entry with a `, `\n * is a fact about font stacks, and an engine that appended one by default would\n * be guessing about every other language.\n *\n * @param text - the document.\n * @param range - the range the list was opened over.\n * @param item - the chosen row.\n * @returns the resulting text, caret, and the edit that produced them.\n */\nexport function applyCompletion(text: string, range: Range, item: SuggestionItem): AppliedCompletion {\n const from = clamp(Math.min(range.from, range.to), 0, text.length)\n const to = clamp(Math.max(range.from, range.to), from, text.length)\n const insert = item.insert ?? item.label\n const append = item.append ?? ''\n const offset = item.caretOffset ?? 0\n\n if (item.mode === 'before') {\n const head = text.slice(0, from)\n // The whitespace in front of the existing entry belonged to the comma before\n // it, so it is restored rather than doubled.\n const gap = head !== '' && !/\\s$/.test(head) ? ' ' : ''\n const rest = text.slice(from).replace(/^\\s+/, '')\n const written = `${gap}${insert}${redundant(append, rest) ? '' : append}`\n return {\n text: `${head}${written}${rest}`,\n caret: head.length + written.length + offset,\n range: { from: head.length, to: head.length + written.length },\n from,\n to: from,\n insert: written,\n }\n }\n\n const head = text.slice(0, from)\n const rest = text.slice(to)\n const written = `${insert}${redundant(append, rest) ? '' : append}`\n return {\n text: `${head}${written}${rest}`,\n caret: head.length + written.length + offset,\n range: { from: head.length, to: head.length + written.length },\n from,\n to,\n insert: written,\n }\n}\n\n/**\n * Whether an append would only repeat what the document already says.\n *\n * Accepting `running` immediately before an existing space must not produce two,\n * and accepting a font family immediately before an existing `, ` must not add\n * another comma. Whitespace is compared as whitespace rather than as the exact\n * characters, so a tab counts as the space an append was reaching for.\n * @param append - the row's `append` text.\n * @param rest - the document immediately after the range.\n * @returns whether the append should be left out.\n */\nfunction redundant(append: string, rest: string): boolean {\n if (append === '') return true\n return append.trim() === '' ? /^\\s/.test(rest) : rest.startsWith(append)\n}\n","// ─── hover: what the pointer is resting on ─────────────────────────────────\n//\n// A tooltip is only worth showing when it says something the text does not, and\n// there are exactly three things that qualify: a problem, a semantic mark the\n// grammar made, and the grammar's own explanation of a token. They are consulted\n// in that order and the first one that has something to say wins.\n//\n// A diagnostic leads deliberately. The other two describe what the text IS, and\n// the user resting the pointer on a red squiggle is asking what is WRONG with it\n// — answering \"circle: a full disc\" there would be technically true and useless,\n// and it is exactly the behaviour that makes people stop hovering.\n\nimport type { Decoration, Diagnostic, Grammar, HoverContext, HoverInfo, Severity } from './types.js'\nimport type { Inspection } from './inspect.js'\nimport { containsOffset, lineAt, lineStarts, tokenAt, wordInfoAt } from './text.js'\nimport { isResolvedGrammar, resolveGrammar, type ResolvedGrammar } from './scan.js'\n\n/** The word a severity is shown under, as VSCode titles its hovered diagnostics. */\nconst SEVERITY_TITLE: Record<Severity, string> = {\n error: 'Error',\n warning: 'Warning',\n info: 'Info',\n hint: 'Hint',\n}\n\n/**\n * Turn one diagnostic into a tooltip.\n *\n * Exported because a host that shows its own marker list wants the same wording,\n * and because a test should be able to assert the tooltip without going through\n * the ordering rules below.\n * @param diagnostic - the diagnostic.\n * @returns the tooltip.\n */\nexport function diagnosticHover(diagnostic: Diagnostic): HoverInfo {\n return {\n kind: 'diagnostic',\n title: SEVERITY_TITLE[diagnostic.severity],\n detail: diagnostic.source,\n body: diagnostic.detail === undefined ? diagnostic.message : `${diagnostic.message}\\n\\n${diagnostic.detail}`,\n range: { from: diagnostic.from, to: diagnostic.to },\n }\n}\n\n/**\n * Resolve what a hover should show at an offset.\n *\n * @param inspection - the current inspection.\n * @param grammar - the language.\n * @param offset - the character offset the pointer resolved to.\n * @returns the tooltip, or undefined when there is nothing to say.\n */\nexport function resolveHover<State>(\n inspection: Inspection<State>,\n grammar: Grammar<State> | ResolvedGrammar<State>,\n offset: number,\n): HoverInfo | undefined {\n const resolved = isResolvedGrammar(grammar) ? grammar : resolveGrammar(grammar)\n const { text, tokens, diagnostics, decorations, state } = inspection\n\n // ── a problem outranks a description ─────────────────────────────────────\n // The narrowest diagnostic wins when several overlap, so a squiggle inside a\n // wider warning still explains itself rather than its container.\n let covering: Diagnostic | undefined\n for (const diagnostic of diagnostics) {\n if (!containsOffset(diagnostic, offset)) continue\n if (covering === undefined || diagnostic.to - diagnostic.from < covering.to - covering.from) {\n covering = diagnostic\n }\n }\n if (covering !== undefined) return diagnosticHover(covering)\n\n // ── a mark the grammar made, combined with its own account of the token ──\n // Both, rather than one or the other. A decoration's title is short by design (\"in\n // effect: Geist Mono\") and the grammar's description is rich but says nothing about\n // the mark, so a tooltip that showed only one of them would always be missing the\n // half the reader wanted.\n const decoration: Decoration | undefined = decorations.find((entry) => containsOffset(entry, offset))\n const described = describeAt(inspection, resolved, offset)\n if (decoration?.title !== undefined) {\n return {\n kind: 'decoration',\n title: decoration.title,\n detail: described?.detail ?? described?.title,\n body: described?.body,\n range: { from: decoration.from, to: decoration.to },\n }\n }\n\n return described\n}\n\n/**\n * Ask the grammar what a token is.\n *\n * Split out because the decoration branch above wants the same answer and must not\n * build a second context for it — one parse, one description, however many tooltips\n * are made from it.\n * @param inspection - the current inspection.\n * @param resolved - the resolved grammar.\n * @param offset - the offset being described.\n * @returns the description, or undefined when the grammar has none.\n */\nfunction describeAt<State>(\n inspection: Inspection<State>,\n resolved: ResolvedGrammar<State>,\n offset: number,\n): HoverInfo | undefined {\n if (resolved.grammar.describe === undefined) return undefined\n const { text, tokens, diagnostics, state } = inspection\n const found = tokenAt(tokens, offset)\n // Whitespace is painted like anything else, so a token IS found in blank space — and a\n // grammar handed one will describe it, which is how resting the pointer on a gap produced a\n // tooltip naming the fallback scope. There is no thing under the pointer to explain, so the\n // grammar is told there is no token; a grammar that wants to say something about the\n // POSITION can still do so, because `describe` is called either way.\n const token = found === undefined || found.text.trim() === '' ? undefined : found\n const context: HoverContext<State> = {\n text,\n offset,\n token,\n word: wordInfoAt(text, offset, resolved.wordChars),\n line: lineAt(text, offset, lineStarts(text)),\n tokens,\n diagnostics,\n state,\n }\n return resolved.grammar.describe(context) ?? undefined\n}\n","// ─── grammar: the two identity functions authors actually want ──────────────\n//\n// Neither does anything at runtime, and that is not a joke at the reader's\n// expense: `defineGrammar` exists so `State` is inferred from `analyze` and then\n// enforced everywhere else. Written as a bare object literal, a grammar whose\n// `analyze` returns `{ entries: Entry[] }` would have every hook's `context.state`\n// typed as `unknown`, and the author would spend the afternoon casting.\n//\n// const grammar = defineGrammar({\n// id: 'my-language',\n// rules: [...],\n// analyze: (text) => ({ lines: text.split('\\n') }), // State is inferred\n// compose: [{\n// id: 'values',\n// range: (context) => ({ from: 0, to: context.caret }),\n// items: (context) => context.state.lines.map(...), // typed, not cast\n// }],\n// })\n\nimport type { CompletionSource, Grammar } from './types.js'\n\n/**\n * Declare a grammar, inferring its state type from `analyze`.\n * @param grammar - the grammar.\n * @returns the same grammar, typed.\n */\nexport function defineGrammar<State = unknown>(grammar: Grammar<State>): Grammar<State> {\n return grammar\n}\n\n/**\n * Declare a completion source, inferring the state type from its context.\n * @param source - the source.\n * @returns the same source, typed.\n */\nexport function defineCompletion<State = unknown>(\n source: CompletionSource<State>,\n): CompletionSource<State> {\n return source\n}\n","// ─── styles: the one stylesheet ─────────────────────────────────────────────\n//\n// The CSS lives in a TypeScript string so it can be injected with no build step\n// and no CSS loader, which is what keeps the library usable from a plain script\n// tag. `scripts/build-css.mjs` also writes it out as `dist/styles.css` for the\n// hosts that would rather link it, from this same string, so the two can never\n// disagree.\n//\n// The alignment contract\n// ----------------------\n// The painted layer sits behind the real textarea and draws the same characters, so it may\n// change only what does not move a glyph: colour, background, and text-decoration. Anything\n// that changes an advance — a different font, a weight, letter-spacing, a font-feature —\n// slides the paint off the character it belongs to, and by a different amount on every\n// character, so it reads as a rendering glitch rather than as a styling mistake.\n//\n// The two elements therefore share ONE rule for their typography, and that rule is the only\n// thing that has to hold. THE FONT ITSELF IS THE HOST'S CHOICE: a proportional face aligns just\n// as well as a monospace one, because the layer, the field, and the measuring mirror all read\n// the same computed font. `--litearea-font` is a variable like any other.\n//\n// What is NOT the host's choice is ligatures and kerning, which are forced off, and the reason\n// is subtler than \"a ligature would look wrong\". A ligature draws one glyph where the field\n// holds two characters — and the layer splits its spans wherever a diagnostic or a decoration\n// begins, which cuts a ligature in half. The field would then render one glyph and the layer\n// two, at different widths, and the rest of the line would slide. Turning them off removes the\n// possibility rather than relying on no span boundary ever landing inside a pair.\n\n/**\n * One colour per scope, in one list, because the variables and the rules that use them MUST\n * agree and once did not.\n *\n * Twenty-nine scope variables were declared here with no rule anywhere that consumed them. The\n * tokenizer painted the right classes, the variables were documented, the stylesheet looked\n * complete — and every scope rendered in the inherited text colour, so the editor had no syntax\n * colouring at all. Nothing in the DOM revealed it: the spans were correct. Generating both\n * halves from this list is the fix, and it is the kind of drift a browser check cannot catch\n * either, since a colourless token is a perfectly ordinary thing to find.\n *\n * A key is the FOLDED scope name, which is what a scope becomes as a class: `value.shape` is\n * written `value-shape` here because `scopeClass` turns its dots into hyphens.\n */\nconst SCOPE_PALETTE: ReadonlyArray<{ scope: string; light: string; dark?: string }> = [\n { scope: 'text', light: 'var(--litearea-fg)' },\n { scope: 'word', light: 'var(--litearea-fg)' },\n { scope: 'family', light: 'var(--litearea-fg)' },\n { scope: 'family-generic', light: '#7c3aed', dark: '#c4a2ff' },\n { scope: 'family-unknown', light: 'var(--litearea-warning)' },\n { scope: 'family-unclosed', light: 'var(--litearea-error)' },\n { scope: 'weight', light: 'var(--litearea-accent)' },\n { scope: 'weight-missing', light: 'var(--litearea-warning)' },\n { scope: 'state', light: 'var(--litearea-accent)' },\n { scope: 'property', light: '#7c3aed', dark: '#c4a2ff' },\n { scope: 'operator', light: 'var(--litearea-fg-dim)' },\n { scope: 'separator', light: 'var(--litearea-fg-dim)' },\n { scope: 'value-shape', light: '#0f766e', dark: '#5eead4' },\n { scope: 'value-color', light: '#0f766e', dark: '#5eead4' },\n { scope: 'value-pattern', light: '#0f766e', dark: '#5eead4' },\n { scope: 'value-motion', light: '#0f766e', dark: '#5eead4' },\n { scope: 'value-number', light: '#b45309', dark: '#fbbf24' },\n { scope: 'comment', light: 'var(--litearea-fg-dim)' },\n { scope: 'invalid', light: 'var(--litearea-error)' },\n { scope: 'keyword', light: 'var(--litearea-accent)' },\n { scope: 'string', light: '#0f766e', dark: '#5eead4' },\n { scope: 'number', light: '#b45309', dark: '#fbbf24' },\n]\n\n/**\n * The variable declarations for one colour scheme.\n * @param scheme - `light` declares every scope; `dark` declares only those that differ.\n * @returns one CSS declaration per line.\n */\nfunction scopeVariables(scheme: 'light' | 'dark'): string {\n return SCOPE_PALETTE.filter((entry) => scheme === 'light' || entry.dark !== undefined)\n .map((entry) => {\n const value = scheme === 'light' ? entry.light : entry.dark\n return ` --litearea-scope-${entry.scope}: ${String(value)};`\n })\n .join('\\n')\n}\n\n/**\n * The rules that spend those variables.\n * @returns one CSS rule per line.\n */\nfunction scopeRules(): string {\n return SCOPE_PALETTE.map(\n (entry) =>\n `.litearea-scope-${entry.scope} { color: var(--litearea-scope-${entry.scope}); }`,\n ).join('\\n')\n}\n\n/** Everything a scope or a mark is painted with comes from one of these. */\nexport const LITEAREA_STYLES = `\n.litearea {\n --litearea-font: ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace;\n --litearea-font-size: 13px;\n --litearea-line-height: 20px;\n --litearea-padding-block: 6px;\n --litearea-padding-inline: 10px;\n --litearea-radius: 8px;\n --litearea-fg: #1f2328;\n --litearea-fg-dim: #6b7280;\n --litearea-fg-strong: #111827;\n --litearea-bg: #ffffff;\n --litearea-bg-raised: #ffffff;\n --litearea-border: #d8dbe0;\n --litearea-border-focus: #4d6bfe;\n --litearea-accent: #4d6bfe;\n --litearea-accent-soft: rgba(77, 107, 254, 0.12);\n --litearea-selection: rgba(77, 107, 254, 0.22);\n --litearea-error: #e5484d;\n --litearea-warning: #d97706;\n --litearea-info: #4d6bfe;\n --litearea-hint: #8b8f97;\n --litearea-shadow: 0 6px 24px rgba(15, 23, 42, 0.14);\n\n${scopeVariables('light')}\n\n position: relative;\n display: block;\n color: var(--litearea-fg);\n}\n\n@media (prefers-color-scheme: dark) {\n .litearea {\n --litearea-fg: #e6e8eb;\n --litearea-fg-dim: #8b919b;\n --litearea-fg-strong: #ffffff;\n --litearea-bg: #1b1e24;\n --litearea-bg-raised: #23262c;\n --litearea-border: #363b44;\n${scopeVariables('dark')}\n --litearea-error: #ff6b6b;\n --litearea-warning: #f59e0b;\n --litearea-shadow: 0 6px 24px rgba(0, 0, 0, 0.5);\n }\n}\n\n/* ── the box ─────────────────────────────────────────────────────────────── */\n\n.litearea-box {\n position: relative;\n display: block;\n border: 1px solid var(--litearea-border);\n border-radius: var(--litearea-radius);\n background: var(--litearea-bg);\n transition: border-color 120ms ease;\n}\n\n.litearea-box:focus-within {\n border-color: var(--litearea-border-focus);\n}\n\n.litearea-invalid .litearea-box {\n border-color: var(--litearea-error);\n}\n\n/*\n * The layer and the field share this rule and nothing may be added to one alone.\n * Every property here is a property the mirror copies too — three elements, one\n * typography, or the paint drifts.\n */\n.litearea-layer,\n.litearea-input {\n box-sizing: border-box;\n width: 100%;\n margin: 0;\n padding: var(--litearea-padding-block) var(--litearea-padding-inline);\n border: none;\n font-family: var(--litearea-font);\n font-size: var(--litearea-font-size);\n font-weight: 400;\n font-style: normal;\n font-stretch: normal;\n font-variant-ligatures: none;\n font-kerning: none;\n font-feature-settings: \"liga\" 0, \"calt\" 0, \"dlig\" 0;\n line-height: var(--litearea-line-height);\n letter-spacing: normal;\n word-spacing: normal;\n text-transform: none;\n text-indent: 0;\n text-align: left;\n direction: ltr;\n tab-size: 2;\n white-space: pre-wrap;\n overflow-wrap: break-word;\n word-break: break-word;\n}\n\n.litearea-layer {\n position: absolute;\n inset: 0;\n overflow: hidden;\n pointer-events: none;\n user-select: none;\n}\n\n/*\n * When the box is clamped to its maximum height the field grows a scrollbar, and a\n * scrollbar narrows the text. If the layer kept the full width it would wrap\n * differently from the field and every colour would slide off its character, so the\n * field's measured scrollbar width is published as --litearea-scrollbar and added\n * here. The value is 0 whenever no scrollbar is shown.\n */\n.litearea-layer {\n padding-right: calc(var(--litearea-padding-inline) + var(--litearea-scrollbar, 0px));\n}\n\n.litearea-paint {\n position: relative;\n min-height: 100%;\n /* A zero-width space keeps the layer's last line box as tall as the field's:\n a trailing newline would otherwise collapse in the paint alone, and the box\n would jump the moment one was typed. */\n will-change: transform;\n}\n\n.litearea-input {\n position: relative;\n display: block;\n resize: none;\n background: transparent;\n color: transparent;\n caret-color: var(--litearea-fg);\n outline: none;\n overflow-y: hidden;\n}\n\n.litearea-growable .litearea-input {\n resize: none;\n}\n\n.litearea-resizable .litearea-input {\n resize: vertical;\n}\n\n.litearea-input::placeholder {\n color: var(--litearea-fg-dim);\n}\n\n.litearea-input::selection {\n background: var(--litearea-selection);\n}\n\n.litearea-readonly .litearea-input {\n caret-color: transparent;\n}\n\n/*\n * The rules that spend the variables, generated from the same list that declares them. There is\n * deliberately NO catch-all rule setting a property on every painted span: there was one, and a\n * class plus an element outranks a bare class on specificity, so it silently switched off every\n * squiggle in the library.\n *\n * A scope that is not in the list gets no colour from here, and a host writing a grammar of its\n * own styles it with a plain rule — .litearea-scope-my-thing { color: … } — since nothing in\n * this file competes for that selector.\n */\n${scopeRules()}\n\n.litearea-dec-effective {\n border-radius: 3px;\n background: var(--litearea-accent-soft);\n box-shadow: 0 0 0 1px var(--litearea-accent-soft);\n}\n\n/* The four shapes a diagnostic can take. Wavy for the two that mean \"fix this\", dotted for\n the two that mean \"worth knowing\" — the same distinction VSCode draws, and the reason\n severity is a class rather than an inline colour. */\n.litearea-diag-error {\n text-decoration-line: underline;\n text-decoration-style: wavy;\n text-decoration-color: var(--litearea-error);\n text-decoration-skip-ink: none;\n text-underline-offset: 3px;\n}\n\n.litearea-diag-warning {\n text-decoration-line: underline;\n text-decoration-style: wavy;\n text-decoration-color: var(--litearea-warning);\n text-decoration-skip-ink: none;\n text-underline-offset: 3px;\n}\n\n.litearea-diag-info {\n text-decoration-line: underline;\n text-decoration-style: dotted;\n text-decoration-color: var(--litearea-info);\n text-decoration-skip-ink: none;\n text-underline-offset: 3px;\n}\n\n.litearea-diag-hint {\n text-decoration-line: underline;\n text-decoration-style: dotted;\n text-decoration-color: var(--litearea-hint);\n text-decoration-skip-ink: none;\n text-underline-offset: 3px;\n}\n\n/* ── the completion list ─────────────────────────────────────────────────── */\n\n/*\n * The container holds two things and scrolls NEITHER of them: the list scrolls itself, and the\n * documentation is pinned below it. Putting the documentation inside the scroll range — which is\n * what this used to do — makes it unreachable with a long list and a long explanation: the\n * arrows move the active row rather than the scrollbar, so a keyboard user never sees it, and a\n * mouse user has to scroll down to read it and back up to reach the next row.\n */\n.litearea-popup {\n position: absolute;\n z-index: 30;\n display: none;\n flex-direction: column;\n max-width: 460px;\n padding: 4px;\n border: 1px solid var(--litearea-border);\n border-radius: 10px;\n background: var(--litearea-bg-raised);\n box-shadow: var(--litearea-shadow);\n font-family: var(--litearea-font);\n font-size: 12px;\n line-height: 18px;\n color: var(--litearea-fg);\n overflow: hidden;\n}\n\n.litearea-popup[data-open=\"true\"] {\n display: flex;\n}\n\n/* The rows, and the only part that scrolls. Its height is bounded so the documentation below\n always has somewhere to live. */\n.litearea-list {\n min-height: 0;\n max-height: 208px;\n overflow-y: auto;\n}\n\n/*\n * The explanation, pinned. Its own height is bounded and it scrolls ITSELF, so a long\n * explanation stays readable while the rows stay put — and arrowing to the next row swaps the\n * text in place instead of requiring a scroll back up.\n */\n.litearea-docs {\n flex: none;\n max-height: 132px;\n overflow-y: auto;\n margin: 4px -4px -4px;\n padding: 6px 10px;\n border-top: 1px solid var(--litearea-border);\n background: var(--litearea-bg);\n border-radius: 0 0 10px 10px;\n color: var(--litearea-fg);\n white-space: pre-wrap;\n}\n\n.litearea-popup[data-docs=\"false\"] .litearea-docs {\n display: none;\n}\n\n.litearea-row {\n display: flex;\n align-items: baseline;\n gap: 8px;\n padding: 3px 6px;\n border-radius: 6px;\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n}\n\n.litearea-row[aria-selected=\"true\"] {\n background: var(--litearea-accent-soft);\n}\n\n.litearea-rowKind {\n flex: none;\n width: 7px;\n height: 7px;\n border-radius: 2px;\n background: var(--litearea-fg-dim);\n transform: translateY(-1px);\n}\n\n.litearea-kind-family { background: var(--litearea-scope-family-generic); }\n.litearea-kind-generic { background: var(--litearea-scope-family-generic); }\n.litearea-kind-weight { background: var(--litearea-scope-weight); }\n.litearea-kind-state { background: var(--litearea-scope-state); }\n.litearea-kind-property { background: var(--litearea-scope-property); }\n.litearea-kind-value { background: var(--litearea-scope-value-shape); }\n.litearea-kind-number { background: var(--litearea-scope-value-number); }\n.litearea-kind-custom { background: var(--litearea-fg-dim); }\n\n.litearea-rowLabel {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.litearea-rowMatch {\n color: var(--litearea-accent);\n font-weight: 600;\n}\n\n.litearea-rowDetail {\n flex: none;\n color: var(--litearea-fg-dim);\n font-size: 11px;\n}\n\n.litearea-docsTitle {\n font-weight: 600;\n}\n\n.litearea-docsDetail {\n color: var(--litearea-fg-dim);\n}\n\n.litearea-docsBody {\n margin-top: 2px;\n color: var(--litearea-fg-dim);\n}\n\n/* ── the hover tooltip ───────────────────────────────────────────────────── */\n\n.litearea-tooltip {\n position: absolute;\n z-index: 40;\n display: none;\n max-width: 340px;\n padding: 6px 10px;\n border: 1px solid var(--litearea-border);\n border-radius: 8px;\n background: var(--litearea-bg-raised);\n box-shadow: var(--litearea-shadow);\n font-family: var(--litearea-font);\n font-size: 11px;\n line-height: 16px;\n color: var(--litearea-fg);\n pointer-events: none;\n white-space: pre-wrap;\n}\n\n.litearea-tooltip[data-open=\"true\"] {\n display: block;\n}\n\n.litearea-tooltipTitle {\n font-weight: 600;\n}\n\n.litearea-tooltipDetail {\n color: var(--litearea-fg-dim);\n}\n\n.litearea-tooltipBody {\n margin-top: 3px;\n color: var(--litearea-fg-dim);\n}\n\n.litearea-srOnly {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n`.trim()\n\n/**\n * Put the stylesheet in a document, once.\n *\n * Marked with a data attribute so two editors on one page, or two copies of the\n * library, do not stack two identical sheets — and so a host can find and replace\n * it.\n * @param ownerDocument - the document to install into.\n * @param nonce - an optional CSP nonce for the style element.\n * @returns the style element, or undefined when there is no document.\n */\nexport function injectStyles(\n ownerDocument: Document,\n nonce?: string,\n): HTMLStyleElement | undefined {\n if (ownerDocument === null || ownerDocument === undefined) return undefined\n const existing = ownerDocument.querySelector<HTMLStyleElement>('style[data-litearea-styles]')\n if (existing !== null) return existing\n const style = ownerDocument.createElement('style')\n style.dataset.liteareaStyles = ''\n if (nonce !== undefined) style.nonce = nonce\n style.textContent = LITEAREA_STYLES\n const head = ownerDocument.head ?? ownerDocument.documentElement\n if (head === null || head === undefined) return undefined\n head.appendChild(style)\n return style\n}\n\n/**\n * The class a scope is painted with.\n *\n * Dots and other punctuation are folded to hyphens, because a scope like\n * `value.shape` is a nice name to write and a terrible one to select: the CSS\n * would need a backslash before the dot at every use, and one forgotten escape\n * silently paints nothing.\n * @param scope - the scope name.\n * @returns the class name.\n */\nexport function scopeClass(scope: string): string {\n const folded = scope.replace(/[^A-Za-z0-9_-]+/g, '-').replace(/^-+|-+$/g, '')\n return folded === '' ? 'litearea-scope-text' : `litearea-scope-${folded}`\n}\n\n/** The class a decoration kind is painted with. */\nexport function decorationClass(kind: string): string {\n return `litearea-dec-${kind.replace(/[^A-Za-z0-9_-]+/g, '-')}`\n}\n\n/** The class a diagnostic severity is underlined with. */\nexport function severityClass(severity: string): string {\n return `litearea-diag-${severity.replace(/[^A-Za-z0-9_-]+/g, '-')}`\n}\n","// ─── support: what this browser can actually do ─────────────────────────────\n//\n// The engine is pure and needs nothing. This module is the only place that asks\n// the environment a question, so the answer is in one place and the rest of the\n// DOM layer can assume it.\n\n/** Whether a document is available at all, so an import is safe under Node. */\nexport function hasDocument(): boolean {\n return typeof document !== 'undefined' && document !== null\n}\n\n/**\n * Whether the browser still offers `document.execCommand`.\n *\n * It is deprecated, and it is also the only way to change a textarea's value while\n * keeping the browser's own undo stack intact — no modern input API can be driven\n * from script, because a synthetic event is untrusted and the browser refuses to\n * treat it as a user edit. So the check is not \"is this nice API available\" but\n * \"can this edit be undone\", and the editor degrades honestly when the answer is\n * no: the edit still lands, and the history it should have joined does not.\n * @returns whether an undo-preserving edit is possible.\n */\nexport function canEditThroughPipeline(): boolean {\n return hasDocument() && typeof document.execCommand === 'function'\n}\n\n/** Whether `caretPositionFromPoint` or its WebKit spelling exists. */\nexport function hasCaretHitTest(): boolean {\n if (!hasDocument()) return false\n const probe = document as Document & {\n caretPositionFromPoint?: unknown\n caretRangeFromPoint?: unknown\n }\n return (\n typeof probe.caretPositionFromPoint === 'function' ||\n typeof probe.caretRangeFromPoint === 'function'\n )\n}\n\n/**\n * The character offset a point in the viewport falls on, according to the browser.\n *\n * The browser is asked rather than the editor computing it, because hit-testing\n * wrapped, proportional text is exactly the kind of geometry a hand-written\n * measurement gets subtly wrong. A textarea's transparent text still lays out\n * normally, so the caret APIs answer for it correctly.\n * @param x - viewport x.\n * @param y - viewport y.\n * @returns the offset, or undefined when the browser cannot say.\n */\nexport function offsetFromPoint(x: number, y: number): number | undefined {\n if (!hasDocument()) return undefined\n const probe = document as Document & {\n caretPositionFromPoint?: (x: number, y: number) => { offsetNode: Node; offset: number } | null\n caretRangeFromPoint?: (x: number, y: number) => Range | null\n }\n if (typeof probe.caretPositionFromPoint === 'function') {\n const position = probe.caretPositionFromPoint(x, y)\n if (position !== null && position !== undefined) return position.offset\n return undefined\n }\n if (typeof probe.caretRangeFromPoint === 'function') {\n const range = probe.caretRangeFromPoint(x, y)\n if (range !== null && range !== undefined) return range.startOffset\n }\n return undefined\n}\n\n/**\n * Merge partial option objects without letting an explicit `undefined` win.\n *\n * `{ ...defaults, ...given }` looks right and is wrong the moment a caller passes\n * an optional field it did not fill in: the key exists, so it overwrites the\n * default with `undefined`, and the editor then behaves as if the option had been\n * switched off. This copies only the keys that were actually provided.\n * @param defaults - the base.\n * @param given - the overrides, which may be undefined.\n * @returns the merged object.\n */\nexport function withDefaults<T extends object>(defaults: T, given: Partial<T> | undefined): T {\n if (given === undefined) return { ...defaults }\n const merged = { ...defaults }\n for (const key of Object.keys(given) as Array<keyof T>) {\n const value = given[key]\n if (value !== undefined) merged[key] = value as T[keyof T]\n }\n return merged\n}\n","// ─── editing: changing a textarea without breaking its history ──────────────\n//\n// This is the module the whole library exists to get right.\n//\n// A textarea owns its own undo stack, and that stack is maintained by the\n// browser's editing pipeline — not by the value property. Assigning to\n// `field.value` replaces the text and DESTROYS the history, which is why a\n// controlled component that round-trips every keystroke through React state (or a\n// state setter of any kind) has no working Ctrl+Z. It also resets the caret to the\n// end, which is the other half of the same mistake.\n//\n// So the editor never writes `value` for an edit the user could have made. It\n// moves the selection and asks the browser to insert text, which the browser\n// records as one undoable edit:\n//\n// field.setSelectionRange(from, to)\n// document.execCommand('insertText', false, text) // ← undoable\n//\n// `execCommand` is deprecated, and there is no replacement. A synthetic\n// `beforeinput` or `InputEvent` is untrusted, so the browser will not run it\n// through the editing pipeline; `setRangeText` is the standard API and bypasses\n// the history entirely. Every editor that supports undo on a textarea uses this\n// call. Where it is missing the edit still happens through `setRangeText`, and the\n// caller is told plainly that the history did not get it, so a host can decide\n// whether that matters.\n\nimport { clamp } from '../core/text.js'\nimport { canEditThroughPipeline } from './support.js'\n\n/** A caret or selection, as offsets into the value. */\nexport interface TextSelection {\n /** The anchor end. Equal to `end` for a caret. */\n start: number\n /** The moving end. */\n end: number\n}\n\n/**\n * How an edit reached the document.\n *\n * `pipeline` means the browser recorded it and Ctrl+Z will undo it. `direct` means\n * the text changed and the history did not, which only happens where\n * `document.execCommand` is unavailable — a test environment, or a browser that\n * has finally removed it.\n */\nexport type EditOutcome = 'pipeline' | 'direct' | 'unchanged'\n\n/** Read the caret or selection out of a field. */\nexport function readSelection(field: HTMLTextAreaElement): TextSelection {\n const start = field.selectionStart ?? 0\n const end = field.selectionEnd ?? start\n return { start, end }\n}\n\n/**\n * Put a caret or selection into a field.\n *\n * Setting a selection moves the caret and nothing else: it does not touch the\n * value, so it cannot disturb the undo stack. This is what the editor uses instead\n * of re-rendering text to reposition the caret — the re-render was the bug.\n *\n * A range given the wrong way round is ordered rather than collapsed. `start` and\n * `end` are named for a caret and a selection, and a caller that computes them from a\n * backwards drag has still asked for that text to be selected; quietly selecting\n * nothing at the far end would be a silent wrong answer.\n * @param field - the textarea.\n * @param start - the anchor offset.\n * @param end - the moving offset; defaults to `start`.\n */\nexport function writeSelection(\n field: HTMLTextAreaElement,\n start: number,\n end: number = start,\n): void {\n const length = field.value.length\n const from = clamp(Math.min(start, end), 0, length)\n const to = clamp(Math.max(start, end), from, length)\n field.setSelectionRange(from, to)\n}\n\n/** The line height in force on a field, falling back to the computed font size. */\nexport function fieldLineHeight(field: HTMLTextAreaElement): number {\n const styles = field.ownerDocument.defaultView?.getComputedStyle(field)\n if (styles === null || styles === undefined) return 0\n const lineHeight = Number.parseFloat(styles.lineHeight)\n if (Number.isFinite(lineHeight)) return lineHeight\n const fontSize = Number.parseFloat(styles.fontSize)\n return Number.isFinite(fontSize) ? fontSize * 1.2 : 0\n}\n\n/**\n * Replace a range through the browser's editing pipeline, so it can be undone.\n *\n * The field is focused first because the pipeline only runs on the focused\n * element, and a completion accepted by mouse click would otherwise arrive after\n * the click had already blurred the field.\n * @param field - the textarea.\n * @param from - the first offset to replace.\n * @param to - the offset after the last.\n * @param text - what to put there. The empty string deletes.\n * @returns how the edit landed.\n */\nexport function replaceThroughPipeline(\n field: HTMLTextAreaElement,\n from: number,\n to: number,\n text: string,\n): EditOutcome {\n const start = clamp(Math.min(from, to), 0, field.value.length)\n const end = clamp(Math.max(from, to), start, field.value.length)\n if (start === end && text === '') return 'unchanged'\n\n if (field.ownerDocument.activeElement !== field) field.focus({ preventScroll: true })\n writeSelection(field, start, end)\n\n const before = field.value\n if (canEditThroughPipeline()) {\n try {\n field.ownerDocument.execCommand('insertText', false, text)\n } catch {\n // Firefox throws rather than returning false for some input types. Falling\n // through to the direct path is the right answer either way.\n }\n // The return value is not trustworthy across browsers, and it does not need to\n // be: the VALUE decides. A change we did not make ourselves is one the\n // browser's history already knows about, which is the whole point.\n if (field.value !== before) return 'pipeline'\n }\n\n field.setRangeText(text, start, end, 'end')\n if (field.value === before) return 'unchanged'\n dispatchInput(field, text)\n return 'direct'\n}\n\n/**\n * Fire the event the browser would have fired, for the direct path only.\n *\n * The pipeline path needs no help: the browser dispatches `input` itself, which is\n * exactly why the editor can treat both paths the same way downstream.\n * @param field - the textarea.\n * @param text - what was written.\n */\nexport function dispatchInput(field: HTMLTextAreaElement, text: string): void {\n const view = field.ownerDocument.defaultView\n const InputEventCtor = view === null ? undefined : (view as Window & { InputEvent?: typeof InputEvent }).InputEvent\n if (typeof InputEventCtor === 'function') {\n field.dispatchEvent(\n new InputEventCtor('input', { bubbles: true, inputType: 'insertText', data: text }),\n )\n return\n }\n field.dispatchEvent(new Event('input', { bubbles: true }))\n}\n\n/**\n * Undo, through the browser's own history.\n *\n * Exposed so a host can offer a button without reimplementing a stack, and so the\n * browser harness can drive the same path a keyboard shortcut drives.\n * @param field - the textarea.\n * @returns whether the call was possible at all. It cannot report whether anything\n * was actually undone, because no browser exposes that.\n */\nexport function undoField(field: HTMLTextAreaElement): boolean {\n if (!canEditThroughPipeline()) return false\n if (field.ownerDocument.activeElement !== field) field.focus({ preventScroll: true })\n try {\n return field.ownerDocument.execCommand('undo')\n } catch {\n return false\n }\n}\n\n/**\n * Redo, through the browser's own history.\n * @param field - the textarea.\n * @returns whether the call was possible at all.\n */\nexport function redoField(field: HTMLTextAreaElement): boolean {\n if (!canEditThroughPipeline()) return false\n if (field.ownerDocument.activeElement !== field) field.focus({ preventScroll: true })\n try {\n return field.ownerDocument.execCommand('redo')\n } catch {\n return false\n }\n}\n\n/**\n * Write a whole document into a field.\n *\n * Two paths, and the difference matters. `preserveHistory` selects everything and\n * inserts through the pipeline, so the replacement is one undoable edit and Ctrl+Z\n * brings the previous text back — the right behaviour for a Reset button. Without\n * it the value property is assigned, which is faster and clears the history, which\n * is the right behaviour when a host is loading a different document entirely.\n * @param field - the textarea.\n * @param next - the new text.\n * @param preserveHistory - whether the change should be undoable.\n * @returns how the write landed.\n */\nexport function writeDocument(\n field: HTMLTextAreaElement,\n next: string,\n preserveHistory = false,\n): EditOutcome {\n if (field.value === next) return 'unchanged'\n if (preserveHistory) return replaceThroughPipeline(field, 0, field.value.length, next)\n field.value = next\n writeSelection(field, next.length, next.length)\n return 'direct'\n}\n","// ─── mirror: measuring text the textarea will not tell us ───────────────────\n//\n// A textarea can report its `scrollHeight` and its selection offsets, and that is\n// the whole of it. It cannot say where the caret is on screen, and its\n// `scrollHeight` cannot be trusted while its own height is being changed — asking\n// for it means first collapsing the element, which reflows the page and makes the\n// box flicker on every keystroke.\n//\n// So a second element is kept offscreen with the field's exact typography and the\n// same box, and the question is asked of IT. Two jobs come out of the same\n// element: where the caret is, and how tall the content is. Both are pure\n// measurements of text, both need the same copied styles, and both are wrong in\n// the same way if a single property is missed — which is why there is one mirror\n// and not two.\n//\n// `visibility: hidden` rather than `display: none`, because a hidden element still\n// lays out and a removed one does not.\n\nimport { clamp } from '../core/text.js'\n\n/**\n * The properties that decide where a glyph lands.\n *\n * Anything in this list that the mirror does not copy makes every measurement\n * wrong by a little, and the failures are not obvious: a missing\n * `letter-spacing` moves the caret a fraction of a character per character, so the\n * popup drifts further off the longer the line is. The list is deliberately\n * exhaustive rather than \"the ones that seemed to matter\".\n */\nconst COPIED_PROPERTIES = [\n 'fontFamily',\n 'fontSize',\n 'fontWeight',\n 'fontStyle',\n 'fontStretch',\n 'fontVariantLigatures',\n 'fontKerning',\n 'fontFeatureSettings',\n 'lineHeight',\n 'letterSpacing',\n 'wordSpacing',\n 'textTransform',\n 'textIndent',\n 'textAlign',\n 'direction',\n 'tabSize',\n 'whiteSpace',\n 'overflowWrap',\n 'wordBreak',\n 'hyphens',\n 'paddingTop',\n 'paddingRight',\n 'paddingBottom',\n 'paddingLeft',\n 'borderTopWidth',\n 'borderRightWidth',\n 'borderBottomWidth',\n 'borderLeftWidth',\n 'borderTopStyle',\n 'borderRightStyle',\n 'borderBottomStyle',\n 'borderLeftStyle',\n 'boxSizing',\n] as const\n\n/** Where the caret is, in pixels relative to the field's border box. */\nexport interface CaretBox {\n /** Distance from the field's left border edge to the caret. */\n x: number\n /** Distance from the field's top border edge to the caret's line box. */\n y: number\n /** The height of the caret's line. */\n height: number\n /** The line height in force, whether or not it was declared. */\n lineHeight: number\n}\n\n/** A zero-width space: content that draws nothing and occupies a line. */\nconst SENTINEL = '\\u200b'\n\n/**\n * An offscreen element that lays text out exactly as a given textarea does.\n *\n * One instance per field is enough; the editor owns exactly one.\n */\nexport class TextMirror {\n /** The measuring element. Kept out of the document's flow by `position: fixed`. */\n readonly element: HTMLDivElement\n private readonly document: Document\n private readonly view: Window | undefined\n /** The field this mirror is currently shaped like. */\n private adopted: HTMLTextAreaElement | undefined\n /** The line height measured with the field, or 0 before the first measurement. */\n private measuredLineHeight = 0\n\n /**\n * @param ownerDocument - the document to create the element in.\n */\n constructor(ownerDocument: Document) {\n this.document = ownerDocument\n this.view = ownerDocument.defaultView ?? undefined\n this.element = ownerDocument.createElement('div')\n this.element.setAttribute('aria-hidden', 'true')\n this.element.dataset.liteareaPart = 'mirror'\n // `white-space: pre-wrap` is the one property both jobs depend on absolutely:\n // a newline has to break the line in the mirror exactly as it does in the\n // field, and a run of spaces has to survive.\n this.element.style.cssText = [\n 'position:fixed',\n 'top:0',\n 'left:0',\n 'visibility:hidden',\n 'pointer-events:none',\n 'z-index:-1',\n 'margin:0',\n 'overflow:hidden',\n 'white-space:pre-wrap',\n 'overflow-wrap:break-word',\n 'word-break:break-word',\n 'box-sizing:border-box',\n ].join(';')\n }\n\n /** Whether the mirror is in a document. */\n get mounted(): boolean {\n return this.element.isConnected\n }\n\n /**\n * Mount the mirror, once, so measurements have a layout to read.\n * @param parent - where to mount it. The body is right unless the document has none.\n */\n mount(parent?: Element): void {\n if (this.mounted) return\n const host = parent ?? this.document.body ?? this.document.documentElement\n if (host === null || host === undefined) return\n host.appendChild(this.element)\n }\n\n /**\n * Shape the mirror like a field.\n *\n * The width is the interesting part. It has to be the field's CONTENT width, or\n * text wraps in one and not the other — and the field's `clientWidth` is its\n * content plus padding but NOT its border, while the mirror is `border-box`. So\n * the borders are added back, and what is deliberately left out is the\n * scrollbar: a field clamped to its maximum height has one, and the text wraps\n * inside the narrower area above it.\n * @param field - the textarea to imitate.\n */\n adopt(field: HTMLTextAreaElement): void {\n this.mount()\n this.adopted = field\n const view = this.view\n if (view === null || view === undefined) return\n const styles = view.getComputedStyle(field)\n for (const property of COPIED_PROPERTIES) {\n this.element.style.setProperty(\n property.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`),\n styles.getPropertyValue(property.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)),\n )\n }\n const borderLeft = Number.parseFloat(styles.borderLeftWidth) || 0\n const borderRight = Number.parseFloat(styles.borderRightWidth) || 0\n this.element.style.width = `${String(field.clientWidth + borderLeft + borderRight)}px`\n this.measuredLineHeight = 0\n }\n\n /**\n * The line height in force, measured rather than assumed.\n *\n * `line-height: normal` is a real value and a common one, and it cannot be read\n * as a number — `parseFloat('normal')` is `NaN`. So it is measured by laying one\n * line of text out and taking the height, which is also the only way to be right\n * about a font whose normal leading is not 1.2.\n * @param field - the field to measure against.\n * @returns the line height in pixels.\n */\n lineHeight(field: HTMLTextAreaElement): number {\n if (this.measuredLineHeight > 0) return this.measuredLineHeight\n const view = this.view\n if (view === null || view === undefined) return 0\n const styles = view.getComputedStyle(field)\n const declared = Number.parseFloat(styles.lineHeight)\n if (Number.isFinite(declared) && declared > 0) {\n this.measuredLineHeight = declared\n return declared\n }\n this.adopt(field)\n this.setText('M')\n const padding = this.verticalPadding()\n const height = this.element.getBoundingClientRect().height - padding\n // A font that reports nothing usable still needs an answer, and 1.2 × the font\n // size is what `normal` means for essentially every font in practice.\n const fontSize = Number.parseFloat(styles.fontSize)\n const fallback = (Number.isFinite(fontSize) ? fontSize : 16) * 1.2\n this.measuredLineHeight = height > 0 ? height : fallback\n return this.measuredLineHeight\n }\n\n /** The mirror's vertical padding plus border, which every height includes. */\n verticalPadding(): number {\n const view = this.view\n if (view === null || view === undefined) return 0\n const styles = view.getComputedStyle(this.element)\n const sum =\n (Number.parseFloat(styles.paddingTop) || 0) +\n (Number.parseFloat(styles.paddingBottom) || 0) +\n (Number.parseFloat(styles.borderTopWidth) || 0) +\n (Number.parseFloat(styles.borderBottomWidth) || 0)\n return sum\n }\n\n /**\n * Put text in the mirror with nothing else in it.\n * @param text - the content.\n */\n setText(text: string): void {\n this.element.textContent = text\n }\n\n /**\n * The height a field needs to show a document without scrolling.\n *\n * The trailing-newline problem is handled here. A div with `white-space:\n * pre-wrap` and content ending in `\\n` does not lay out a final empty line — the\n * newline breaks the line but nothing follows it — so the measured height comes\n * back one line short and the field grows a scrollbar exactly when the user\n * presses Enter at the end. A zero-width space after the newline gives that last\n * line something to be.\n * @param field - the field being sized.\n * @param value - the text it holds.\n * @returns the border-box height the content requires.\n */\n contentHeight(field: HTMLTextAreaElement, value: string): number {\n this.adopt(field)\n const needsSentinel = value === '' || value.endsWith('\\n') || value.endsWith('\\r')\n this.setText(needsSentinel ? `${value}${SENTINEL}` : value)\n return this.element.getBoundingClientRect().height\n }\n\n /**\n * Where the caret sits, in pixels relative to the field's border box.\n *\n * The trick is a marker element holding the character AFTER the caret, measured\n * against the mirror. Everything before the caret lays out normally, so the\n * marker lands exactly where the next glyph will be — which is where the caret\n * is. At the end of the document there is no next character, so a zero-width\n * space stands in for it.\n *\n * The field's own scroll offset is subtracted, because the caret's position on\n * screen is what the popup has to be placed against, and a scrolled field moves\n * its text without moving its border box.\n *\n * @param field - the field the caret is in.\n * @param offset - the caret's character offset.\n * @returns the caret box, or undefined when there is no layout to measure.\n */\n caretBox(field: HTMLTextAreaElement, offset: number): CaretBox | undefined {\n const view = this.view\n if (view === null || view === undefined) return undefined\n this.adopt(field)\n const value = field.value\n const position = clamp(offset, 0, value.length)\n const before = value.slice(0, position)\n const after = value.slice(position)\n const next = after === '' ? SENTINEL : after.charAt(0)\n\n // Rebuilt rather than patched: the mirror is offscreen and measuring it is\n // cheap, while keeping incremental DOM in step with a fast typist is not.\n this.element.textContent = ''\n this.element.appendChild(this.document.createTextNode(before))\n const marker = this.document.createElement('span')\n marker.textContent = next\n // A span that can wrap would let the marker jump to the next line on its own,\n // which is exactly the wrong answer for a caret at a line end.\n marker.style.whiteSpace = 'pre'\n this.element.appendChild(marker)\n this.element.appendChild(this.document.createTextNode(after.slice(next.length)))\n\n const mirrorRect = this.element.getBoundingClientRect()\n const markerRect = marker.getBoundingClientRect()\n const lineHeight = this.lineHeight(field)\n return {\n x: markerRect.left - mirrorRect.left - field.scrollLeft,\n y: markerRect.top - mirrorRect.top - field.scrollTop,\n height: markerRect.height > 0 ? markerRect.height : lineHeight,\n lineHeight,\n }\n }\n\n /** Take the mirror out of the document. */\n destroy(): void {\n this.element.remove()\n this.adopted = undefined\n }\n\n /**\n * The field this mirror was last shaped like.\n * @returns the field, or undefined before {@link adopt}.\n */\n get field(): HTMLTextAreaElement | undefined {\n return this.adopted\n }\n}\n","// ─── overlay: the painted layer behind the field ────────────────────────────\n//\n// The layer draws the same characters as the textarea, in colour, and it is\n// positioned to share the field's box exactly. It never measures anything: the\n// segments come out of `buildSegments` in document order and are appended back to\n// back, so the browser's own text layout puts every character where the field put\n// it. The only thing this module does besides writing DOM is keep the layer\n// scrolled with the field.\n\nimport type { SegmentInput } from '../core/segments.js'\nimport { buildSegments, segmentClasses } from '../core/segments.js'\n\n/** How the layer turns a scope, a decoration, or a severity into a class. */\nexport interface OverlayClassNames {\n scope: (scope: string) => string\n decoration: (kind: string) => string\n severity: (severity: string) => string\n}\n\n/** The painted layer and the element that holds the paint. */\nexport class Overlay {\n /** The scroll container. Same box as the field. */\n readonly element: HTMLDivElement\n /** The element the spans are written into. */\n private readonly paint: HTMLDivElement\n private readonly document: Document\n private readonly classNames: OverlayClassNames\n /** What was painted last, so an unchanged document is not repainted. */\n private paintedText: string | undefined\n private paintedKey = ''\n\n /**\n * @param ownerDocument - the document to build in.\n * @param classNames - the three class-name mappings.\n */\n constructor(ownerDocument: Document, classNames: OverlayClassNames) {\n this.document = ownerDocument\n this.classNames = classNames\n this.element = ownerDocument.createElement('div')\n this.element.className = 'litearea-layer'\n this.element.setAttribute('aria-hidden', 'true')\n this.element.dataset.liteareaPart = 'layer'\n this.paint = ownerDocument.createElement('div')\n this.paint.className = 'litearea-paint'\n this.element.appendChild(this.paint)\n }\n\n /**\n * Paint a document.\n *\n * `key` is whatever the caller knows changed. When it and the text both match\n * the last call the work is skipped, which is what keeps a caret move or a\n * mouse hover from rebuilding every span on the page.\n * @param text - the document.\n * @param input - the tokens, decorations, and diagnostics.\n * @param key - a cheap signature of everything that affects the paint.\n * @param fallbackScope - the scope for characters no token covers.\n */\n render(text: string, input: SegmentInput, key: string, fallbackScope = 'text'): void {\n if (this.paintedText === text && this.paintedKey === key) return\n const segments = buildSegments(text, input, fallbackScope)\n const fragment = this.document.createDocumentFragment()\n for (const segment of segments) {\n const span = this.document.createElement('span')\n span.className = segmentClasses(\n segment,\n this.classNames.scope,\n this.classNames.decoration,\n this.classNames.severity,\n ).join(' ')\n if (segment.title !== undefined) span.title = segment.title\n span.textContent = segment.text\n fragment.appendChild(span)\n }\n this.paint.replaceChildren(fragment)\n this.paintedText = text\n this.paintedKey = key\n }\n\n /**\n * Follow the field's scroll position.\n *\n * The layer is `overflow: hidden` and its content is taller than its box exactly\n * when the field is: an auto-grown field has nothing to scroll and a field\n * clamped to its maximum height has everything to scroll. Copying the offset is\n * therefore enough, and it is more reliable than a transform, which can leave\n * the text on a half pixel.\n * @param field - the textarea.\n */\n syncScroll(field: HTMLTextAreaElement): void {\n if (this.element.scrollTop !== field.scrollTop) this.element.scrollTop = field.scrollTop\n if (this.element.scrollLeft !== field.scrollLeft) this.element.scrollLeft = field.scrollLeft\n }\n\n /** Forget what was painted, so the next render rebuilds. */\n invalidate(): void {\n this.paintedText = undefined\n this.paintedKey = ''\n }\n\n /** Take the layer out of the document. */\n destroy(): void {\n this.element.remove()\n this.paint.replaceChildren()\n }\n}\n","// ─── popup: the completion list ─────────────────────────────────────────────\n//\n// Three parts, and the split between them is the whole design:\n//\n// div.litearea-popup the positioned container; scrolls NOTHING\n// div.litearea-list the scroller, and the listbox role; holds rows only\n// div.litearea-docs the documentation, pinned below the list\n//\n// The documentation used to be appended INSIDE the scrolling element, after the rows, and\n// that made it unreachable in the one case it matters most: with a long list and a long\n// explanation, the explanation sat at the end of the scroll range, so a keyboard user could\n// never see it at all — the arrows move the active row, not the scrollbar — and a mouse user\n// had to scroll down to read it and then back up to reach the next row. Pinning it outside the\n// scroller fixes both, because the panel never moves when the list scrolls and never has to be\n// scrolled to in the first place.\n//\n// Two interaction details are also deliberate. A pick must not blur the field: a click fires\n// `mousedown` before `blur`, so the row listens for `mousedown`, cancels the default to keep\n// the focus, and accepts — listening for `click` instead means the field is already blurred by\n// the time the handler runs. And the list scrolls only as far as the active row needs, because\n// a list that re-centres on every arrow press looks like it is jumping.\n\nimport type { CompletionRow, SuggestionItem } from '../core/types.js'\nimport { highlightSegments } from '../core/rank.js'\n\n/** Where a floating element is allowed to sit. */\nexport interface AnchorBox {\n /** Distance from the positioning container's left edge. */\n x: number\n /** Distance from the positioning container's top edge. */\n y: number\n /** The height of the line the anchor sits on. */\n height: number\n}\n\n/** What the list tells its owner. */\nexport interface PopupHandlers {\n /** A row was chosen with the mouse. */\n accept(index: number): void\n /** The pointer moved over a row, which makes it active. */\n hover(index: number): void\n}\n\n/** The completion list, with its documentation panel. */\nexport class Popup {\n /** The positioned container. */\n readonly element: HTMLDivElement\n /** The scrolling element, which holds the rows and nothing else. */\n readonly list: HTMLDivElement\n private readonly document: Document\n private readonly handlers: PopupHandlers\n private rows: readonly CompletionRow[] = []\n private active = -1\n private open = false\n private showDocs = true\n private readonly docs: HTMLDivElement\n private readonly prefix: string\n\n /**\n * @param ownerDocument - the document to build in.\n * @param handlers - how to report a pick and a hover.\n * @param idPrefix - a stable prefix for row ids, so two editors do not collide.\n */\n constructor(ownerDocument: Document, handlers: PopupHandlers, idPrefix: string) {\n this.document = ownerDocument\n this.handlers = handlers\n this.prefix = idPrefix\n\n this.element = ownerDocument.createElement('div')\n this.element.className = 'litearea-popup'\n this.element.dataset.liteareaPart = 'popup'\n this.element.dataset.open = 'false'\n\n this.list = ownerDocument.createElement('div')\n this.list.className = 'litearea-list'\n this.list.setAttribute('role', 'listbox')\n this.list.id = `${idPrefix}-listbox`\n this.element.appendChild(this.list)\n\n this.docs = ownerDocument.createElement('div')\n this.docs.className = 'litearea-docs'\n this.docs.hidden = true\n this.element.appendChild(this.docs)\n\n // Bound to the list rather than to each row, so replacing every row on each keystroke does\n // not mean attaching and detaching listeners on every keystroke.\n this.list.addEventListener('mousedown', this.onMouseDown)\n this.list.addEventListener('mousemove', this.onMouseMove)\n }\n\n /** Whether the list is showing. */\n get isOpen(): boolean {\n return this.open\n }\n\n /** The active row's index, or -1. */\n get activeIndex(): number {\n return this.active\n }\n\n /** The rows currently shown. */\n get items(): readonly CompletionRow[] {\n return this.rows\n }\n\n /** The active row, when there is one. */\n get activeRow(): CompletionRow | undefined {\n return this.rows[this.active]\n }\n\n /** The id the field's `aria-controls` should name. It is the list, not the container. */\n get listId(): string {\n return this.list.id\n }\n\n /**\n * The id of the active row, for the field's `aria-activedescendant`.\n *\n * The list does not write that attribute itself: the field belongs to the editor, and a\n * floating list reaching out of its own subtree to find it is the kind of coupling that\n * breaks the moment the two are mounted somewhere unexpected.\n * @returns the row id, or undefined when no row is active.\n */\n get activeRowId(): string | undefined {\n return this.active >= 0 ? this.rowId(this.active) : undefined\n }\n\n /**\n * Show a list.\n * @param rows - the rows, already ranked.\n * @param active - the row to make active.\n * @param showDocs - whether to render the documentation panel.\n */\n show(rows: readonly CompletionRow[], active: number, showDocs: boolean): void {\n this.rows = rows\n this.active = active\n this.showDocs = showDocs\n this.open = true\n this.element.dataset.open = 'true'\n this.element.dataset.docs = showDocs ? 'true' : 'false'\n this.list.scrollTop = 0\n this.render()\n }\n\n /** Hide the list and forget its rows. */\n close(): void {\n if (!this.open) return\n this.open = false\n this.active = -1\n this.rows = []\n this.element.dataset.open = 'false'\n this.list.replaceChildren()\n this.docs.hidden = true\n this.docs.replaceChildren()\n }\n\n /**\n * Make a row active without rebuilding the list.\n * @param index - the row index.\n */\n setActive(index: number): void {\n if (index === this.active) return\n const previous = this.list.querySelector<HTMLElement>(`#${this.rowId(this.active)}`)\n if (previous !== null) previous.setAttribute('aria-selected', 'false')\n this.active = index\n const next = this.list.querySelector<HTMLElement>(`#${this.rowId(index)}`)\n if (next !== null) {\n next.setAttribute('aria-selected', 'true')\n // Only as far as needed, and only the LIST scrolls: the documentation panel is outside\n // this element, so moving the active row can never push the explanation out of sight.\n const top = next.offsetTop\n const bottom = top + next.offsetHeight\n if (top < this.list.scrollTop) this.list.scrollTop = top\n else if (bottom > this.list.scrollTop + this.list.clientHeight) {\n this.list.scrollTop = bottom - this.list.clientHeight\n }\n }\n this.renderDocs()\n }\n\n /**\n * Place the list under an anchor, flipping above it when there is no room below.\n *\n * The container's own box is what is measured, so the documentation panel counts towards the\n * height and a popup whose rows and explanation together would run off the bottom flips as a\n * whole rather than being cut in half.\n * @param anchor - the caret's box, in the container's coordinates.\n * @param container - the element the list is positioned against.\n * @param viewport - the visible area to stay inside.\n */\n place(anchor: AnchorBox, container: HTMLElement, viewport: { width: number; height: number }): void {\n const box = this.element.getBoundingClientRect()\n const containerBox = container.getBoundingClientRect()\n const gap = 4\n let top = anchor.y + anchor.height + gap\n if (containerBox.top + top + box.height > viewport.height - gap) {\n const above = anchor.y - box.height - gap\n // Flipping only helps if there is somewhere to flip TO; otherwise the list stays below\n // and is clamped by the max-heights in the stylesheet.\n if (containerBox.top + above >= gap) top = above\n }\n let left = anchor.x\n const maxLeft = containerBox.width - box.width\n if (left > maxLeft) left = Math.max(0, maxLeft)\n this.element.style.top = `${String(Math.round(top))}px`\n this.element.style.left = `${String(Math.round(left))}px`\n }\n\n /** Take the list out of the document. */\n destroy(): void {\n this.list.removeEventListener('mousedown', this.onMouseDown)\n this.list.removeEventListener('mousemove', this.onMouseMove)\n this.element.remove()\n this.list.replaceChildren()\n this.docs.replaceChildren()\n }\n\n /** The DOM id of a row, which `aria-activedescendant` points at. */\n rowId(index: number): string {\n return `${this.prefix}-row-${String(index)}`\n }\n\n // ── internals ────────────────────────────────────────────────────────────\n\n private render(): void {\n const fragment = this.document.createDocumentFragment()\n this.rows.forEach((row, index) => {\n const element = this.document.createElement('div')\n element.className = 'litearea-row'\n element.id = this.rowId(index)\n element.setAttribute('role', 'option')\n element.setAttribute('aria-selected', index === this.active ? 'true' : 'false')\n element.dataset.index = String(index)\n\n const kind = this.document.createElement('span')\n kind.className = `litearea-rowKind litearea-kind-${row.item.kind ?? 'value'}`\n element.appendChild(kind)\n\n const label = this.document.createElement('span')\n label.className = 'litearea-rowLabel'\n // Emphasised as segments rather than as markup: a font family may legitimately be called\n // `<b>`, and a list that built HTML from a label would either render it or have to escape\n // it, and both are wrong for text that came from the user's machine.\n for (const piece of highlightSegments(row.item.label, row.indices)) {\n if (piece.matched) {\n const mark = this.document.createElement('span')\n mark.className = 'litearea-rowMatch'\n mark.textContent = piece.text\n label.appendChild(mark)\n } else {\n label.appendChild(this.document.createTextNode(piece.text))\n }\n }\n element.appendChild(label)\n\n if (row.item.detail !== undefined) {\n const detail = this.document.createElement('span')\n detail.className = 'litearea-rowDetail'\n detail.textContent = row.item.detail\n element.appendChild(detail)\n }\n fragment.appendChild(element)\n })\n\n // Rows go in the list and nowhere else. The documentation is a sibling that is never\n // rebuilt here, so converting a long explanation cannot disturb the scroll position.\n this.list.replaceChildren(fragment)\n this.renderDocs()\n }\n\n /** Refresh the documentation panel from the active row. */\n private renderDocs(): void {\n const item: SuggestionItem | undefined = this.rows[this.active]?.item\n const hasDocs =\n this.showDocs &&\n this.open &&\n item !== undefined &&\n (item.documentation !== undefined || item.detail !== undefined)\n this.docs.hidden = !hasDocs\n if (!hasDocs || item === undefined) {\n this.docs.replaceChildren()\n return\n }\n const fragment = this.document.createDocumentFragment()\n const title = this.document.createElement('div')\n title.className = 'litearea-docsTitle'\n title.textContent = item.label\n fragment.appendChild(title)\n if (item.detail !== undefined) {\n const detail = this.document.createElement('div')\n detail.className = 'litearea-docsDetail'\n detail.textContent = item.detail\n fragment.appendChild(detail)\n }\n if (item.documentation !== undefined) {\n const body = this.document.createElement('div')\n body.className = 'litearea-docsBody'\n body.textContent = item.documentation\n fragment.appendChild(body)\n }\n this.docs.replaceChildren(fragment)\n // A new explanation is read from its beginning, which matters when the previous one was\n // long enough to have been scrolled.\n this.docs.scrollTop = 0\n }\n\n private readonly onMouseDown = (event: MouseEvent): void => {\n const row = (event.target as HTMLElement | null)?.closest<HTMLElement>('.litearea-row')\n if (row === null || row === undefined) return\n // Before blur, and cancelling the default is what keeps the field focused.\n event.preventDefault()\n const index = Number.parseInt(row.dataset.index ?? '-1', 10)\n if (Number.isInteger(index) && index >= 0) this.handlers.accept(index)\n }\n\n private readonly onMouseMove = (event: MouseEvent): void => {\n const row = (event.target as HTMLElement | null)?.closest<HTMLElement>('.litearea-row')\n if (row === null || row === undefined) return\n const index = Number.parseInt(row.dataset.index ?? '-1', 10)\n if (!Number.isInteger(index) || index < 0 || index === this.active) return\n this.handlers.hover(index)\n }\n}\n","// ─── tooltip: what the pointer is resting on ────────────────────────────────\n//\n// One floating element, positioned near the thing it describes and kept inside the\n// viewport. It never takes the pointer: a tooltip that can be hovered is a tooltip\n// that flickers, because moving the mouse onto it leaves the thing that opened it.\n//\n// The content is deliberately plain text, not markup. A grammar supplies strings,\n// those strings may be a font family called `<b>` or a value containing `#`, and a\n// tooltip that rendered them as HTML would either mis-render the text or have to\n// escape it — both wrong for text the user typed.\n\nimport type { HoverInfo } from '../core/types.js'\n\n/** Where a floating element is allowed to sit. */\nexport interface TooltipAnchor {\n /** Distance from the positioning container's left edge. */\n x: number\n /** Distance from the positioning container's top edge. */\n y: number\n /** The height of the anchored line or range. */\n height: number\n}\n\n/** The hover tooltip. */\nexport class Tooltip {\n /** The tooltip element. */\n readonly element: HTMLDivElement\n private readonly document: Document\n private open = false\n\n /**\n * @param ownerDocument - the document to build in.\n */\n constructor(ownerDocument: Document) {\n this.document = ownerDocument\n this.element = ownerDocument.createElement('div')\n this.element.className = 'litearea-tooltip'\n this.element.setAttribute('role', 'tooltip')\n this.element.dataset.liteareaPart = 'tooltip'\n this.element.dataset.open = 'false'\n }\n\n /** Whether the tooltip is showing. */\n get isOpen(): boolean {\n return this.open\n }\n\n /**\n * Show a hover.\n * @param info - what to say.\n * @param anchor - where the thing being described is.\n * @param container - the element the tooltip is positioned against.\n * @param viewport - the visible area to stay inside.\n */\n show(\n info: HoverInfo,\n anchor: TooltipAnchor,\n container: HTMLElement,\n viewport: { width: number; height: number },\n ): void {\n const fragment = this.document.createDocumentFragment()\n if (info.title !== undefined) {\n const title = this.document.createElement('div')\n title.className = 'litearea-tooltipTitle'\n title.textContent = info.title\n fragment.appendChild(title)\n }\n if (info.detail !== undefined && info.detail !== '') {\n const detail = this.document.createElement('div')\n detail.className = 'litearea-tooltipDetail'\n detail.textContent = info.detail\n fragment.appendChild(detail)\n }\n if (info.body !== undefined && info.body !== '') {\n const body = this.document.createElement('div')\n body.className = 'litearea-tooltipBody'\n body.textContent = info.body\n fragment.appendChild(body)\n }\n this.element.replaceChildren(fragment)\n this.open = true\n this.element.dataset.open = 'true'\n\n const box = this.element.getBoundingClientRect()\n const containerBox = container.getBoundingClientRect()\n const gap = 6\n let top = anchor.y + anchor.height + gap\n if (containerBox.top + top + box.height > viewport.height - gap) {\n const above = anchor.y - box.height - gap\n top = containerBox.top + above >= gap ? above : Math.max(0, viewport.height - gap - box.height - containerBox.top)\n }\n let left = anchor.x\n const overflowRight = containerBox.left + left + box.width - (viewport.width - gap)\n if (overflowRight > 0) left = Math.max(0, left - overflowRight)\n this.element.style.top = `${String(Math.round(top))}px`\n this.element.style.left = `${String(Math.round(left))}px`\n }\n\n /** Hide the tooltip. */\n hide(): void {\n if (!this.open) return\n this.open = false\n this.element.dataset.open = 'false'\n this.element.replaceChildren()\n }\n\n /** Take the tooltip out of the document. */\n destroy(): void {\n this.element.remove()\n this.element.replaceChildren()\n }\n}\n","// ─── editor: the element, and the interaction ───────────────────────────────\n//\n// This is where the four things the library promises are actually kept, and each\n// is a decision made here rather than a behaviour that emerged.\n//\n// **Undo survives, because the DOM owns the text.** The textarea is never given a\n// `value` after it is created. Every edit the user makes is the browser's own, and\n// every edit the editor makes on the user's behalf goes through the browser's\n// editing pipeline (`src/dom/editing.ts`). The highlight layer reads the text; it\n// never writes it. A framework binding on top must leave the element alone for the\n// same reason, which is why the React wrapper renders a bare div and hands the\n// element to this class.\n//\n// **The caret does not move, because nothing rewrites the text under it.** The\n// editors this replaces re-rendered the value on every keystroke and then tried to\n// put the caret back — a race the browser wins eventually, and the same mistake\n// that destroyed the undo stack. Here there is no re-render to lose a race with,\n// and the only caret writes are the ones a completion asked for.\n//\n// **The list behaves, because its range is frozen when it opens.** Filtering runs\n// against the recorded range instead of re-deriving one from a document that has\n// changed since, so the target cannot slide out from under the list while the user\n// types. Enter and Tab accept, Escape dismisses, Ctrl+Space opens on demand, and\n// the arrows move the selection without wrapping — the behaviour every editor has,\n// which is the whole point.\n//\n// **The box fits, because an offscreen mirror is measured instead of the field.**\n// Asking a textarea for its `scrollHeight` means collapsing it first, which\n// reflows the page and flickers on every keystroke. `src/dom/mirror.ts` keeps a\n// second element with the same typography and asks that instead.\n\nimport type {\n Completion,\n Decoration,\n Diagnostic,\n Grammar,\n HoverInfo,\n Range,\n Severity,\n SuggestionItem,\n} from '../core/types.js'\nimport type { Inspection } from '../core/inspect.js'\nimport type { SegmentInput } from '../core/segments.js'\nimport type { CompletionTrigger } from '../core/types.js'\nimport { applyCompletion, complete } from '../core/complete.js'\nimport { resolveHover } from '../core/hover.js'\nimport { inspect } from '../core/inspect.js'\nimport { resolveGrammar, isResolvedGrammar, type ResolvedGrammar } from '../core/scan.js'\nimport { clamp } from '../core/text.js'\nimport { decorationClass, injectStyles, scopeClass, severityClass } from '../styles.js'\nimport {\n readSelection,\n redoField,\n replaceThroughPipeline,\n undoField,\n writeDocument,\n writeSelection,\n type EditOutcome,\n type TextSelection,\n} from './editing.js'\nimport { TextMirror } from './mirror.js'\nimport { Overlay } from './overlay.js'\nimport { Popup } from './popup.js'\nimport { Tooltip } from './tooltip.js'\nimport { withDefaults } from './support.js'\n\n/** How the box follows its content. */\nexport interface LiteAreaSizing {\n /**\n * Whether the height follows the content, so that no scrollbar is shown while\n * the content fits. Default `true`.\n */\n autoGrow?: boolean\n /**\n * The fewest lines to show, written to the textarea's own `rows` attribute.\n *\n * The native attribute is set rather than only a pixel minimum, so the box has\n * the right height on the very first frame — before any measurement, and in a\n * document where the script never runs at all. Default 1.\n */\n minRows?: number\n /** The most lines to show before a scrollbar appears. */\n maxRows?: number\n /** A minimum height in pixels, in addition to `minRows`. */\n minHeight?: number\n /** A maximum height in pixels, in addition to `maxRows`. */\n maxHeight?: number\n}\n\n/** How the completion list behaves. */\nexport interface LiteAreaCompletion {\n /** Whether suggestions appear while typing. Default `true`. */\n auto?: boolean\n /**\n * Characters that open the list in addition to word characters.\n *\n * Default `' '`, and that default is doing real work: both reference languages\n * put a value after a name, so a space is exactly where the next word becomes\n * guessable.\n */\n triggerCharacters?: string\n /** The most rows to offer. Default 100. */\n limit?: number\n /** Whether the documentation panel is shown. Default `true`. */\n showDocumentation?: boolean\n}\n\n/** How the hover tooltip behaves. */\nexport interface LiteAreaHover {\n /** Whether tooltips appear at all. Default `true`. */\n enabled?: boolean\n /** How long the pointer must rest, in milliseconds. Default 140. */\n delay?: number\n}\n\n/** Everything a host may configure. */\nexport interface LiteAreaOptions<State = unknown> {\n /** The language. Nothing else in this library knows anything about syntax. */\n grammar: Grammar<State> | ResolvedGrammar<State>\n /** The initial text. */\n value?: string\n /** Shown while the box is empty. */\n placeholder?: string\n /** Whether the user may edit. */\n readOnly?: boolean\n /** Whether the browser may spell-check. Default `false`, because a DSL is not prose. */\n spellCheck?: boolean\n /** The accessible name. */\n ariaLabel?: string\n /** An extra class on the wrapper. */\n className?: string\n /**\n * CSS custom properties for THIS instance, for per-instance theming.\n *\n * A key may be written `font`, `--litearea-font`, or any other `--…` name; the first two\n * forms mean the same thing, and a key that already starts with `--` is used verbatim so a\n * host's own properties work too. The value is used as written, so `'13px'`,\n * `'var(--my-ui-font)'`, and `'1.6'` are all fine.\n *\n * createEditor(target, {\n * grammar,\n * variables: { font: '\"Fira Code\", monospace', 'font-size': '14px', accent: '#c2410c' },\n * })\n *\n * CSS stays the theme language on purpose — the editor's whole appearance is already\n * described by custom properties, and a second vocabulary for the same facts would mean two\n * places to keep in step. This exists only so that ONE instance can be themed without a host\n * writing a stylesheet rule for it, and so that two editors on a page can differ.\n */\n variables?: Record<string, string>\n /** How the box follows its content. */\n sizing?: LiteAreaSizing\n /** How the list behaves, or `false` to switch completions off entirely. */\n completion?: LiteAreaCompletion | false\n /** How tooltips behave, or `false` to switch them off entirely. */\n hover?: LiteAreaHover | false\n /** Whether semantic decorations are painted. Default `true`. */\n decorations?: boolean\n /** Whether to inject the stylesheet. Default `true`. */\n injectStyles?: boolean\n /** A CSP nonce for the injected stylesheet. */\n styleNonce?: string\n /** Called after a user edit, with the new text. Not called for programmatic writes. */\n onChange?: (value: string) => void\n /** Called when the caret or selection moves. */\n onSelectionChange?: (selection: TextSelection) => void\n /** Called when the problem list changes. */\n onDiagnostics?: (diagnostics: readonly Diagnostic[]) => void\n /** Called when the list opens, filters, or closes. */\n onCompletion?: (completion: Completion | undefined) => void\n /** Called when a tooltip appears or goes away. */\n onHover?: (info: HoverInfo | undefined) => void\n}\n\n/** The sizing with its defaults filled in. */\ntype ResolvedSizing = Required<Pick<LiteAreaSizing, 'autoGrow' | 'minRows'>> &\n Pick<LiteAreaSizing, 'maxRows' | 'minHeight' | 'maxHeight'>\n\n/** The completion settings with their defaults filled in. */\ntype ResolvedCompletion = Required<LiteAreaCompletion>\n\n/** The hover settings with their defaults filled in. */\ntype ResolvedHover = Required<LiteAreaHover>\n\n/** How many rows a Page key moves through. */\nconst PAGE_STEP = 8\n\n/**\n * A code editor over a textarea.\n *\n * The tree it builds:\n *\n * div.litearea ← the positioning container, and this.element\n * div.litearea-box ← the border, the radius, and the focus ring\n * div.litearea-layer ← the painted text, behind and inert\n * textarea ← the real field: transparent text, visible caret\n * div.litearea-popup ← the completion list\n * div.litearea-tooltip ← the hover tooltip\n *\n * The layer is inside the box while the floating elements are outside it, because\n * the box clips nothing and a list that had to fit inside a rounded border would be\n * cut off at the bottom.\n */\nexport class LiteArea<State = unknown> {\n /** The positioning container. Put this in the page. */\n readonly element: HTMLDivElement\n /** The real field. Exposed for a host that needs the element itself. */\n readonly input: HTMLTextAreaElement\n\n private readonly document: Document\n private readonly view: Window | undefined\n /**\n * The grammar as the host declared it, kept so {@link refresh} can re-resolve it.\n *\n * Mutable on purpose, and it is what lets a host pass a live object — a proxy\n * reading the newest props, say — without the editor having to be rebuilt when the\n * language changes. A rebuild would throw away the undo history, which is the one\n * thing this library must not do, so re-resolving is the only acceptable answer.\n */\n private declaredGrammar: Grammar<State>\n /** The grammar the engine is currently running, with its defaults filled in. */\n private grammar: ResolvedGrammar<State>\n private readonly box: HTMLDivElement\n private readonly overlay: Overlay\n private readonly popup: Popup\n private readonly tooltip: Tooltip\n private readonly mirror: TextMirror\n private readonly sizing: ResolvedSizing\n private readonly completion: ResolvedCompletion | undefined\n private readonly hover: ResolvedHover | undefined\n private readonly paintDecorations: boolean\n private readonly handlers: LiteAreaOptions<State>\n private readonly injectedStyle: HTMLStyleElement | undefined\n private readonly instanceId: string\n private readonly fontsReady: Promise<unknown> | undefined\n\n /** The current inspection, and the text it was computed from. */\n private current: Inspection<State> | undefined\n private currentText: string | undefined\n /** Bumped whenever the inspection changes, so the painter can skip work. */\n private revision = 0\n /** The list on screen, with the range frozen when it opened. */\n private completionState: Completion | undefined\n /** True during an IME composition, when no completion may run. */\n private composing = false\n /** True while the editor itself is writing, so its own edit does not re-open the list. */\n private applying = false\n /** The height and overflow last written, so unchanged values are not rewritten. */\n private appliedHeight = -1\n private appliedOverflow = ''\n private appliedScrollbar = -1\n /** The offset the tooltip last described, so a resting pointer does not re-query. */\n private hoverOffset: number | undefined\n /** The custom properties this instance set, so one that disappears can be removed. */\n private appliedVariables = new Set<string>()\n private hoverTimer: number | undefined\n /** Watches for a width change, which invalidates wrapping and the box height. */\n private resizeObserver: ResizeObserver | undefined\n private observedWidth = -1\n /**\n * A signature of the last announced problem list, so the host is told once.\n *\n * Starts as `undefined` rather than as the empty string, because \"no problems\" is a\n * real signature and a host waiting to be told that the list is clear would otherwise\n * never hear it — it would keep whatever it was showing before the editor existed.\n */\n private announced: string | undefined\n private destroyed = false\n\n /**\n * @param options - the grammar, the initial text, and the behaviour to use.\n */\n constructor(options: LiteAreaOptions<State>) {\n const probe = typeof document === 'undefined' ? undefined : document\n if (probe === undefined) {\n throw new Error('litearea: an editor needs a document, and there is none in this environment')\n }\n this.document = probe\n this.view = probe.defaultView ?? undefined\n this.handlers = options\n // A caller may hand over either the grammar as written or one already resolved;\n // both are accepted so a hot path can skip the work.\n const declared = options.grammar\n this.declaredGrammar = isResolvedGrammar(declared) ? declared.grammar : declared\n this.grammar = resolveGrammar(this.declaredGrammar)\n this.instanceId = `litearea-${Math.random().toString(36).slice(2, 9)}`\n\n this.sizing = withDefaults<ResolvedSizing>(\n { autoGrow: true, minRows: 1 },\n options.sizing as Partial<ResolvedSizing> | undefined,\n )\n this.completion =\n options.completion === false\n ? undefined\n : withDefaults<ResolvedCompletion>(\n { auto: true, triggerCharacters: ' ', limit: 100, showDocumentation: true },\n options.completion,\n )\n this.hover =\n options.hover === false\n ? undefined\n : withDefaults<ResolvedHover>({ enabled: true, delay: 140 }, options.hover)\n this.paintDecorations = options.decorations !== false\n\n if (options.injectStyles !== false) {\n this.injectedStyle = injectStyles(this.document, options.styleNonce)\n }\n\n // ── the element tree ───────────────────────────────────────────────────\n this.element = this.document.createElement('div')\n this.element.className =\n options.className === undefined ? 'litearea' : `litearea ${options.className}`\n this.element.classList.add(this.sizing.autoGrow ? 'litearea-growable' : 'litearea-resizable')\n if (options.readOnly === true) this.element.classList.add('litearea-readonly')\n if (options.variables !== undefined) this.applyVariables(options.variables)\n\n this.box = this.document.createElement('div')\n this.box.className = 'litearea-box'\n this.element.appendChild(this.box)\n\n this.overlay = new Overlay(this.document, {\n scope: scopeClass,\n decoration: decorationClass,\n severity: severityClass,\n })\n this.box.appendChild(this.overlay.element)\n\n this.input = this.document.createElement('textarea')\n this.input.className = 'litearea-input'\n this.input.dataset.liteareaPart = 'input'\n this.input.spellcheck = options.spellCheck === true\n this.input.autocomplete = 'off'\n this.input.setAttribute('autocorrect', 'off')\n this.input.setAttribute('autocapitalize', 'off')\n this.input.setAttribute('wrap', 'soft')\n this.input.readOnly = options.readOnly === true\n // The native attribute, so the first frame is already the right height.\n this.input.rows = this.sizing.minRows\n if (options.placeholder !== undefined) this.input.placeholder = options.placeholder\n if (options.ariaLabel !== undefined) this.input.setAttribute('aria-label', options.ariaLabel)\n this.input.setAttribute('aria-autocomplete', this.completion === undefined ? 'none' : 'list')\n this.input.setAttribute('aria-expanded', 'false')\n this.input.setAttribute('role', 'combobox')\n // Written exactly once, before any listener exists, so it is the element's own\n // initial content rather than a programmatic overwrite of it.\n this.input.value = options.value ?? ''\n this.box.appendChild(this.input)\n\n this.popup = new Popup(\n this.document,\n {\n accept: (index) => {\n this.acceptCompletion(index)\n },\n hover: (index) => {\n this.setActive(index)\n },\n },\n this.instanceId,\n )\n this.element.appendChild(this.popup.element)\n this.input.setAttribute('aria-controls', this.popup.listId)\n\n this.tooltip = new Tooltip(this.document)\n this.element.appendChild(this.tooltip.element)\n\n this.mirror = new TextMirror(this.document)\n this.mirror.mount(this.document.body ?? this.document.documentElement)\n\n // A width change invalidates both measurements: text wraps differently, and so\n // does the paint. This is also what performs the FIRST useful measurement, since\n // the constructor runs before the caller has mounted anything and an unmounted\n // field has no width to measure against.\n const Observer = (this.view as (Window & { ResizeObserver?: typeof ResizeObserver }) | undefined)\n ?.ResizeObserver\n if (typeof Observer === 'function') {\n this.resizeObserver = new Observer(() => {\n const width = this.element.clientWidth\n if (width === this.observedWidth) return\n this.observedWidth = width\n this.mirror.adopt(this.input)\n this.resize(this.input.value)\n this.placePopup()\n })\n this.resizeObserver.observe(this.element)\n }\n\n const fonts = (this.document as Document & { fonts?: { ready?: Promise<unknown> } }).fonts\n this.fontsReady = fonts?.ready\n\n this.bind()\n this.sync()\n // A web font arriving after the first paint changes every metric the mirror\n // copied, so the box is re-measured once it lands. Without this the editor is a\n // few pixels off until something else makes it re-layout, which is the classic\n // \"it looks wrong until you click it\" bug.\n if (this.fontsReady !== undefined) {\n void this.fontsReady.then(() => {\n if (!this.destroyed) this.refresh()\n })\n }\n }\n\n // ── what a host reads ──────────────────────────────────────────────────────\n\n /** The current text. */\n get value(): string {\n return this.input.value\n }\n\n /** The caret or selection. */\n get selection(): TextSelection {\n return readSelection(this.input)\n }\n\n /** The last inspection, or undefined before the first one. */\n get inspection(): Inspection<State> | undefined {\n return this.current\n }\n\n /** The problems the grammar found. */\n get diagnostics(): readonly Diagnostic[] {\n return this.current?.diagnostics ?? []\n }\n\n /** The list on screen, when one is. */\n get currentCompletion(): Completion | undefined {\n return this.completionState\n }\n\n /** Whether the editor has focus. */\n get focused(): boolean {\n return this.document.activeElement === this.input\n }\n\n // ── what a host calls ─────────────────────────────────────────────────────\n\n /**\n * Replace the text.\n *\n * `preserveHistory` writes through the editing pipeline, so the replacement is\n * one undoable edit and Ctrl+Z brings the old text back — what a Reset button\n * wants. Without it the value property is assigned, which is faster and clears\n * the history, which is what loading a different document wants.\n *\n * This is the only path that writes the text, and it is never used for an edit\n * the user could have made.\n * @param next - the new text.\n * @param preserveHistory - whether Ctrl+Z should be able to undo it.\n * @returns how the write landed.\n */\n setValue(next: string, preserveHistory = false): EditOutcome {\n if (this.input.value === next) return 'unchanged'\n // Marked as the editor's own write, because a history-preserving write fires an\n // `input` event and everything downstream listens for one. Without this the caller is\n // handed its own change back through `onChange`, and a host that stores what it is\n // told would write its own value twice.\n this.applying = true\n let outcome: EditOutcome\n try {\n outcome = writeDocument(this.input, next, preserveHistory)\n } finally {\n this.applying = false\n }\n this.sync()\n return outcome\n }\n\n /**\n * Put the caret somewhere.\n * @param start - the anchor offset.\n * @param end - the moving offset; defaults to `start`.\n */\n setSelection(start: number, end: number = start): void {\n writeSelection(this.input, start, end)\n this.updateCompletionForCaret()\n }\n\n /** Move the caret into the field. */\n focus(): void {\n this.input.focus()\n }\n\n /** Undo, through the browser's history. */\n undo(): boolean {\n const done = undoField(this.input)\n if (done) this.sync()\n return done\n }\n\n /** Redo, through the browser's history. */\n redo(): boolean {\n const done = redoField(this.input)\n if (done) this.sync()\n return done\n }\n\n /**\n * Set CSS custom properties on the wrapper, replacing whatever this method set last time.\n *\n * A property that has disappeared from the record is removed rather than left behind, so a\n * host can un-theme by passing a smaller object. Properties set by other means — a stylesheet,\n * or the wrapper's inline style directly — are not touched, and a removed one falls back to\n * whatever CSS says.\n *\n * Safe to call at any time after construction. The constructor uses the private write-only\n * half, because re-measuring needs the field, the mirror, and the overlay, none of which exist\n * until it has finished.\n * @param next - the properties, keyed as {@link LiteAreaOptions.variables} describes.\n */\n setVariables(next: Readonly<Record<string, string>>): void {\n this.applyVariables(next)\n // A font or a line height changes every measurement, so the box is re-measured rather than\n // waiting for the next keystroke to notice.\n this.mirror.adopt(this.input)\n this.appliedHeight = -1\n this.sync()\n }\n\n /** Write the properties, and forget the ones that are gone. No re-measure. */\n private applyVariables(next: Readonly<Record<string, string>>): void {\n const keep = new Set<string>()\n for (const [key, value] of Object.entries(next)) {\n const name = variableName(key)\n keep.add(name)\n this.element.style.setProperty(name, value)\n }\n for (const name of this.appliedVariables) {\n if (!keep.has(name)) this.element.style.removeProperty(name)\n }\n this.appliedVariables = keep\n }\n\n /**\n * Re-read the document with the same text.\n *\n * For a host whose grammar depends on something outside it — an installed font\n * list that has just been re-read, a palette that changed — and for the moment a\n * web font finishes loading.\n *\n * The grammar is re-resolved here, which is what makes a live grammar object\n * work: a host that rebuilds its rules on every render can call `refresh()` and\n * the editor picks the new ones up without being rebuilt, so the undo history\n * survives a language change.\n */\n refresh(): void {\n this.grammar = resolveGrammar(this.declaredGrammar)\n this.current = undefined\n this.currentText = undefined\n this.mirror.adopt(this.input)\n this.overlay.invalidate()\n this.appliedHeight = -1\n this.appliedOverflow = ''\n this.appliedScrollbar = -1\n this.sync()\n }\n\n /** Open the completion list on demand, as Ctrl+Space does. */\n showCompletions(): void {\n if (this.completion === undefined) return\n this.openCompletion('explicit')\n }\n\n /** Close the completion list. */\n hideCompletions(): void {\n this.closeCompletion()\n }\n\n /** Remove the editor and every listener it owns. */\n destroy(): void {\n if (this.destroyed) return\n this.destroyed = true\n this.unbind()\n this.resizeObserver?.disconnect()\n this.resizeObserver = undefined\n if (this.hoverTimer !== undefined) this.view?.clearTimeout(this.hoverTimer)\n this.popup.destroy()\n this.tooltip.destroy()\n this.overlay.destroy()\n this.mirror.destroy()\n // The injected sheet is shared by every editor on the page, so it stays:\n // removing it would unstyle the others.\n void this.injectedStyle\n this.element.remove()\n }\n\n // ── the pipeline ──────────────────────────────────────────────────────────\n\n /**\n * Bring everything up to date with the field.\n *\n * The inspection is cached on the text, so moving the caret or scrolling costs\n * nothing beyond the paint — and the paint itself is skipped when neither the\n * text nor the analysis changed.\n */\n private sync(): void {\n const text = this.input.value\n if (this.current === undefined || this.currentText !== text) {\n this.current = inspect(text, this.grammar)\n this.currentText = text\n this.revision += 1\n }\n const inspection = this.current\n this.paint(inspection)\n this.resize(text)\n this.overlay.syncScroll(this.input)\n this.announceDiagnostics(inspection)\n }\n\n /** Paint the layer, and mark the box when a problem is an error. */\n private paint(inspection: Inspection<State>): void {\n const painting: SegmentInput = {\n tokens: inspection.tokens,\n decorations: this.paintDecorations ? inspection.decorations : [],\n diagnostics: inspection.diagnostics,\n }\n const key = [\n String(this.revision),\n this.paintDecorations ? 'd' : '-',\n String(painting.decorations.length),\n String(painting.diagnostics.length),\n ].join(':')\n this.overlay.render(inspection.text, painting, key, this.grammar.fallbackScope)\n const hasError = inspection.diagnostics.some((diagnostic) => diagnostic.severity === 'error')\n this.element.classList.toggle('litearea-invalid', hasError)\n this.input.setAttribute('aria-invalid', hasError ? 'true' : 'false')\n }\n\n /** Tell the host, once, when the problem list actually changed. */\n private announceDiagnostics(inspection: Inspection<State>): void {\n if (this.handlers.onDiagnostics === undefined) return\n const key = inspection.diagnostics\n .map(\n (diagnostic) =>\n `${String(diagnostic.from)}:${diagnostic.code ?? ''}:${diagnostic.message}`,\n )\n .join('|')\n if (key === this.announced) return\n this.announced = key\n this.handlers.onDiagnostics(inspection.diagnostics)\n }\n\n /**\n * Size the box to its content.\n *\n * The mirror has no scrollbar, so its measurement is the height the content wants\n * with the full width available — which is exactly the number that decides whether\n * a scrollbar is needed at all. If it fits under the maximum, the height becomes\n * the content height and the overflow stays hidden, which is the promise of \"grow\n * and shrink so no scrollbar is ever shown\". If it does not fit, the height is\n * clamped and the overflow becomes `auto`.\n *\n * Clamping introduces a second problem that is easy to miss: a scrollbar narrows\n * the text, so the field rewraps, so the PAINT no longer wraps the same way and\n * every coloured span slides off its character. The measured scrollbar width is\n * therefore published as a custom property, and the stylesheet adds it to the\n * layer's own right padding so the two keep wrapping identically.\n *\n * An UNMOUNTED field is skipped rather than measured. Before the element is in the\n * document it has no layout, so its `clientWidth` is zero, the mirror wraps at every\n * character, and the measurement comes back several times too tall — a wrong height\n * that then has to be corrected on the next keystroke, which is what a box that\n * jumps on first focus actually is. The `ResizeObserver` installed at construction\n * does the first real measurement as soon as there is a width to measure against.\n * @param text - the current text.\n */\n private resize(text: string): void {\n if (!this.sizing.autoGrow) {\n // Still adopted, because caret geometry depends on the mirror being shaped like\n // the field even when the field's height is the host's business.\n this.mirror.adopt(this.input)\n return\n }\n if (!this.input.isConnected || this.input.clientWidth === 0) return\n const chrome = this.mirror.verticalPadding()\n const lineHeight = this.mirror.lineHeight(this.input)\n const minPx = Math.max(\n this.sizing.minHeight ?? 0,\n lineHeight * (this.sizing.minRows ?? 1) + chrome,\n )\n const maxCandidate = Math.min(\n this.sizing.maxHeight ?? Number.POSITIVE_INFINITY,\n this.sizing.maxRows === undefined\n ? Number.POSITIVE_INFINITY\n : lineHeight * this.sizing.maxRows + chrome,\n )\n // A maximum below the minimum is a host mistake, and honouring it would make\n // the box smaller than the host was told it could be.\n const maxPx = Math.max(maxCandidate, minPx)\n\n const content = this.mirror.contentHeight(this.input, text)\n const wanted = clamp(Math.max(content, minPx), minPx, maxPx)\n const overflow = content > wanted + 0.5 ? 'auto' : 'hidden'\n\n if (Math.abs(wanted - this.appliedHeight) > 0.5) {\n this.input.style.height = `${String(Math.round(wanted))}px`\n this.appliedHeight = wanted\n }\n if (overflow !== this.appliedOverflow) {\n this.input.style.overflowY = overflow\n this.appliedOverflow = overflow\n }\n // Read AFTER the overflow is applied, because that is when a scrollbar exists\n // and therefore when there is a width to report.\n const scrollbar = overflow === 'auto' ? this.input.offsetWidth - this.input.clientWidth : 0\n const width = Math.max(0, scrollbar)\n if (width !== this.appliedScrollbar) {\n this.element.style.setProperty('--litearea-scrollbar', `${String(width)}px`)\n this.appliedScrollbar = width\n }\n }\n\n // ── completion ────────────────────────────────────────────────────────────\n\n /** The caret's offset, clamped into the text. */\n private caret(): number {\n return clamp(readSelection(this.input).start, 0, this.input.value.length)\n }\n\n /** Resolve and show a list for the caret. */\n private openCompletion(trigger: CompletionTrigger): void {\n if (this.completion === undefined || this.current === undefined) return\n // The source that answered last time is passed back so the same one answers again\n // while it stays eligible. The RANGE is deliberately not held: it is recomputed from\n // the caret on every call, so it grows with the word being typed.\n const result = complete(this.current, this.grammar, {\n text: this.input.value,\n caret: this.caret(),\n trigger,\n previousSourceId: this.completionState?.sourceId,\n limit: this.completion.limit,\n })\n if (result === undefined || result.rows.length === 0) {\n this.closeCompletion()\n return\n }\n this.completionState = result\n this.popup.show(result.rows, 0, this.completion.showDocumentation)\n this.input.setAttribute('aria-expanded', 'true')\n this.syncActiveDescendant()\n this.placePopup()\n this.handlers.onCompletion?.(result)\n }\n\n /** Close the list and tell the host. */\n private closeCompletion(): void {\n if (this.completionState === undefined && !this.popup.isOpen) return\n this.completionState = undefined\n this.popup.close()\n this.input.setAttribute('aria-expanded', 'false')\n this.input.removeAttribute('aria-activedescendant')\n this.handlers.onCompletion?.(undefined)\n }\n\n /** Keep the field's `aria-activedescendant` pointing at the active row. */\n private syncActiveDescendant(): void {\n const id = this.popup.activeRowId\n if (id === undefined) this.input.removeAttribute('aria-activedescendant')\n else this.input.setAttribute('aria-activedescendant', id)\n }\n\n /** Put the list under the caret. */\n private placePopup(): void {\n if (this.completionState === undefined) return\n const box = this.mirror.caretBox(this.input, this.caret())\n if (box === undefined) return\n // The mirror reports relative to the field's border box; the list is positioned\n // against the wrapper. Measuring both rects is used rather than `offsetLeft`\n // arithmetic, because `offsetParent` changes as soon as a host wraps the editor\n // in something positioned, and the caret must not notice.\n const inputRect = this.input.getBoundingClientRect()\n const elementRect = this.element.getBoundingClientRect()\n this.popup.place(\n {\n x: inputRect.left - elementRect.left + box.x,\n y: inputRect.top - elementRect.top + box.y,\n height: box.height,\n },\n this.element,\n { width: this.view?.innerWidth ?? 0, height: this.view?.innerHeight ?? 0 },\n )\n }\n\n /**\n * Take the active row.\n * @param index - the row to take.\n * @param commitCharacter - a character typed to trigger the pick, written after\n * the completion so the keystroke is not swallowed.\n */\n private acceptCompletion(index: number, commitCharacter?: string): void {\n const state = this.completionState\n const row: SuggestionItem | undefined = this.popup.items[index]?.item\n if (state === undefined || row === undefined) return\n const applied = applyCompletion(this.input.value, state.range, row)\n this.applying = true\n try {\n // Only the range that changed is written, and it goes through the editing\n // pipeline, so Ctrl+Z undoes the completion as one edit and the rest of the\n // document — and its history — is untouched.\n replaceThroughPipeline(this.input, applied.from, applied.to, applied.insert)\n writeSelection(this.input, applied.caret)\n if (commitCharacter !== undefined) {\n replaceThroughPipeline(this.input, applied.caret, applied.caret, commitCharacter)\n writeSelection(this.input, applied.caret + commitCharacter.length)\n }\n } finally {\n this.applying = false\n }\n this.closeCompletion()\n this.sync()\n const inspection = this.current\n if (inspection !== undefined) {\n this.grammar.grammar.onAccept?.({\n text: this.input.value,\n caret: this.caret(),\n item: row,\n state: inspection.state,\n })\n }\n }\n\n /** Decide what an edit does to the list. */\n private updateCompletionAfterInput(data: string, deletion: boolean): void {\n if (this.completion === undefined || this.applying || this.composing) return\n if (this.input.readOnly) return\n if (deletion) {\n // Deleting inside an open list re-filters it; deleting with no list open opens\n // nothing, because a backspace is not a request for suggestions.\n if (this.completionState !== undefined) this.openCompletion('auto')\n return\n }\n if (this.completionState !== undefined) {\n this.openCompletion('auto')\n return\n }\n if (!this.completion.auto) return\n if (!this.shouldAutoOpen(data)) return\n this.openCompletion('auto')\n }\n\n /** Whether a keystroke is a reason to offer suggestions. */\n private shouldAutoOpen(data: string): boolean {\n if (data === '' || this.completion === undefined) return false\n const last = data.slice(-1)\n if (this.completion.triggerCharacters.includes(last)) return true\n return this.grammar.wordChars.test(last)\n }\n\n /** Close a list the caret has left. */\n private updateCompletionForCaret(): void {\n const state = this.completionState\n if (state === undefined) return\n const caret = this.caret()\n if (caret < state.range.from || caret > state.range.to) this.closeCompletion()\n else this.placePopup()\n }\n\n // ── hover ─────────────────────────────────────────────────────────────────\n\n /** Start, or restart, the timer that shows a tooltip. */\n private queueHover(offset: number, event: MouseEvent): void {\n if (this.hover === undefined || !this.hover.enabled || this.current === undefined) return\n if (offset === this.hoverOffset && this.tooltip.isOpen) return\n this.hoverOffset = offset\n this.hideTooltip()\n const clientX = event.clientX\n const clientY = event.clientY\n this.hoverTimer = this.view?.setTimeout(() => {\n this.hoverTimer = undefined\n this.showHover(offset, clientX, clientY)\n }, this.hover.delay)\n }\n\n /** Resolve and show a tooltip. */\n private showHover(offset: number, clientX: number, clientY: number): void {\n if (this.current === undefined || this.destroyed) return\n const info = resolveHover(this.current, this.grammar, offset)\n if (info === undefined) {\n this.hideTooltip()\n return\n }\n const rect = this.element.getBoundingClientRect()\n const lineHeight = this.mirror.lineHeight(this.input)\n this.tooltip.show(\n info,\n { x: clientX - rect.left, y: clientY - rect.top, height: lineHeight },\n this.element,\n { width: this.view?.innerWidth ?? 0, height: this.view?.innerHeight ?? 0 },\n )\n this.handlers.onHover?.(info)\n }\n\n /** Hide the tooltip and forget what it described. */\n private hideTooltip(): void {\n if (this.hoverTimer !== undefined) {\n this.view?.clearTimeout(this.hoverTimer)\n this.hoverTimer = undefined\n }\n if (!this.tooltip.isOpen) return\n this.tooltip.hide()\n this.handlers.onHover?.(undefined)\n }\n\n // ── events ────────────────────────────────────────────────────────────────\n\n /** Attach every listener. */\n private bind(): void {\n this.input.addEventListener('input', this.onInput)\n this.input.addEventListener('keydown', this.onKeyDown)\n this.input.addEventListener('scroll', this.onScroll)\n this.input.addEventListener('click', this.onCaretMoved)\n this.input.addEventListener('keyup', this.onKeyUp)\n this.input.addEventListener('select', this.onCaretMoved)\n this.input.addEventListener('blur', this.onBlur)\n this.input.addEventListener('mousemove', this.onMouseMove)\n this.input.addEventListener('mouseleave', this.onMouseLeave)\n this.input.addEventListener('compositionstart', this.onCompositionStart)\n this.input.addEventListener('compositionend', this.onCompositionEnd)\n this.document.addEventListener('selectionchange', this.onSelectionChange)\n }\n\n /** Detach every listener. */\n private unbind(): void {\n this.input.removeEventListener('input', this.onInput)\n this.input.removeEventListener('keydown', this.onKeyDown)\n this.input.removeEventListener('scroll', this.onScroll)\n this.input.removeEventListener('click', this.onCaretMoved)\n this.input.removeEventListener('keyup', this.onKeyUp)\n this.input.removeEventListener('select', this.onCaretMoved)\n this.input.removeEventListener('blur', this.onBlur)\n this.input.removeEventListener('mousemove', this.onMouseMove)\n this.input.removeEventListener('mouseleave', this.onMouseLeave)\n this.input.removeEventListener('compositionstart', this.onCompositionStart)\n this.input.removeEventListener('compositionend', this.onCompositionEnd)\n this.document.removeEventListener('selectionchange', this.onSelectionChange)\n }\n\n private readonly onInput = (event: Event): void => {\n this.sync()\n const input = event as InputEvent\n const type = input.inputType ?? ''\n const deletion = type.startsWith('delete')\n const data = typeof input.data === 'string' ? input.data : ''\n // Typing is not a request for a tooltip, and leaving one up over text that has\n // moved is worse than not having shown it.\n this.hideTooltip()\n this.updateCompletionAfterInput(data, deletion)\n if (!this.applying) this.handlers.onChange?.(this.input.value)\n }\n\n private readonly onKeyDown = (event: KeyboardEvent): void => {\n // First, because a keystroke a row asked for is a pick and not text.\n if (this.commitCharacter(event)) return\n\n if (event.key === 'Escape') {\n if (this.popup.isOpen) {\n event.preventDefault()\n this.closeCompletion()\n return\n }\n this.hideTooltip()\n return\n }\n\n if (event.key === ' ' && (event.ctrlKey || event.metaKey)) {\n event.preventDefault()\n if (this.popup.isOpen) this.closeCompletion()\n else this.openCompletion('explicit')\n return\n }\n\n if (!this.popup.isOpen) return\n const last = this.popup.items.length - 1\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault()\n // No wrapping, because a list that jumps from the end back to the start on\n // one arrow press is a list nobody can navigate deliberately.\n this.setActive(Math.min(this.popup.activeIndex + 1, last))\n return\n case 'ArrowUp':\n event.preventDefault()\n this.setActive(Math.max(this.popup.activeIndex - 1, 0))\n return\n case 'PageDown':\n event.preventDefault()\n this.setActive(Math.min(this.popup.activeIndex + PAGE_STEP, last))\n return\n case 'PageUp':\n event.preventDefault()\n this.setActive(Math.max(this.popup.activeIndex - PAGE_STEP, 0))\n return\n case 'Enter':\n event.preventDefault()\n this.acceptCompletion(this.popup.activeIndex)\n return\n case 'Tab':\n event.preventDefault()\n this.acceptCompletion(this.popup.activeIndex)\n return\n default:\n return\n }\n }\n\n /**\n * Whether a keystroke is a commit character for the active row.\n *\n * Typing `=` at the end of `shape` takes the `shape=` row and keeps the\n * character, rather than either swallowing the keystroke or leaving the row to be\n * clicked. A row opts in; nothing has a commit character by default.\n * @param event - the key event.\n * @returns whether the keystroke was consumed.\n */\n private commitCharacter(event: KeyboardEvent): boolean {\n if (!this.popup.isOpen) return false\n if (event.key.length !== 1 || event.ctrlKey || event.metaKey || event.altKey) return false\n const characters = this.popup.activeRow?.item.commitCharacters\n if (characters === undefined || !characters.includes(event.key)) return false\n event.preventDefault()\n this.acceptCompletion(this.popup.activeIndex, event.key)\n return true\n }\n\n /** Make a row active and keep the ARIA pointer in step. */\n private setActive(index: number): void {\n this.popup.setActive(index)\n this.syncActiveDescendant()\n }\n\n private readonly onScroll = (): void => {\n this.overlay.syncScroll(this.input)\n this.placePopup()\n this.hideTooltip()\n }\n\n private readonly onCaretMoved = (): void => {\n this.updateCompletionForCaret()\n this.handlers.onSelectionChange?.(readSelection(this.input))\n }\n\n private readonly onKeyUp = (event: KeyboardEvent): void => {\n // Shift+Arrow and Home/End move the caret without an `input` event, and a list\n // left open over a caret that has walked out of its range would complete the\n // wrong thing.\n if (event.key.startsWith('Arrow') || event.key === 'Home' || event.key === 'End') {\n this.updateCompletionForCaret()\n }\n }\n\n private readonly onSelectionChange = (): void => {\n if (this.document.activeElement !== this.input) return\n this.handlers.onSelectionChange?.(readSelection(this.input))\n }\n\n private readonly onBlur = (): void => {\n // A pick beats this, because the list cancels the default on `mousedown`; a\n // genuine blur closes everything.\n this.closeCompletion()\n this.hideTooltip()\n }\n\n private readonly onMouseMove = (event: MouseEvent): void => {\n if (this.hover === undefined || !this.hover.enabled) return\n if (this.popup.isOpen) {\n this.hideTooltip()\n return\n }\n // The BROWSER is asked where the pointer is in the text, rather than the editor\n // measuring wrapped proportional glyphs by hand — which is exactly the geometry\n // a hand-written measurement always gets slightly wrong.\n const offset = caretOffsetFromPoint(this.document, event.clientX, event.clientY)\n if (offset === undefined) return\n this.queueHover(offset, event)\n }\n\n private readonly onMouseLeave = (): void => {\n this.hoverOffset = undefined\n this.hideTooltip()\n }\n\n private readonly onCompositionStart = (): void => {\n this.composing = true\n this.closeCompletion()\n }\n\n private readonly onCompositionEnd = (): void => {\n this.composing = false\n this.sync()\n }\n}\n\n/**\n * The full custom-property name for a key a host may have written in a few ways.\n *\n * `font`, `litearea-font`, and `--litearea-font` all mean the same property; a key that already\n * begins with `--` is used verbatim, so `--litearea-font` and a host's own `--my-brand` both\n * work without the editor having to guess which prefix was meant.\n * @param key - the key as written.\n * @returns the custom-property name.\n */\nfunction variableName(key: string): string {\n if (key.startsWith('--')) return key\n return key.startsWith('litearea-') ? `--${key}` : `--litearea-${key}`\n}\n\n/**\n * The caret offset a viewport point falls on.\n *\n * A free function so the editor does not reach into the document for it, and so the\n * two spellings of the API live in one place.\n * @param ownerDocument - the document.\n * @param x - viewport x.\n * @param y - viewport y.\n * @returns the offset, or undefined when the browser cannot say.\n */\nfunction caretOffsetFromPoint(\n ownerDocument: Document,\n x: number,\n y: number,\n): number | undefined {\n const probe = ownerDocument as Document & {\n caretPositionFromPoint?: (x: number, y: number) => { offset: number } | null\n caretRangeFromPoint?: (x: number, y: number) => Range | null\n }\n if (typeof probe.caretPositionFromPoint === 'function') {\n return probe.caretPositionFromPoint(x, y)?.offset\n }\n if (typeof probe.caretRangeFromPoint === 'function') {\n return probe.caretRangeFromPoint(x, y)?.startOffset\n }\n return undefined\n}\n\n/** A severity, re-exported so a host can narrow a diagnostic without importing core. */\nexport type EditorSeverity = Severity\n\n/** A range, re-exported for the same reason. */\nexport type EditorRange = Range\n\n/** A decoration, re-exported for the same reason. */\nexport type EditorDecoration = Decoration\n","// ─── create: the one-line entry point ───────────────────────────────────────\n//\n// The class exists for a host that wants to hold the instance and drive it. This\n// exists for the far more common case of wanting an editor in an element and not\n// much else.\n\nimport { LiteArea, type LiteAreaOptions } from './editor.js'\n\n/**\n * Build an editor and put it in an element.\n *\n * The `refresh` after mounting is not a formality. A textarea that is not in the\n * document has no layout, so it has no width, so nothing can be measured against it\n * — and a measurement taken then is not merely imprecise, it wraps the text at every\n * character and comes back several times too tall. The editor's own\n * `ResizeObserver` would correct it on the next frame, which means one frame of a box\n * at the wrong height. Measuring again here, synchronously, means the first frame is\n * already right.\n * @param target - where to mount it. Its contents are appended to, not replaced.\n * @param options - the grammar, the initial text, and the behaviour to use.\n * @returns the editor, so the caller can drive it.\n */\nexport function createEditor<State = unknown>(\n target: Element,\n options: LiteAreaOptions<State>,\n): LiteArea<State> {\n const editor = new LiteArea(options)\n target.appendChild(editor.element)\n editor.refresh()\n return editor\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/format.ts","../src/core/text.ts","../src/core/vocabulary.ts","../src/core/scan.ts","../src/core/inspect.ts","../src/core/segments.ts","../src/core/rank.ts","../src/core/complete.ts","../src/core/hover.ts","../src/core/grammar.ts","../src/styles.ts","../src/dom/support.ts","../src/dom/editing.ts","../src/dom/mirror.ts","../src/dom/overlay.ts","../src/dom/popup.ts","../src/dom/tooltip.ts","../src/dom/editor.ts","../src/dom/create.ts"],"names":["range","index","previousScope","match","scopeClass","decorationClass","severityClass","complete","head","rest","written"],"mappings":"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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgItB,YAAY;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;A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","file":"index.cjs","sourcesContent":["// ─── format: the small string helpers the messages share ────────────────────\n//\n// Kept apart from the vocabulary so that a grammar can raise its own diagnostics\n// with the same phrasing the built-in ones use, and so that a translated host can\n// reuse the substitution instead of writing a second one.\n\n/** The most members a message will name before it stops counting. */\nconst DEFAULT_LIST_LIMIT = 12\n\n/**\n * Substitute `{name}` placeholders in a template.\n *\n * A placeholder with no matching key is left exactly as it was rather than\n * blanked: a visible `{allowed}` in a message is a bug report, and an empty gap\n * is a mystery.\n * @param template - the template, with `{name}` placeholders.\n * @param values - the substitutions.\n * @returns the filled text.\n */\nexport function fillTemplate(template: string, values: Readonly<Record<string, string>>): string {\n return String(template).replace(/\\{(\\w+)\\}/g, (match, key: string) =>\n Object.hasOwn(values, key) ? String(values[key]) : match,\n )\n}\n\n/**\n * A readable list: `a`, `a or b`, `a, b, or c`.\n *\n * The conjunction is a parameter because the same list reads differently as\n * \"expected one of X, Y, or Z\" and as \"X, Y, and Z are installed\".\n * @param items - the members.\n * @param options - `conjunction` (`'or'` by default) and `limit`, the most\n * members to name before summarising the rest as `… and N more`.\n * @returns the phrase.\n */\nexport function listPhrase(\n items: readonly string[],\n options?: { conjunction?: string; limit?: number },\n): string {\n const conjunction = options?.conjunction ?? 'or'\n const limit = options?.limit ?? DEFAULT_LIST_LIMIT\n const shown = items.slice(0, limit)\n const rest = items.length - shown.length\n if (shown.length === 0) return ''\n if (shown.length === 1) {\n return rest > 0 ? `${String(shown[0])} and ${String(rest)} more` : String(shown[0])\n }\n // Two members take no comma before the conjunction. \"circle, or square\" is not how\n // anyone writes it, and every diagnostic that lists a two-member vocabulary would\n // have said it that way.\n if (shown.length === 2) {\n const pair = `${String(shown[0])} ${conjunction} ${String(shown[1])}`\n return rest > 0 ? `${pair}, and ${String(rest)} more` : pair\n }\n const head = shown.slice(0, -1).join(', ')\n const tail = shown[shown.length - 1]\n const phrase = `${head}, ${conjunction} ${String(tail)}`\n return rest > 0 ? `${phrase}, and ${String(rest)} more` : phrase\n}\n\n/**\n * Collapse the whitespace in a snippet of user text so it can be quoted inside a\n * one-line message.\n * @param text - the text.\n * @param limit - the longest result, ellipsised beyond it.\n * @returns the excerpt.\n */\nexport function excerpt(text: string, limit = 24): string {\n const flat = text.replace(/\\s+/g, ' ').trim()\n return flat.length <= limit ? flat : `${flat.slice(0, limit - 1)}…`\n}\n","// ─── text: offsets, lines, and words ────────────────────────────────────────\n//\n// The engine counts in character offsets and nothing else. Not rows, not\n// columns, not pixels: every position that crosses a module boundary in litearea\n// is an offset into the document string, so there is exactly one coordinate\n// system to get wrong instead of three that must be kept in step.\n//\n// Pixels enter only in `src/dom/`, only to place the popup, and never travel\n// back inward. That boundary is the fix for a whole family of bugs in the\n// editors this library replaces, where a caret was tracked as a character index\n// in one place and read back as a screen position in another.\n\nimport type { LineInfo, Range, Token, WordInfo } from './types.js'\n\n/** Keeps a number inside a range, which every caller here needs and none should repeat. */\nexport function clamp(value: number, low: number, high: number): number {\n return value < low ? low : value > high ? high : value\n}\n\n/** Whether a value is a usable offset: a finite, non-negative integer. */\nexport function isOffset(value: unknown): value is number {\n return typeof value === 'number' && Number.isInteger(value) && value >= 0\n}\n\n/**\n * The offset each line starts at, in order. The first entry is always `0`.\n *\n * `\\r\\n`, `\\n`, and a lone `\\r` all end a line, because this text is typed by\n * hand into a textarea and a paste from a Windows editor must not read as one\n * long line. The terminator itself belongs to no line: a line's text excludes it\n * so that column arithmetic never has to reason about a stray carriage return.\n * @param source - the document.\n * @returns one offset per line, ascending.\n */\nexport function lineStarts(source: string): number[] {\n const starts = [0]\n for (let index = 0; index < source.length; index += 1) {\n const code = source.charCodeAt(index)\n if (code === 10) {\n starts.push(index + 1)\n } else if (code === 13) {\n if (source.charCodeAt(index + 1) === 10) index += 1\n starts.push(index + 1)\n }\n }\n return starts\n}\n\n/**\n * The index of the line an offset falls on.\n * @param starts - the result of {@link lineStarts}.\n * @param offset - a character offset.\n * @returns a zero-based line index.\n */\nexport function lineIndexAt(starts: readonly number[], offset: number): number {\n let low = 0\n let high = starts.length - 1\n while (low < high) {\n const middle = Math.ceil((low + high) / 2)\n if ((starts[middle] ?? 0) <= offset) low = middle\n else high = middle - 1\n }\n return low\n}\n\n/**\n * The line an offset falls on, with the offset expressed inside it.\n *\n * `before` and `after` are the line's own text split at the caret, which is what\n * completion and the indentation rules actually want; handing them out here\n * means neither has to re-derive the split and get it subtly different.\n * @param source - the document.\n * @param offset - a character offset; clamped into the document.\n * @param starts - the result of {@link lineStarts}, when the caller already has it.\n * @returns the line, its bounds, and the caret's place in it.\n */\nexport function lineAt(source: string, offset: number, starts?: readonly number[]): LineInfo {\n const position = clamp(offset, 0, source.length)\n const boundaries = starts ?? lineStarts(source)\n const index = lineIndexAt(boundaries, position)\n const from = boundaries[index] ?? 0\n const rawTo = boundaries[index + 1] ?? source.length\n // The next line's start sits after the terminator, so the last character of\n // the raw slice is the terminator itself — one character, or two for `\\r\\n`.\n let to = rawTo\n while (to > from) {\n const code = source.charCodeAt(to - 1)\n if (code === 10 || code === 13) to -= 1\n else break\n }\n const text = source.slice(from, to)\n const column = clamp(position - from, 0, text.length)\n return {\n from,\n to,\n text,\n number: index,\n column,\n before: text.slice(0, column),\n after: text.slice(column),\n }\n}\n\n/**\n * Whether a character is part of a word.\n *\n * The predicate is supplied by the grammar because it decides three things at\n * once — what a completion replaces, what a diagnostic underlines, and where a\n * double click puts the selection — and a language whose names contain a hyphen\n * must say so or every completion will replace one segment of a name instead of\n * the name.\n * @param char - one character, or the empty string at the end of the document.\n * @param wordChars - a single-character test.\n * @returns whether the character continues a word.\n */\nexport function isWordChar(char: string, wordChars: RegExp): boolean {\n return char !== '' && wordChars.test(char)\n}\n\n/**\n * The word at an offset.\n *\n * The word is found by expanding in BOTH directions from the offset rather than\n * by requiring the offset to be strictly inside a word. Completion needs the\n * second reading: a caret sitting at `Geist|` is at the end of the word, and the\n * word it is completing is still `Geist` — a lookup that insisted the offset be\n * interior would find nothing at exactly the moment the user wants a list.\n * @param source - the document.\n * @param offset - a character offset; clamped into the document.\n * @param wordChars - a single-character test.\n * @returns the word, its range, and the text either side of the caret.\n */\nexport function wordInfoAt(source: string, offset: number, wordChars: RegExp): WordInfo {\n const position = clamp(offset, 0, source.length)\n let from = position\n let to = position\n while (from > 0 && isWordChar(source.charAt(from - 1), wordChars)) from -= 1\n while (to < source.length && isWordChar(source.charAt(to), wordChars)) to += 1\n const text = source.slice(from, to)\n const column = position - from\n return {\n from,\n to,\n text,\n prefix: text.slice(0, column),\n suffix: text.slice(column),\n }\n}\n\n/** Whether a range is empty. */\nexport function isEmptyRange(range: Range): boolean {\n return range.to <= range.from\n}\n\n/** Whether an offset lies inside a range, with `to` exclusive. */\nexport function containsOffset(range: Range, offset: number): boolean {\n return offset >= range.from && offset < range.to\n}\n\n// ─── reading the token stream ───────────────────────────────────────────────\n\n/**\n * The token covering an offset.\n *\n * Zero-length tokens are skipped, so a caret at a boundary resolves to the token\n * it is *inside* rather than to an empty marker sitting on the seam.\n * @param tokens - the scanned tokens, ascending.\n * @param offset - a character offset.\n * @returns the covering token, or undefined in whitespace.\n */\nexport function tokenAt(tokens: readonly Token[], offset: number): Token | undefined {\n for (const token of tokens) {\n if (token.from <= offset && offset < token.to) return token\n if (token.from > offset) break\n }\n return undefined\n}\n\n/**\n * The scope painted at an offset, when there is one.\n * @param tokens - the scanned tokens, ascending.\n * @param offset - a character offset.\n * @returns the scope, or undefined in whitespace.\n */\nexport function scopeAt(tokens: readonly Token[], offset: number): string | undefined {\n return tokenAt(tokens, offset)?.scope\n}\n\n/**\n * The nearest token that ends at or before an offset, skipping whitespace.\n *\n * Whitespace is skipped because every caller is asking a question about\n * structure — \"which slot is this word in?\" — and a space is never an answer.\n * @param tokens - the scanned tokens, ascending.\n * @param offset - a character offset.\n * @returns the token, or undefined at the start of the document.\n */\nexport function tokenBefore(tokens: readonly Token[], offset: number): Token | undefined {\n let found\n for (const token of tokens) {\n if (token.to > offset) break\n if (token.text.trim() !== '') found = token\n }\n return found\n}\n\n/**\n * The nearest token that starts at or after an offset, skipping whitespace.\n * @param tokens - the scanned tokens, ascending.\n * @param offset - a character offset.\n * @returns the token, or undefined at the end of the document.\n */\nexport function tokenAfter(tokens: readonly Token[], offset: number): Token | undefined {\n for (const token of tokens) {\n if (token.to <= offset) continue\n if (token.text.trim() !== '') return token\n }\n return undefined\n}\n\n/**\n * The non-whitespace tokens on one line, in order.\n *\n * Completion and diagnostics both ask \"what is on this line so far\", and both\n * must ignore the indentation and the gaps between words. Returning the tokens\n * rather than the words means a grammar can ask what they *were* (their scopes)\n * and not only what they said.\n * @param tokens - the scanned tokens, ascending.\n * @param line - a line number, or a line record.\n * @returns the tokens on that line.\n */\nexport function tokensOnLine(\n tokens: readonly Token[],\n line: number | LineInfo,\n): Token[] {\n const number = typeof line === 'number' ? line : line.number\n return tokens.filter((token) => token.line === number && token.text.trim() !== '')\n}\n","// ─── vocabulary: the four facts that must agree ─────────────────────────────\n//\n// A closed set of words appears four times in a language-aware editor: as the\n// syntax that accepts it, as the colour it is painted in, as the message a typo\n// earns, and as the documentation a hover shows. Written out four times they\n// drift — a word added to the parser and forgotten by the highlighter is the\n// ordinary way a grammar rots — and the drift is invisible until someone types\n// the new word and watches the editor get it wrong.\n//\n// So they are declared once. `defineVocabulary` returns an object the engine\n// already knows how to consume: hand it to a `words` rule and it paints, accepts,\n// rejects, and documents without being mentioned again.\n//\n// const SHAPES = defineVocabulary({\n// id: 'shape',\n// words: ['circle', 'rounded', 'square', 'none'],\n// unknownMessage: '\"{word}\" is not a shape — expected one of {allowed}.',\n// docs: { circle: 'A full disc, the background for a busy state.' },\n// })\n//\n// { kind: 'words', words: SHAPES }\n\nimport type {\n ResolvedVocabulary,\n Scope,\n Severity,\n VocabularyContext,\n VocabularyEntry,\n WordsSource,\n} from './types.js'\nimport { fillTemplate, listPhrase } from './format.js'\n\n/** What a vocabulary is told about the document it is being resolved for. */\nexport interface VocabularySpec<State = unknown> {\n /** A stable id, used in the diagnostic code and for debugging. */\n id: string\n /**\n * The members.\n *\n * A function is how a set that lives outside the document reaches the grammar\n * without the grammar holding mutable state: the installed fonts, the states\n * the host actually has. It is called once per scan.\n */\n words: readonly string[] | ((context: VocabularyContext<State>) => readonly string[])\n /** The scope a member is painted with. Defaults to `vocabulary:<id>`. */\n scope?: Scope | ((word: string) => Scope)\n /** The scope a rejected word is painted with. Defaults to `'invalid'`. */\n unknownScope?: Scope\n /**\n * The message a rejected word earns.\n *\n * Present, a word-shaped token outside the set is reported; absent, it is\n * reported by nobody and the grammar is the poorer for it. `{word}` and\n * `{allowed}` are substituted, the latter as a readable list.\n */\n unknownMessage?: string | ((word: string, allowed: readonly string[]) => string)\n /** How loudly a rejected word complains. Default `'error'`. */\n unknownSeverity?: Severity\n /** A stable code for the rejection. Defaults to `vocabulary:<id>`. */\n unknownCode?: string\n /**\n * What each member explains about itself, for hover. A bare string is taken as\n * the body.\n */\n docs?: Readonly<Record<string, string | VocabularyEntry>>\n /** A dimmed line shown beside a member in the completion list. */\n detail?: (word: string) => string | undefined\n /** Whether membership is case-sensitive. Default `false`. */\n caseSensitive?: boolean\n /**\n * How a member is written into the document when it is accepted.\n *\n * Separate from the word itself because a member is not always insertable as\n * typed: a font family containing a space has to be quoted, even though the\n * vocabulary calls it `IBM Plex Mono`.\n */\n format?: (word: string) => string\n}\n\n/**\n * Build a vocabulary: the set, its colour, its rejection, and its documentation.\n * @param spec - the declaration.\n * @returns a resolved vocabulary, ready for a `words` rule.\n */\nexport function defineVocabulary<State = unknown>(\n spec: VocabularySpec<State>,\n): ResolvedVocabulary<State> {\n const caseSensitive = spec.caseSensitive === true\n const unknownScope = spec.unknownScope ?? 'invalid'\n const defaultScope = `vocabulary:${spec.id}`\n const unknownCode = spec.unknownCode ?? `vocabulary:${spec.id}`\n const unknownSeverity = spec.unknownSeverity ?? 'error'\n /** Fold a word for lookup, honouring the vocabulary's case rule. */\n const fold = (word: string): string => (caseSensitive ? word : word.toLowerCase())\n /** Find the member a word names, preserving the declared spelling. */\n const memberOf = (word: string, allowed: readonly string[]): string | undefined => {\n const needle = fold(word)\n return allowed.find((candidate) => fold(candidate) === needle)\n }\n /** The declaration for one member, whichever of the two shapes it took. */\n const docOf = (word: string): VocabularyEntry | undefined => {\n if (spec.docs === undefined) return undefined\n for (const [key, value] of Object.entries(spec.docs)) {\n if (fold(key) !== fold(word)) continue\n return typeof value === 'string' ? { body: value } : value\n }\n return undefined\n }\n\n return {\n id: spec.id,\n caseSensitive,\n resolve: (context) => {\n const words = typeof spec.words === 'function' ? spec.words(context) : spec.words\n return Array.isArray(words) ? words : []\n },\n has: (word, context) => {\n const words = typeof spec.words === 'function' ? spec.words(context) : spec.words\n return memberOf(word, Array.isArray(words) ? words : []) !== undefined\n },\n scopeFor: (word) => {\n if (typeof spec.scope === 'function') return spec.scope(memberOf(word, [word]) ?? word)\n return spec.scope ?? defaultScope\n },\n unknownScope,\n reject: (word, context) => {\n if (spec.unknownMessage === undefined) return undefined\n const allowed = typeof spec.words === 'function' ? spec.words(context) : spec.words\n const members = Array.isArray(allowed) ? allowed : []\n const message =\n typeof spec.unknownMessage === 'function'\n ? spec.unknownMessage(word, members)\n : fillTemplate(spec.unknownMessage, {\n word,\n allowed: listPhrase(members, { conjunction: 'or' }),\n })\n return { message, severity: unknownSeverity, code: unknownCode }\n },\n entryFor: (word) => docOf(word),\n format: (word) => (spec.format === undefined ? word : spec.format(word)),\n }\n}\n\n/**\n * The members of a vocabulary, resolved for a document.\n *\n * A helper for the common case of a caller that has a vocabulary and wants its\n * words, without reaching through to `resolve` and re-supplying the context.\n * @param vocabulary - a resolved vocabulary.\n * @param context - the document it is being resolved for.\n * @returns the members, in declaration order.\n */\nexport function vocabularyWords<State>(\n vocabulary: ResolvedVocabulary<State>,\n context: VocabularyContext<State>,\n): readonly string[] {\n return vocabulary.resolve(context)\n}\n\n/**\n * Recognize a vocabulary among the shapes a `WordsSource` may take.\n *\n * The test is structural rather than `instanceof`, so a grammar may hand over its\n * own object as long as it carries the four facts — which is what lets a host\n * wrap a vocabulary in logging, caching, or a translation layer without the\n * engine needing to know.\n * @param source - a words source.\n * @returns the vocabulary, or undefined when the source is a bare list or function.\n */\nexport function asResolvedVocabulary<State>(\n source: WordsSource<State>,\n): ResolvedVocabulary<State> | undefined {\n if (typeof source !== 'object' || source === null || Array.isArray(source)) return undefined\n const candidate = source as { resolve?: unknown }\n return typeof candidate.resolve === 'function' ? (source as ResolvedVocabulary<State>) : undefined\n}\n\n/**\n * The members any words source stands for, whichever shape it took.\n * @param source - a bare list, a vocabulary, or a function.\n * @param context - the document it is being resolved for.\n * @returns the members, or an empty list when the source resolved to nothing.\n */\nexport function resolveWordsSource<State>(\n source: WordsSource<State>,\n context: VocabularyContext<State>,\n): readonly string[] {\n const vocabulary = asResolvedVocabulary(source)\n const raw =\n vocabulary !== undefined\n ? vocabulary.resolve(context)\n : typeof source === 'function'\n ? source(context)\n : source\n return Array.isArray(raw) ? raw.filter((word) => word !== '') : []\n}\n","// ─── scan: text in, painted tokens out ──────────────────────────────────────\n//\n// One left-to-right pass. At each position the rules are tried in the order the\n// grammar declared them and the first one that matches wins, which is the whole\n// of the precedence model: to make a rule win, put it higher.\n//\n// A few decisions here are what keep a hand-written grammar honest.\n//\n// A rule may never match the empty string. A pattern that can, such as `/\\w*/`,\n// is treated as if it did not match, so the scan cannot stall on one position\n// forever. An infinite loop in a highlighter looks exactly like a frozen page.\n//\n// Consecutive tokens with the same scope are merged. Whitespace is most of a\n// document, and one span per space would mean thousands of DOM nodes for a file\n// nobody is looking at. Merging stops at a newline, because a token's line and\n// column describe where it starts and a span across two lines would make that a\n// lie.\n//\n// A non-nested region is found in one search rather than tested character by\n// character, and its contents are painted as a single span without the rule list\n// ever running inside it. That is what makes a string a string: the word\n// `running` inside a quoted font name is text, not a state.\n\nimport type {\n Diagnostic,\n Grammar,\n LineInfo,\n RegionRule,\n Rule,\n RuleContext,\n RuleMatch,\n Scope,\n ScopeSpec,\n Token,\n VocabularyContext,\n WordsRule,\n WordsSource,\n} from './types.js'\nimport { listPhrase } from './format.js'\nimport { clamp, isWordChar, lineAt, lineIndexAt, lineStarts } from './text.js'\nimport { asResolvedVocabulary } from './vocabulary.js'\n\n/** A grammar with its defaults filled in and its patterns made safe to reuse. */\nexport interface ResolvedGrammar<State = unknown> {\n /**\n * Marks this value as already resolved.\n *\n * Present so the two shapes can be told apart without guessing. The obvious test\n * — \"does it have a `fallbackScope`?\" — is wrong, because a plain grammar is\n * allowed to declare one, and the mistake surfaces as the engine reading `.grammar`\n * off a value that has no such field and crashing at the first keystroke.\n */\n readonly __resolved: true\n grammar: Grammar<State>\n rules: readonly Rule<State>[]\n /** The scope a character no rule claimed is painted with. */\n fallbackScope: Scope\n /** The single-character test that decides where words begin and end. */\n wordChars: RegExp\n}\n\n/**\n * Whether a value is a resolved grammar rather than one as written.\n * @param value - the grammar, either shape.\n * @returns whether it is already resolved.\n */\nexport function isResolvedGrammar<State>(\n value: Grammar<State> | ResolvedGrammar<State>,\n): value is ResolvedGrammar<State> {\n return (value as { __resolved?: unknown }).__resolved === true\n}\n\n/** The whole result of one scan: the paint, what the scan noticed, and the analysis. */\nexport interface ScanResult<State = unknown> {\n tokens: Token[]\n /**\n * What the lexical pass itself found: a word a vocabulary rejected, a region\n * that never closed. A grammar's own `checks` and `validate` are added by\n * `diagnose`, which builds on this.\n */\n diagnostics: Diagnostic[]\n /** Whatever `Grammar.analyze` returned, or `initialState`. */\n state: State\n}\n\n/** The word predicate a grammar that does not declare one gets. */\nconst DEFAULT_WORD_CHARS = /[\\p{L}\\p{N}_$]/u\n\n/**\n * A pattern that can be run at a position without ever skipping ahead.\n *\n * The sticky flag is added rather than demanded: a grammar author writing\n * `/foo/` means \"foo here\", and one who forgot the `y` would otherwise get a\n * pattern that quietly matches anywhere later in the document and paints the\n * wrong text. Compiled patterns are cached per source pattern, so a scan does not\n * recompile one per position.\n */\nconst stickyCache = new WeakMap<RegExp, RegExp>()\n\n/**\n * A pattern that runs at a position and cannot skip ahead.\n * @param pattern - the rule's pattern.\n * @returns the same pattern with the sticky flag, cached.\n */\nfunction sticky(pattern: RegExp): RegExp {\n const cached = stickyCache.get(pattern)\n if (cached !== undefined) return cached\n const flags = pattern.flags.replace(/[gy]/g, '')\n const compiled = new RegExp(pattern.source, `${flags}y`)\n stickyCache.set(pattern, compiled)\n return compiled\n}\n\n/** Run a pattern at an exact position, or report that it did not match there. */\nfunction execAt(pattern: RegExp, source: string, index: number): RegExpExecArray | null {\n pattern.lastIndex = index\n const match = pattern.exec(source)\n return match !== null && match.index === index ? match : null\n}\n\n/**\n * Strip the flags that would make a pattern stateful across calls.\n *\n * `RegExp.prototype.test` advances `lastIndex` on a global pattern, so a word\n * predicate carrying one would answer correctly for the first character and then\n * for every other one — a bug that looks like a typo in the grammar and cannot be\n * seen by reading it.\n * @param pattern - the grammar's pattern, if it declared one.\n * @returns a pattern safe to call repeatedly.\n */\nfunction withoutStatefulFlags(pattern: RegExp): RegExp {\n const flags = pattern.flags.replace(/[gy]/g, '')\n return flags === pattern.flags ? pattern : new RegExp(pattern.source, flags)\n}\n\n/**\n * Fill in a grammar's defaults and make its patterns safe.\n * @param grammar - the grammar as written.\n * @returns the grammar the scanner runs.\n */\nexport function resolveGrammar<State>(grammar: Grammar<State>): ResolvedGrammar<State> {\n return {\n __resolved: true,\n grammar,\n rules: grammar.rules,\n fallbackScope: grammar.fallbackScope ?? 'text',\n wordChars: withoutStatefulFlags(grammar.wordChars ?? DEFAULT_WORD_CHARS),\n }\n}\n\n/** What a words source resolves to, once per scan. */\ninterface ResolvedWords {\n list: readonly string[]\n /** Folded member text, for lookup. */\n set: Set<string>\n /**\n * Members containing a character the word predicate rejects, longest first.\n * They cannot be reached by reading a word in, so they are matched literally.\n */\n literal: readonly string[]\n caseSensitive: boolean\n}\n\n/**\n * Scan a document into tokens.\n * @param source - the document.\n * @param grammar - the language, as written or already resolved.\n * @returns the tokens, the lexical diagnostics, and the analysis.\n */\nexport function scan<State>(\n source: string,\n grammar: Grammar<State> | ResolvedGrammar<State>,\n): ScanResult<State> {\n const resolved: ResolvedGrammar<State> = isResolvedGrammar(grammar)\n ? grammar\n : resolveGrammar(grammar)\n const { rules, fallbackScope, wordChars } = resolved\n const declared = resolved.grammar\n const sourceId = declared.id\n const state: State =\n declared.analyze === undefined ? (declared.initialState as State) : declared.analyze(source)\n const vocabularyContext: VocabularyContext<State> = { text: source, state }\n\n const tokens: Token[] = []\n const diagnostics: Diagnostic[] = []\n const starts = lineStarts(source)\n const length = source.length\n\n // ── per-scan caches ───────────────────────────────────────────────────────\n // The vocabulary context is constant for a whole scan, so a vocabulary is\n // resolved once rather than at every position that tests a word.\n const wordsCache = new Map<WordsSource<State>, ResolvedWords>()\n /**\n * The line last asked for, so the scan does not re-slice per token.\n *\n * Only the line's BOUNDS are cached, never its column. A column depends on the\n * position being asked about while the bounds do not, and caching the pair\n * together is a bug with a very specific smell: the first token on a line caches\n * column 0, every later token on that line reads it back, and every rule guarded\n * by `firstOnLine` starts matching the whole line.\n */\n let cachedLineNumber = -1\n let cachedLineBounds: { from: number; to: number; text: string } | undefined\n /** Compiled `prevNot` character classes, per rule context. */\n const prevNotCache = new WeakMap<RuleContext, RegExp>()\n\n /** The line record for a position, with the column computed for that position. */\n const lineInfoAt = (position: number): LineInfo => {\n const number = lineIndexAt(starts, position)\n if (number !== cachedLineNumber || cachedLineBounds === undefined) {\n const info = lineAt(source, position, starts)\n cachedLineBounds = { from: info.from, to: info.to, text: info.text }\n cachedLineNumber = number\n }\n const column = clamp(position - cachedLineBounds.from, 0, cachedLineBounds.text.length)\n return {\n from: cachedLineBounds.from,\n to: cachedLineBounds.to,\n text: cachedLineBounds.text,\n number,\n column,\n before: cachedLineBounds.text.slice(0, column),\n after: cachedLineBounds.text.slice(column),\n }\n }\n\n /** Resolve a words source, once per scan. */\n const resolveWords = (from: WordsSource<State>): ResolvedWords => {\n const cached = wordsCache.get(from)\n if (cached !== undefined) return cached\n const vocabulary = asResolvedVocabulary(from)\n const caseSensitive = vocabulary?.caseSensitive === true\n const raw =\n vocabulary !== undefined\n ? vocabulary.resolve(vocabularyContext)\n : typeof from === 'function'\n ? from(vocabularyContext)\n : from\n const list = Array.isArray(raw) ? raw.filter((word) => word !== '') : []\n const fold = (word: string): string => (caseSensitive ? word : word.toLowerCase())\n const entry: ResolvedWords = {\n list,\n set: new Set(list.map(fold)),\n literal: list\n .filter((word) => [...word].some((char) => !isWordChar(char, wordChars)))\n .slice()\n .sort((left, right) => right.length - left.length),\n caseSensitive,\n }\n wordsCache.set(from, entry)\n return entry\n }\n\n /** Name a match: a fixed scope, or the grammar's function. */\n const scopeOf = (\n spec: ScopeSpec<State> | undefined,\n match: RuleMatch<State>,\n fallback: Scope,\n ): Scope => (spec === undefined ? fallback : typeof spec === 'function' ? spec(match) : spec)\n\n /** Whether every predicate a rule declared holds at this position. */\n const contextHolds = (\n when: RuleContext | undefined,\n index: number,\n previousScope: Scope | undefined,\n ): boolean => {\n if (when === undefined) return true\n const info = lineInfoAt(index)\n if (when.firstOnLine === true && info.text.slice(0, info.column).trim() !== '') return false\n if (when.after !== undefined) {\n if (previousScope === undefined || !when.after.includes(previousScope)) return false\n }\n if (when.notAfter !== undefined && previousScope !== undefined) {\n if (when.notAfter.includes(previousScope)) return false\n }\n if (when.line !== undefined && !when.line.test(info.text)) return false\n if (when.minColumn !== undefined && info.column < when.minColumn) return false\n if (when.maxColumn !== undefined && info.column > when.maxColumn) return false\n if (when.prevNot !== undefined && index > 0) {\n let pattern = prevNotCache.get(when)\n if (pattern === undefined) {\n pattern = new RegExp(`[${when.prevNot}]`)\n prevNotCache.set(when, pattern)\n }\n // `prevNot` names characters that must NOT precede the match, so a hit here is\n // a failure. At offset zero there is nothing in front of the match, so the\n // predicate holds — a rule guarded this way is not meant to be disabled at the\n // start of the document, which is what returning early there would do.\n if (pattern.test(source.charAt(index - 1))) return false\n }\n return true\n }\n\n // ── emitting ─────────────────────────────────────────────────────────────\n\n /** The scope of the innermost enclosing region, for a token's `region`. */\n let regionScope: Scope | undefined\n /** The scope of the nearest preceding non-whitespace token, maintained as we go. */\n let previousScope: Scope | undefined\n\n /**\n * Append a token, merging it into the previous one when that is invisible.\n * @param scope - the scope to paint.\n * @param from - the first offset.\n * @param to - the offset after the last.\n * @param region - overrides the enclosing region scope, for a fast-path region.\n */\n const push = (scope: Scope, from: number, to: number, region?: Scope): void => {\n if (to <= from) return\n const text = source.slice(from, to)\n const last = tokens[tokens.length - 1]\n if (\n last !== undefined &&\n last.scope === scope &&\n last.to === from &&\n last.region === region &&\n !/[\\r\\n]/.test(text) &&\n !/[\\r\\n]/.test(last.text)\n ) {\n last.to = to\n last.text = source.slice(last.from, to)\n } else {\n const info = lineInfoAt(from)\n tokens.push({ from, to, scope, text, line: info.number, column: from - info.from, region })\n }\n if (text.trim() !== '') previousScope = scope\n }\n\n /** Raise a diagnostic, stamping the grammar's id on it. */\n const report = (problem: {\n from: number\n to: number\n message: string\n severity?: Diagnostic['severity']\n code?: string\n }): void => {\n diagnostics.push({\n from: problem.from,\n to: problem.to,\n message: problem.message,\n severity: problem.severity ?? 'error',\n code: problem.code ?? 'lexical',\n source: sourceId,\n })\n }\n\n /** The `RuleMatch` a scope function is handed. */\n const ruleMatch = (\n text: string,\n from: number,\n groups: readonly (string | undefined)[],\n ): RuleMatch<State> => ({ text, source, from, groups, state })\n\n // ── reading words ────────────────────────────────────────────────────────\n\n /** The offset after the run of word characters starting at a position. */\n const readWordRun = (index: number): number => {\n let to = index\n while (to < length && isWordChar(source.charAt(to), wordChars)) to += 1\n return to\n }\n\n /**\n * The whitespace-separated segments a phrase may span.\n *\n * A phrase never crosses a line: a name split over two lines is two names, and\n * letting a vocabulary reach across the break would paint a paragraph as one\n * font.\n */\n const readSegments = (index: number, limit: number): Array<{ from: number; to: number }> => {\n const segments: Array<{ from: number; to: number }> = []\n let cursor = index\n while (segments.length < limit && cursor < length) {\n const to = readWordRun(cursor)\n if (to === cursor) break\n segments.push({ from: cursor, to })\n cursor = to\n const gap = /^[^\\S\\r\\n]+/.exec(source.slice(cursor))?.[0]\n if (gap === undefined) break\n cursor += gap.length\n }\n return segments\n }\n\n /** The longest member a position spells, or undefined when it spells none. */\n const matchWords = (\n rule: WordsRule<State>,\n words: ResolvedWords,\n index: number,\n ): { to: number; member: string } | undefined => {\n const fold = (word: string): string => (words.caseSensitive ? word : word.toLowerCase())\n const firstTo = readWordRun(index)\n if (firstTo > index) {\n if (rule.phrase !== undefined) {\n const segments = readSegments(index, Math.max(rule.phrase.max ?? 4, 1))\n // Longest first, so a catalogue holding both `IBM Plex` and `IBM Plex\n // Mono` resolves the longer name.\n for (let count = segments.length; count >= 1; count -= 1) {\n const texts = segments.slice(0, count).map((segment) => source.slice(segment.from, segment.to))\n const candidate = texts.join(' ')\n if (words.set.has(fold(candidate))) {\n const last = segments[count - 1]\n if (last !== undefined) return { to: last.to, member: candidate }\n }\n }\n } else {\n const candidate = source.slice(index, firstTo)\n if (words.set.has(fold(candidate))) return { to: firstTo, member: candidate }\n }\n }\n // A member the word predicate cannot read, matched as written. Only tried when reading\n // a word in failed, so the ordinary path pays nothing.\n for (const member of words.literal) {\n // A member containing whitespace is reachable through the phrase path, and matching\n // it literally would ignore `phrase.max` — a cap that only applies on one of the two\n // routes to the same member is not a cap.\n if (rule.phrase !== undefined && /\\s/.test(member)) continue\n if (source.startsWith(member, index)) return { to: index + member.length, member }\n }\n return undefined\n }\n\n /** Whether any rule would claim a position, which is what ends an unclaimed run. */\n const anyRuleClaims = (index: number, previous: Scope | undefined): boolean => {\n // A nested region's closing delimiter is a claim even though no rule mentions\n // it at this position. Without this the run would swallow the delimiter, the\n // region would never close, and a perfectly well-formed document would be\n // reported as unterminated.\n const openRegion = openRegions[openRegions.length - 1]\n if (openRegion !== undefined) {\n const endMatch = execAt(sticky(openRegion.rule.end), source, index)\n if (endMatch !== null && endMatch[0].length > 0) return true\n }\n for (const rule of rules) {\n if (!contextHolds(rule.when, index, previous)) continue\n if (rule.kind === 'region') {\n const match = execAt(sticky(rule.begin), source, index)\n if (match !== null && match[0].length > 0) return true\n continue\n }\n if (rule.kind === 'words') {\n if (matchWords(rule, resolveWords(rule.words), index) !== undefined) return true\n // A rule that reports what it rejects also claims what it rejects:\n // otherwise the word would be swallowed as plain text and the rejection\n // would never be reached.\n if (rule.unknown !== undefined && readWordRun(index) > index) return true\n continue\n }\n const match = execAt(sticky(rule.pattern), source, index)\n if (match !== null && match[0].length > 0) return true\n }\n return false\n }\n\n // ── the main loop ────────────────────────────────────────────────────────\n\n /** The regions currently open, innermost last. Only a nested region uses the stack. */\n const openRegions: Array<{\n rule: RegionRule<State>\n scope: Scope\n /** Where the opening delimiter was, so an unterminated region can be reported. */\n beginFrom: number\n beginTo: number\n }> = []\n\n let index = 0\n while (index < length) {\n const open = openRegions[openRegions.length - 1]\n\n if (open !== undefined) {\n // The region's own end is always what is tried first, whatever else the rule allows.\n const endMatch = execAt(sticky(open.rule.end), source, index)\n if (endMatch !== null && endMatch[0].length > 0) {\n const closeScope = scopeOf(\n open.rule.closeScope ?? open.rule.scope,\n ruleMatch(endMatch[0], index, [...endMatch]),\n open.scope,\n )\n push(closeScope, index, index + endMatch[0].length, open.scope)\n index += endMatch[0].length\n openRegions.pop()\n regionScope = openRegions[openRegions.length - 1]?.scope\n continue\n }\n\n // ── an opaque region recognises nothing but its own delimiters ───────\n // This is what makes a string a string: the word `running` inside a quoted name is\n // text, not a state. Nesting does NOT lift it — a comment that nests is still a\n // comment all the way down, and a language whose comments behave otherwise would be\n // one nobody could write a comment in.\n if (open.rule.transparent !== true) {\n if (open.rule.nested === true) {\n const inner = execAt(sticky(open.rule.begin), source, index)\n if (inner !== null && inner[0].length > 0) {\n const innerMatch = ruleMatch(inner[0], index, [...inner])\n push(\n scopeOf(open.rule.openScope ?? open.rule.scope, innerMatch, open.scope),\n index,\n index + inner[0].length,\n open.scope,\n )\n openRegions.push({\n rule: open.rule,\n scope: open.scope,\n beginFrom: index,\n beginTo: index + inner[0].length,\n })\n index += inner[0].length\n continue\n }\n }\n push(open.scope, index, index + 1, open.scope)\n index += 1\n continue\n }\n // A transparent region falls through: the rule list runs inside it, which is the\n // whole meaning of the flag.\n }\n\n let matched = false\n\n for (const rule of rules) {\n if (!contextHolds(rule.when, index, previousScope)) continue\n\n if (rule.kind === 'region') {\n const begin = execAt(sticky(rule.begin), source, index)\n if (begin === null || begin[0].length === 0) continue\n const beginMatch = ruleMatch(begin[0], index, [...begin])\n const scope = scopeOf(rule.scope, beginMatch, 'text')\n const openScope = scopeOf(rule.openScope ?? rule.scope, beginMatch, scope)\n const contentScope = scopeOf(rule.contentScope ?? rule.scope, beginMatch, scope)\n const closeScope = scopeOf(rule.closeScope ?? rule.scope, beginMatch, scope)\n const beginEnd = index + begin[0].length\n push(openScope, index, beginEnd, regionScope)\n\n // A region that only nests, or that is transparent, is tracked on the stack; the\n // stack is what its end is matched against, and what an unterminated one is reported\n // from. Everything else takes the fast path below.\n if (rule.nested === true || rule.transparent === true) {\n openRegions.push({ rule, scope: contentScope, beginFrom: index, beginTo: beginEnd })\n regionScope = contentScope\n index = beginEnd\n matched = true\n break\n }\n\n // The common case: find the end in one search rather than re-testing at\n // every character, and paint the whole middle as a single span.\n const close = findRegionEnd(rule.end, source, beginEnd)\n if (close === undefined) {\n // An unterminated region may be painted apart from a terminated one: `unclosed.scope`\n // is what lets a grammar say \"this is not a string, it is a broken string\", which is\n // the difference between a reader trusting the colours and being misled by them.\n push(\n scopeOf(rule.unclosed?.scope === undefined ? undefined : rule.unclosed.scope, beginMatch, contentScope),\n beginEnd,\n length,\n scope,\n )\n report({\n from: index,\n to: beginEnd,\n message:\n rule.unclosed?.message === undefined\n ? `Unterminated ${scope}.`\n : typeof rule.unclosed.message === 'function'\n ? rule.unclosed.message(beginMatch)\n : rule.unclosed.message,\n severity: rule.unclosed?.severity ?? 'error',\n code: rule.unclosed?.code ?? 'unclosed-region',\n })\n index = length\n matched = true\n break\n }\n push(contentScope, beginEnd, close.from, scope)\n push(closeScope, close.from, close.to, scope)\n index = close.to\n matched = true\n break\n }\n\n if (rule.kind === 'words') {\n const words = resolveWords(rule.words)\n const vocabulary = asResolvedVocabulary(rule.words)\n const hit = matchWords(rule, words, index)\n if (hit !== undefined) {\n const text = source.slice(index, hit.to)\n const match = ruleMatch(text, index, [text])\n const scope =\n rule.scope !== undefined\n ? scopeOf(rule.scope, match, 'word')\n : vocabulary?.scopeFor !== undefined\n ? vocabulary.scopeFor(hit.member)\n : 'word'\n push(scope, index, hit.to, regionScope)\n index = hit.to\n matched = true\n break\n }\n if (rule.unknown === undefined) continue\n // Only the first word is consumed. The scanner has no way to know how far\n // a name it has never seen was meant to reach, and guessing would swallow\n // the words that follow it; a multi-word name that is merely misspelled is\n // the grammar's validator's business, where the structure is known.\n const candidateTo = readWordRun(index)\n if (candidateTo <= index) continue\n const word = source.slice(index, candidateTo)\n const rejected = vocabulary?.reject?.(word, vocabularyContext)\n const message =\n rule.unknown.message === undefined\n ? rejected?.message\n : typeof rule.unknown.message === 'function'\n ? rule.unknown.message(word, ruleMatch(word, index, [word]))\n : rule.unknown.message\n .replace(/\\{word\\}/g, word)\n .replace(/\\{allowed\\}/g, listPhrase(words.list))\n push(rule.unknown.scope ?? vocabulary?.unknownScope ?? 'invalid', index, candidateTo, regionScope)\n if (message !== undefined) {\n report({\n from: index,\n to: candidateTo,\n message,\n severity: rule.unknown.severity ?? rejected?.severity ?? 'error',\n code: rule.unknown.code ?? rejected?.code ?? 'unknown-word',\n })\n }\n index = candidateTo\n matched = true\n break\n }\n\n const match = execAt(sticky(rule.pattern), source, index)\n if (match === null || match[0].length === 0) continue\n const matchInfo = ruleMatch(match[0], index, [...match])\n push(scopeOf(rule.scope, matchInfo, fallbackScope), index, index + match[0].length, regionScope)\n index += match[0].length\n matched = true\n break\n }\n\n if (matched) continue\n\n // ── nothing claimed this character ─────────────────────────────────────\n // A run of unclaimed characters is taken at once. Whitespace is by far the\n // most common thing no rule claims, and pushing it one character at a time\n // would be both slower and a great many spans.\n //\n // The run carries its own `previous`: once it has consumed a non-whitespace\n // character, the nearest preceding token is the run itself, not whatever came\n // before it. Without that, a rule guarded by `after` would be asked the wrong\n // question part way through and could let the run swallow a word it wanted.\n // Inside a nested region, a character no rule claims is still region content, so\n // it is painted with that region's scope rather than with the document fallback.\n const unclaimed = regionScope ?? fallbackScope\n let to = index\n let runPrevious = previousScope\n while (to < length) {\n const char = source.charAt(to)\n if (char === '\\n' || char === '\\r') break\n if (anyRuleClaims(to, runPrevious)) break\n if (/\\S/.test(char)) runPrevious = unclaimed\n to += 1\n }\n // `anyRuleClaims(index, ...)` is false here by construction, so this always\n // advances; the guard is against a rule list that disagrees with itself.\n push(unclaimed, index, Math.max(to, index + 1), regionScope)\n index = Math.max(to, index + 1)\n }\n\n // ── regions the document ended inside ───────────────────────────────────\n // A nested region is closed by the stack, not by a search, so running off the end of the\n // document leaves its frame open with nothing said. Reporting it here is the same fact\n // the opaque path reports when its search fails: a delimiter was opened and never closed.\n // Innermost first, because that is the one the reader has to fix first.\n for (let frame = openRegions.length - 1; frame >= 0; frame -= 1) {\n const open = openRegions[frame]\n if (open === undefined) continue\n const message =\n open.rule.unclosed?.message === undefined\n ? `Unterminated ${open.scope}.`\n : typeof open.rule.unclosed.message === 'function'\n ? open.rule.unclosed.message(ruleMatch('', open.beginFrom, ['']))\n : open.rule.unclosed.message\n report({\n from: open.beginFrom,\n to: open.beginTo,\n message,\n severity: open.rule.unclosed?.severity ?? 'error',\n code: open.rule.unclosed?.code ?? 'unclosed-region',\n })\n }\n\n return { tokens, diagnostics, state }\n}\n\n/**\n * Find a region's closing delimiter at or after a position.\n *\n * The search runs over the rest of the document rather than character by\n * character. The pattern is deliberately stripped of the sticky flag for this one\n * call: the end of a region is *searched for*, not anchored, which is the\n * difference between a string and a string that must begin exactly where the last\n * one ended.\n * @param pattern - the rule's `end` pattern.\n * @param source - the document.\n * @param from - where to start looking.\n * @returns the closing range, or undefined when the region never closes.\n */\nfunction findRegionEnd(\n pattern: RegExp,\n source: string,\n from: number,\n): { from: number; to: number } | undefined {\n const probe = new RegExp(pattern.source, `${pattern.flags.replace(/[gy]/g, '')}g`)\n probe.lastIndex = from\n const match = probe.exec(source)\n if (match === null || match[0].length === 0) return undefined\n return { from: match.index, to: match.index + match[0].length }\n}\n","// ─── inspect: the one call the editor makes per keystroke ───────────────────\n//\n// Everything the editor needs to know about a document is computed here, once,\n// from one grammar. The paint, the squiggles, the semantic decorations, and the\n// structural analysis come out of a single call and are stored together, so the\n// completion list and the coloured text cannot be looking at different documents.\n//\n// That is a deliberate inversion of how the editors this library replaces were\n// built. Each of them re-derived the tokens, the parse, and the suggestions\n// separately, from the same string, in three places — and the three drifted, so\n// a word could be painted as a valid value while the completer thought it was\n// unknown and the diagnostic pointed at a range that had already moved.\n\nimport type {\n CheckRule,\n Decoration,\n DiagnoseContext,\n Diagnostic,\n Grammar,\n Token,\n} from './types.js'\nimport { listPhrase } from './format.js'\nimport { isResolvedGrammar, resolveGrammar, scan, type ResolvedGrammar } from './scan.js'\nimport { resolveWordsSource } from './vocabulary.js'\n\n/** Everything one pass over a document produced. */\nexport interface Inspection<State = unknown> {\n /** The text this was computed from, kept so nothing has to guess its version. */\n text: string\n tokens: Token[]\n /** Lexical problems, the grammar's `checks`, and its `validate`, together. */\n diagnostics: Diagnostic[]\n /** Semantic ranges that are not tokens. */\n decorations: Decoration[]\n /** Whatever `Grammar.analyze` returned. */\n state: State\n}\n\n/**\n * Run a grammar's declarative checks over the tokens.\n *\n * A check is the shape most vocabulary mistakes actually take — \"this token is\n * one of these words or it is wrong\" — and expressing it declaratively means the\n * message, the severity, and the code are declared once instead of being\n * reassembled by hand at every site.\n * @param source - the document.\n * @param grammar - the resolved grammar.\n * @param tokens - the scanned tokens.\n * @param state - the analysis, so a check may consult a vocabulary the machine supplied.\n * @returns the diagnostics the checks raised.\n */\nfunction runChecks<State>(\n source: string,\n grammar: ResolvedGrammar<State>,\n tokens: readonly Token[],\n state: State,\n): Diagnostic[] {\n const checks = grammar.grammar.checks\n if (checks === undefined || checks.length === 0) return []\n const diagnostics: Diagnostic[] = []\n // The ANALYSIS, not `initialState`. A `WordsSource` function is documented as receiving\n // the grammar's analysis, and the point of a dynamic vocabulary is that it comes from\n // outside the document — so a check whose allowed set is resolved from `analyze` must\n // see it, or the two halves of one declaration would disagree about what is legal.\n const context = { text: source, state }\n\n for (const check of checks as readonly CheckRule<State>[]) {\n const members = check.allow === undefined ? undefined : resolveWordsSource(check.allow, context)\n const vocabulary = check.allow === undefined ? undefined : check.allow\n const caseSensitive =\n typeof vocabulary === 'object' && vocabulary !== null && !Array.isArray(vocabulary)\n ? (vocabulary as { caseSensitive?: boolean }).caseSensitive === true\n : false\n const fold = (word: string): string => (caseSensitive ? word : word.toLowerCase())\n const set =\n members === undefined ? undefined : new Set(members.map((member) => fold(member)))\n /** Lines already reported, for a check that only wants one complaint each. */\n const reportedLines = new Set<number>()\n\n for (const token of tokens) {\n // Whitespace is a token like any other, which means a check written against `'*'` would\n // otherwise underline every space and report it as a misspelling. No one has ever\n // wanted a diagnostic about a space.\n if (token.text.trim() === '') continue\n if (!check.scopes.includes('*') && !check.scopes.includes(token.scope)) continue\n if (check.except !== undefined && check.except.test(token.text)) continue\n if (set !== undefined && set.has(fold(token.text))) continue\n if (check.perLine === true) {\n if (reportedLines.has(token.line)) continue\n reportedLines.add(token.line)\n }\n diagnostics.push({\n from: token.from,\n to: token.to,\n severity: check.severity ?? 'error',\n message: check.message\n .replace(/\\{word\\}/g, token.text)\n .replace(/\\{allowed\\}/g, listPhrase(members ?? [])),\n code: check.code,\n detail: check.detail,\n source: grammar.grammar.id,\n })\n }\n }\n return diagnostics\n}\n\n/**\n * Inspect a document: paint, problems, decorations, and structure in one pass.\n * @param source - the document.\n * @param grammar - the language, as written or already resolved.\n * @returns everything the editor needs for one text.\n */\nexport function inspect<State>(\n source: string,\n grammar: Grammar<State> | ResolvedGrammar<State>,\n): Inspection<State> {\n const resolved = isResolvedGrammar(grammar) ? grammar : resolveGrammar(grammar)\n const scanned = scan(source, resolved)\n const declared = resolved.grammar\n const diagnostics: Diagnostic[] = [...scanned.diagnostics]\n\n diagnostics.push(...runChecks(source, resolved, scanned.tokens, scanned.state))\n\n if (declared.validate !== undefined) {\n const context: DiagnoseContext<State> = {\n text: source,\n tokens: scanned.tokens,\n state: scanned.state,\n report: (problem) => {\n diagnostics.push({\n from: problem.from,\n to: problem.to,\n severity: problem.severity ?? 'error',\n message: problem.message,\n code: problem.code ?? 'validate',\n detail: problem.detail,\n source: declared.id,\n })\n },\n }\n declared.validate(context)\n }\n\n const decorations = declared.decorate === undefined ? [] : [...declared.decorate(source, scanned.state)]\n\n return {\n text: source,\n tokens: scanned.tokens,\n diagnostics: normalizeDiagnostics(diagnostics),\n decorations: normalizeDecorations(decorations, source.length),\n state: scanned.state,\n }\n}\n\n/**\n * Sort diagnostics by position and drop duplicates.\n *\n * Two rules can legitimately notice the same mistake — a vocabulary's own\n * rejection and a grammar's validator both know that `nope` is not a colour —\n * and drawing the underline twice makes it darker rather than more informative.\n * Duplicates are compared on position, code, and message, so two genuinely\n * different complaints about one word both survive.\n * @param diagnostics - the collected diagnostics.\n * @returns the deduplicated, ordered list.\n */\nexport function normalizeDiagnostics(diagnostics: readonly Diagnostic[]): Diagnostic[] {\n const seen = new Set<string>()\n const out: Diagnostic[] = []\n for (const diagnostic of diagnostics) {\n const key = `${diagnostic.from}:${diagnostic.to}:${diagnostic.code ?? ''}:${diagnostic.message}`\n if (seen.has(key)) continue\n seen.add(key)\n out.push(diagnostic)\n }\n return out.sort((left, right) => left.from - right.from || left.to - right.to)\n}\n\n/**\n * Clamp decorations into the document and drop the ones that came out empty.\n *\n * A grammar computing decorations from a stale parse can hand over a range that\n * no longer exists, and a decoration outside the text would only produce a span\n * nobody can see.\n * @param decorations - the declared decorations.\n * @param length - the document's length.\n * @returns the usable decorations, ordered.\n */\nfunction normalizeDecorations(decorations: readonly Decoration[], length: number): Decoration[] {\n const out: Decoration[] = []\n for (const decoration of decorations) {\n const from = Math.max(0, Math.min(decoration.from, length))\n const to = Math.max(from, Math.min(decoration.to, length))\n if (to <= from) continue\n out.push({ ...decoration, from, to })\n }\n return out.sort((left, right) => left.from - right.from || left.to - right.to)\n}\n","// ─── segments: one pass over the document, for the painter ──────────────────\n//\n// The painted layer has to cover every character exactly once, in order, and it\n// has to do it while three independent things want to say something about those\n// characters: the scope that colours them, the decoration that marks them, and the\n// diagnostic that underlines them.\n//\n// The naive way is three layers, and it does not work. Each would have to position\n// its spans itself, so each would need its own idea of where a range starts, and a\n// span positioned by measuring is a span that drifts as soon as the font, the\n// wrapping, or the padding is even slightly different from what was measured.\n//\n// So they are merged into ONE stream of adjacent segments, and the renderer emits\n// them back to back with no positioning at all: the characters lay out where the\n// characters lay out, and the colours follow. Alignment stops being something the\n// code maintains and becomes something the layout cannot get wrong.\n//\n// This is pure — text and ranges in, segments out — which is why the trickiest\n// part of the painter is testable without a browser.\n\nimport type { Decoration, Diagnostic, Severity, Token } from './types.js'\n\n/** One run of characters that all share the same presentation. */\nexport interface PaintSegment {\n from: number\n to: number\n /** The characters themselves, so the painter never re-slices. */\n text: string\n /** The scope that colours them. */\n scope: string\n /** The decoration kinds that mark them, in declaration order. */\n decorations: string[]\n /** The loudest diagnostic covering them, when one does. */\n severity: Severity | undefined\n /** A hover title donated by a decoration, when it has one. */\n title: string | undefined\n}\n\n/** What a segment builder needs: the three range lists and nothing else. */\nexport interface SegmentInput {\n tokens: readonly Token[]\n decorations: readonly Decoration[]\n diagnostics: readonly Diagnostic[]\n}\n\n/**\n * The order severities outrank each other.\n *\n * One segment shows one squiggle, because two underlines on the same characters\n * only make a messier line rather than a more informative one. The loudest wins,\n * which is also the one a reader needs to see first.\n */\nconst SEVERITY_RANK: Record<Severity, number> = { error: 4, warning: 3, info: 2, hint: 1 }\n\n/**\n * Merge a scope, a decoration, and a diagnostic into adjacent segments.\n *\n * @param text - the document the ranges refer to.\n * @param input - the three range lists.\n * @param fallbackScope - the scope for characters no token covers.\n * @returns the segments, in order, covering the whole document.\n */\nexport function buildSegments(\n text: string,\n input: SegmentInput,\n fallbackScope = 'text',\n): PaintSegment[] {\n const length = text.length\n if (length === 0) return []\n\n // ── the cut points ────────────────────────────────────────────────────────\n // Every range boundary is a potential change of presentation, so they are the\n // only places a segment can begin or end.\n const cuts = new Set<number>([0, length])\n for (const token of input.tokens) {\n cuts.add(Math.max(0, Math.min(token.from, length)))\n cuts.add(Math.max(0, Math.min(token.to, length)))\n }\n for (const decoration of input.decorations) {\n cuts.add(Math.max(0, Math.min(decoration.from, length)))\n cuts.add(Math.max(0, Math.min(decoration.to, length)))\n }\n for (const diagnostic of input.diagnostics) {\n cuts.add(Math.max(0, Math.min(diagnostic.from, length)))\n cuts.add(Math.max(0, Math.min(diagnostic.to, length)))\n }\n const bounds = [...cuts].sort((left, right) => left - right)\n\n const segments: PaintSegment[] = []\n for (let index = 0; index < bounds.length - 1; index += 1) {\n const from = bounds[index] ?? 0\n const to = bounds[index + 1] ?? 0\n if (to <= from) continue\n\n const scope = coverScope(input.tokens, from, fallbackScope)\n const decorations = coverDecorations(input.decorations, from, to)\n const severity = coverSeverity(input.diagnostics, from, to)\n const title = input.decorations.find(\n (decoration) => decoration.title !== undefined && from >= decoration.from && to <= decoration.to,\n )?.title\n\n const last = segments[segments.length - 1]\n if (\n last !== undefined &&\n last.scope === scope &&\n last.severity === severity &&\n last.title === title &&\n sameList(last.decorations, decorations)\n ) {\n // Extending the previous segment keeps the DOM small without changing what\n // is drawn, which is the only reason the merge exists.\n last.to = to\n last.text = text.slice(last.from, to)\n continue\n }\n segments.push({ from, to, text: text.slice(from, to), scope, decorations, severity, title })\n }\n return segments\n}\n\n/** The scope of the token covering a position, or the fallback. */\nfunction coverScope(tokens: readonly Token[], offset: number, fallback: string): string {\n for (const token of tokens) {\n if (token.from > offset) break\n if (offset >= token.from && offset < token.to) return token.scope\n }\n return fallback\n}\n\n/** The decoration kinds covering a range, in the order they were declared. */\nfunction coverDecorations(decorations: readonly Decoration[], from: number, to: number): string[] {\n const kinds: string[] = []\n for (const decoration of decorations) {\n if (decoration.from <= from && to <= decoration.to) kinds.push(decoration.kind)\n }\n return kinds\n}\n\n/** The loudest diagnostic severity covering a range. */\nfunction coverSeverity(\n diagnostics: readonly Diagnostic[],\n from: number,\n to: number,\n): Severity | undefined {\n let loudest: Severity | undefined\n for (const diagnostic of diagnostics) {\n if (diagnostic.from > from || diagnostic.to < to) continue\n if (loudest === undefined || SEVERITY_RANK[diagnostic.severity] > SEVERITY_RANK[loudest]) {\n loudest = diagnostic.severity\n }\n }\n return loudest\n}\n\n/** Whether two short lists say the same thing, in the same order. */\nfunction sameList(left: readonly string[], right: readonly string[]): boolean {\n if (left.length !== right.length) return false\n for (let index = 0; index < left.length; index += 1) {\n if (left[index] !== right[index]) return false\n }\n return true\n}\n\n/**\n * The class attribute for a segment.\n *\n * Order matters for a stylesheet author's sanity rather than for the cascade: the\n * scope comes first so a rule can target `scope + mark` if it ever needs to.\n * @param segment - the segment.\n * @param scopeClass - how a scope becomes a class.\n * @param decorationClass - how a decoration kind becomes a class.\n * @param severityClass - how a severity becomes a class.\n * @returns the class list.\n */\nexport function segmentClasses(\n segment: PaintSegment,\n scopeClass: (scope: string) => string,\n decorationClass: (kind: string) => string,\n severityClass: (severity: string) => string,\n): string[] {\n const classes = [scopeClass(segment.scope)]\n for (const kind of segment.decorations) classes.push(decorationClass(kind))\n if (segment.severity !== undefined) classes.push(severityClass(segment.severity))\n return classes\n}\n","// ─── rank: how a completion list is ordered and filtered ────────────────────\n//\n// Two jobs that are easy to conflate and must not be. \"Which rows does this\n// needle match?\" is a filter, and a row either matches or does not. \"In what\n// order?\" is a ranking, and it is where the feel of a completer actually lives:\n// typing `inter` should put `Inter` above `Inter Tight` above `Plex Inter`, and\n// nothing about the matching itself decides that.\n//\n// The ranking is expressed as a TIER plus a local score rather than as one\n// arithmetic blend. A single blend is the classic mistake — add enough bonuses\n// and a longer subsequence eventually outscores an exact match, so the obvious\n// answer sinks below a coincidence — and it is also untestable, because no one\n// can say what the number 47.3 means. Tiers make the precedence a list you can\n// read and a set of cases you can assert:\n//\n// exact, case-sensitive `Inter` → `Inter`\n// exact, any case `inter` → `Inter`\n// prefix `inte` → `Inter`\n// word-boundary `fm` → `Fira Mono`, `IPM` → `IBM Plex Mono`\n// substring `lex` → `Plex Inter`\n// subsequence `jbmo` → `JetBrains Mono`\n//\n// Nothing here knows anything about any language. A needle and a label go in, a\n// score and the matched offsets come out, which is why this module has no import\n// of the grammar contract at all.\n\n/** The most of a score a local bonus may contribute, so a tier always dominates. */\nconst TIER_STRIDE = 1_000_000\n\n/**\n * The precedence tiers, highest first. The numbers are grades, not weights: a\n * tier only has to be larger than the one below it.\n */\nconst TIER = {\n /** The needle is the label, in the same case. */\n exact: 5,\n /** The needle is the label, ignoring case. */\n exactFold: 4,\n /** The label starts with the needle. */\n prefix: 3,\n /**\n * Every needle character either starts a word or continues one the match has\n * already started. This is what makes initials work: `fm` finds `Fira Mono` and\n * `IPM` finds `IBM Plex Mono`, without `IPM` being a substring of anything.\n */\n boundary: 2,\n /** The needle appears as one unbroken run inside the label. */\n substring: 1,\n /** The needle's characters appear in order, with gaps. */\n subsequence: 0,\n} as const\n\n/** Characters that make the character after them the start of a word. */\nconst SEPARATORS = /[\\s\\-_./:@()+[\\]]/\n\n/** A needle and the positions in the label it matched. */\nexport interface FuzzyMatch {\n /** The ranking score. Higher is a better match. */\n score: number\n /** The matched offsets into the label, ascending, for showing what matched. */\n indices: number[]\n /** The tier the match reached, for tests and for explaining a ranking. */\n tier: number\n}\n\n/**\n * Whether a position in a label starts a word.\n *\n * Three things start one: the beginning, a separator, and a lower-to-upper\n * transition. The third is what makes camelCase names searchable by their humps,\n * and it is why `NotoSans` and `Noto Sans` behave the same way under a needle\n * like `ns`.\n * @param label - the text being searched.\n * @param index - a position in it.\n * @returns whether a word starts there.\n */\nexport function isWordStart(label: string, index: number): boolean {\n if (index <= 0) return index === 0\n const previous = label.charAt(index - 1)\n if (SEPARATORS.test(previous)) return true\n const current = label.charAt(index)\n return previous === previous.toLowerCase() && current !== current.toLowerCase()\n}\n\n/** Whether a needle wants case-sensitive matching: it does when it has any uppercase. */\nfunction wantsExactCase(needle: string): boolean {\n return needle !== needle.toLowerCase()\n}\n\n/** A local bonus for a matched character. Never large enough to cross a tier. */\nfunction localScore(\n label: string,\n needle: string,\n indices: readonly number[],\n exactCase: boolean,\n): number {\n let score = 0\n for (let position = 0; position < indices.length; position += 1) {\n const index = indices[position]\n if (index === undefined) continue\n if (index === 0) score += 24\n else if (isWordStart(label, index)) score += 14\n if (position > 0 && index === (indices[position - 1] ?? -2) + 1) score += 10\n if (exactCase && label.charAt(index) === needle.charAt(position)) score += 4\n }\n const first = indices[0] ?? 0\n const last = indices[indices.length - 1] ?? 0\n // Gaps inside the matched span hurt, starting late hurts, and a short label\n // beats a long one that matched equally well — the same tie-break a reader\n // makes when two rows look alike.\n score -= (last - first + 1 - needle.length) * 1.5\n score -= first * 2\n score -= label.length * 0.05\n return score\n}\n\n/**\n * Match a needle against a label.\n *\n * Case follows the needle: a needle with an uppercase character is matched\n * case-sensitively, so `Inter` does not quietly match `inter`, while an\n * all-lowercase needle matches anything. That is the same \"smart case\" a\n * terminal has used for decades and the one VSCode applies.\n * @param needle - what the user has typed.\n * @param label - what is being searched.\n * @returns the score and matched offsets, or undefined when the needle does not match.\n */\nexport function fuzzyMatch(needle: string, label: string): FuzzyMatch | undefined {\n if (needle === '') return { score: 0, indices: [], tier: 0 }\n const exactCase = wantsExactCase(needle)\n const haystack = exactCase ? label : label.toLowerCase()\n const query = exactCase ? needle : needle.toLowerCase()\n\n // ── the cheap wins, in the order they should be believed ────────────────\n if (label === needle) {\n return { score: TIER.exact * TIER_STRIDE + localScore(label, needle, range(needle.length), true), indices: range(needle.length), tier: TIER.exact }\n }\n if (label.toLowerCase() === query) {\n const indices = range(needle.length)\n return {\n score: TIER.exactFold * TIER_STRIDE + localScore(label, needle, indices, exactCase),\n indices,\n tier: TIER.exactFold,\n }\n }\n if (haystack.startsWith(query)) {\n const indices = range(needle.length)\n return {\n score: TIER.prefix * TIER_STRIDE + localScore(label, needle, indices, exactCase),\n indices,\n tier: TIER.prefix,\n }\n }\n\n // ── the candidates ──────────────────────────────────────────────────────\n // A contiguous run is not automatically the best answer, which is why every\n // candidate is scored and the best one wins rather than the first one found.\n // `ns` against `notoSans` matches contiguously at the end and as two humps at the\n // start; only the second is what the typist meant, and a scorer that returned on\n // the first contiguous hit would never see it.\n let best: FuzzyMatch | undefined\n const consider = (candidate: FuzzyMatch): void => {\n if (best === undefined || candidate.score > best.score) best = candidate\n }\n\n for (let at = haystack.indexOf(query); at >= 0; at = haystack.indexOf(query, at + 1)) {\n const indices = range(needle.length, at)\n const tier = isWordStart(label, at) ? TIER.boundary : TIER.substring\n consider({ score: tier * TIER_STRIDE + localScore(label, needle, indices, exactCase), indices, tier })\n }\n\n // Every position the first character could have started at is tried, rather than\n // only the first one. Greedy-from-the-first-hit looks right and is wrong: `IPM`\n // against `IBM Plex Mono` would take the `P` of `Plex` and then fail to find an\n // `M`, when the `M` of `Mono` was available all along.\n for (let start = 0; start < haystack.length; start += 1) {\n if (haystack.charAt(start) !== query.charAt(0)) continue\n const indices: number[] = [start]\n let cursor = start + 1\n let complete = true\n for (let position = 1; position < query.length; position += 1) {\n const found = haystack.indexOf(query.charAt(position), cursor)\n if (found < 0) {\n complete = false\n break\n }\n indices.push(found)\n cursor = found + 1\n }\n if (!complete) continue\n // A match whose characters all start or continue a word reads as initials and\n // outranks one that merely happens to appear in order.\n const tier = indicesAreBoundaryish(label, indices) ? TIER.boundary : TIER.subsequence\n consider({ score: tier * TIER_STRIDE + localScore(label, needle, indices, exactCase), indices, tier })\n }\n return best\n}\n\n/**\n * Whether every matched position either starts a word or continues the run before it.\n * @param label - the searched text.\n * @param indices - the matched offsets.\n * @returns whether the match reads as initials rather than as scattered letters.\n */\nfunction indicesAreBoundaryish(label: string, indices: readonly number[]): boolean {\n for (let position = 0; position < indices.length; position += 1) {\n const index = indices[position]\n if (index === undefined) continue\n if (isWordStart(label, index)) continue\n if (position > 0 && index === (indices[position - 1] ?? -2) + 1) continue\n return false\n }\n return true\n}\n\n/** `[from, from + count)`, as an array. */\nfunction range(count: number, from = 0): number[] {\n const out: number[] = []\n for (let index = 0; index < count; index += 1) out.push(from + index)\n return out\n}\n\n/** One row of a ranked list, with the evidence for its position. */\nexport interface Ranked<T> {\n item: T\n score: number\n /** The offsets in the label that matched, for emphasising them in the list. */\n indices: number[]\n}\n\n/** How to read a row while ranking it. */\nexport interface RankOptions<T> {\n /** The text shown to the user. */\n label(item: T): string\n /** The text matched against the needle, when it differs from the label. */\n filterText?(item: T): string\n /**\n * The primary sort key, as VSCode's `sortText` is: rows are ordered by it\n * first and by match score only within an equal key. It is how a grammar puts\n * a whole group on top — the value already in effect, say — without pretending\n * its label starts with a `0`.\n */\n sortText?(item: T): string | undefined\n}\n\n/**\n * Filter and order rows for a needle.\n *\n * An empty needle keeps every row in the order the grammar declared, which is\n * what Ctrl+Space should show: the whole vocabulary, grouped the way the grammar\n * thinks about it, not alphabetised by a scorer that has nothing to go on.\n * @param items - the candidate rows.\n * @param needle - what the user has typed.\n * @param options - how to read a row.\n * @returns the matching rows, best first.\n */\nexport function rank<T>(items: readonly T[], needle: string, options: RankOptions<T>): Ranked<T>[] {\n const out: Ranked<T>[] = []\n for (const item of items) {\n if (needle === '') {\n out.push({ item, score: 0, indices: [] })\n continue\n }\n const label = options.label(item)\n const subject = options.filterText?.(item) ?? label\n const match = fuzzyMatch(needle, subject)\n if (match === undefined) continue\n // The offsets are only meaningful against the label, so a row matched on\n // different text is ranked without an emphasis rather than with the wrong one.\n out.push({ item, score: match.score, indices: subject === label ? match.indices : [] })\n }\n\n if (options.sortText === undefined) {\n // Sorting by score alone, on a stable sort, keeps the order the grammar\n // declared for everything the needle does not separate. That is load-bearing:\n // an empty needle must show a catalogue in catalogue order, and an alphabetical\n // tie-break would quietly rearrange a list the grammar had already ranked.\n out.sort((left, right) => right.score - left.score)\n return out\n }\n return out.sort((left, right) => {\n const leftKey = options.sortText?.(left.item) ?? options.label(left.item)\n const rightKey = options.sortText?.(right.item) ?? options.label(right.item)\n return leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : right.score - left.score\n })\n}\n\n/**\n * Split a label around the characters a needle matched, for the list to emphasise.\n *\n * Returned as segments rather than as a marked-up string because the caller is\n * building DOM nodes, not HTML: a font family called `<b>` must be shown as\n * `<b>`, and a completer that returns markup has to escape what it was given or\n * it is wrong about a real font.\n * @param label - the row's text.\n * @param indices - the matched offsets, ascending.\n * @returns alternating plain and matched segments, in order.\n */\nexport function highlightSegments(\n label: string,\n indices: readonly number[],\n): Array<{ text: string; matched: boolean }> {\n if (indices.length === 0) return label === '' ? [] : [{ text: label, matched: false }]\n const marked = new Set(indices)\n const segments: Array<{ text: string; matched: boolean }> = []\n let current: { text: string; matched: boolean } | undefined\n for (let index = 0; index < label.length; index += 1) {\n const matched = marked.has(index)\n if (current === undefined || current.matched !== matched) {\n if (current !== undefined) segments.push(current)\n current = { text: '', matched }\n }\n current.text += label.charAt(index)\n }\n if (current !== undefined) segments.push(current)\n return segments\n}\n","// ─── complete: turning a caret into a list, and a list into an edit ─────────\n//\n// Two pure functions, deliberately separated, because they fail in different\n// ways and only one of them is interesting to a user.\n//\n// `complete` answers \"what could go here?\" and returns rows. `applyCompletion`\n// answers \"what does the document become?\" and returns text plus a caret. Keeping\n// them apart is what makes the hard half — the interaction — testable in Node\n// without a browser, and it is why the two bugs that make a completer feel broken\n// have somewhere to live:\n//\n// A SOURCE that swaps mid-typing loses the thread. The list opens over a family\n// name, the user types `=` and it becomes a value list, and the row they were\n// looking at is gone. So once a source has answered, it keeps answering for as long\n// as it stays eligible, and the priority order only decides which source OPENS the\n// list.\n//\n// A range that does not grow leaves text behind. The range is recomputed from the\n// caret on every filter, never reused: type `ru`, accept `running`, and the\n// replacement must cover both letters. Holding the range resolved when the list\n// opened replaces only the `r` and produces `running u` — a bug worth naming,\n// because it is invisible in a test that only ever types one character before\n// accepting.\n\nimport type {\n Completion,\n CompletionContext,\n CompletionSource,\n CompletionTrigger,\n Grammar,\n Range,\n SuggestionItem,\n} from './types.js'\nimport type { Inspection } from './inspect.js'\nimport { rank, type Ranked } from './rank.js'\nimport { clamp, lineAt, lineStarts, scopeAt, tokenBefore, tokensOnLine, wordInfoAt } from './text.js'\nimport { isResolvedGrammar, resolveGrammar, type ResolvedGrammar } from './scan.js'\n\n/** The most rows a completion will carry, so a huge catalogue cannot stall a list. */\nconst DEFAULT_LIMIT = 100\n\n/** What the editor knows when it asks for a list. */\nexport interface CompletionRequest {\n text: string\n caret: number\n trigger: CompletionTrigger\n /**\n * The source that answered last time, when a list is already open.\n *\n * Passing it is what keeps a list stable while the user types: the same source answers\n * again for as long as it stays eligible, so typing a character that makes a different\n * source eligible does not swap the rows out from under the reader. Only the SOURCE is\n * held — the range is recomputed from the caret every time, so it grows with the word.\n */\n previousSourceId?: string | undefined\n /** The most rows to return. */\n limit?: number\n}\n\n/**\n * Resolve a completion for a caret.\n *\n * @param inspection - the current inspection of the document.\n * @param grammar - the language.\n * @param request - the caret, the trigger, and any list already open.\n * @returns the range and the rows, or undefined when nothing applies.\n */\nexport function complete<State>(\n inspection: Inspection<State>,\n grammar: Grammar<State> | ResolvedGrammar<State>,\n request: CompletionRequest,\n): Completion | undefined {\n const resolved = isResolvedGrammar(grammar) ? grammar : resolveGrammar(grammar)\n const sources = resolved.grammar.compose\n if (sources === undefined || sources.length === 0) return undefined\n\n const text = request.text\n const caret = clamp(request.caret, 0, text.length)\n const context = completionContext(inspection, resolved, caret, request.trigger)\n\n const eligible = sources.filter((source) => source.when === undefined || source.when(context))\n if (eligible.length === 0) return undefined\n\n // ── which source, and over what range ────────────────────────────────────\n // Ordered by priority, and the range comes from the winner because two sources\n // disagreeing about the range have no coherent shared answer.\n // ── which source ────────────────────────────────────────────────────────\n // Priority decides which source OPENS the list; after that the source that answered\n // keeps answering while it remains eligible, so the rows do not change identity under\n // the reader's hands. The range is not part of this: it is computed fresh below, from\n // the caret as it is now.\n const ordered = [...eligible].sort((left, right) => (right.priority ?? 0) - (left.priority ?? 0))\n const reopening =\n request.previousSourceId === undefined\n ? undefined\n : ordered.find((source) => source.id === request.previousSourceId)\n const winner = reopening ?? ordered[0]\n if (winner === undefined) return undefined\n const range = resolveRange(winner, context)\n\n // ── the rows ─────────────────────────────────────────────────────────────\n const merged: SuggestionItem[] = [...winner.items(context)]\n for (const source of ordered) {\n if (source === winner || source.merge !== true) continue\n merged.push(...source.items(context))\n }\n if (merged.length === 0) return undefined\n\n // The needle is what the user has typed INSIDE the range, which is the only reading\n // that stays meaningful when the range is an entry rather than a word. It is clamped\n // to the range at both ends: a caret can sit past the range — after the trailing space\n // of an entry, say — and slicing to the caret there would pull a separator into the\n // needle and filter the list by a character the user did not mean to search for.\n const needleFrom = clamp(range.from, 0, caret)\n const needleTo = clamp(caret, needleFrom, Math.max(range.to, needleFrom))\n const needle = text.slice(needleFrom, needleTo)\n const ranked: Ranked<SuggestionItem>[] = rank(merged, needle, {\n label: (item) => item.label,\n ...(merged.some((item) => item.filterText !== undefined)\n ? { filterText: (item: SuggestionItem) => item.filterText ?? item.label }\n : {}),\n ...(merged.some((item) => item.sortText !== undefined)\n ? { sortText: (item: SuggestionItem) => item.sortText }\n : {}),\n })\n const limit = request.limit ?? DEFAULT_LIMIT\n\n return {\n range,\n rows: ranked.slice(0, limit).map((entry) => ({\n item: entry.item,\n score: entry.score,\n indices: entry.indices,\n })),\n needle,\n sourceId: winner.id,\n }\n}\n\n/** Resolve a source's range, whether it declared one or computes it. */\nfunction resolveRange<State>(\n source: CompletionSource<State>,\n context: CompletionContext<State>,\n): Range {\n if (typeof source.range !== 'function') return source.range\n const range = source.range(context)\n return {\n from: Math.min(range.from, range.to),\n to: Math.max(range.from, range.to),\n }\n}\n\n/**\n * Build everything a completion source may look at.\n * @param inspection - the current inspection.\n * @param resolved - the resolved grammar.\n * @param caret - the caret offset.\n * @param trigger - how the list came to be open.\n * @returns the context.\n */\nfunction completionContext<State>(\n inspection: Inspection<State>,\n resolved: ResolvedGrammar<State>,\n caret: number,\n trigger: CompletionTrigger,\n): CompletionContext<State> {\n const { text, tokens, diagnostics, state } = inspection\n const line = lineAt(text, caret, lineStarts(text))\n const lineTokens = tokensOnLine(tokens, line.number)\n const word = wordInfoAt(text, caret, resolved.wordChars)\n return {\n text,\n caret,\n word,\n line,\n tokens,\n diagnostics,\n state,\n scope: scopeAt(tokens, caret),\n scopeBefore: tokenBefore(tokens, caret)?.scope,\n // \"First on line\" means only whitespace precedes the caret, which is a question\n // about the caret and not about the token under it: a caret in the indentation of\n // a line that already has content is not first on that line. `lineTokens` is what\n // tells the difference, so the tokens are read even though the answer looks like a\n // string test.\n firstOnLine: line.before.trim() === '' && !lineTokens.some((token) => token.to <= caret),\n // \"First word\" additionally allows the rest of the word the caret is in, which is\n // what keeps a line-head completion alive while the head is being typed.\n firstWord: line.text.slice(0, Math.max(0, word.from - line.from)).trim() === '',\n firstToken: lineTokens[0],\n trigger,\n }\n}\n\n/** An edit produced by accepting a row. */\nexport interface AppliedCompletion {\n /** The document after the edit. */\n text: string\n /** Where the caret belongs in it. */\n caret: number\n /**\n * What changed, in the NEW document. The editor uses it to scroll the result\n * into view and to describe the edit to a host.\n */\n range: Range\n /**\n * The offset the edit starts at in the ORIGINAL document.\n *\n * Exposed alongside `insert` because an editor must write only the range that\n * changed. Assigning the whole recomputed `text` would be simpler and would throw\n * away the browser's undo history, which is the one thing this library exists to\n * protect.\n */\n from: number\n /** The offset the edit ends at in the original document. */\n to: number\n /** The text written between those two offsets. */\n insert: string\n}\n\n/**\n * Apply a chosen row to a document.\n *\n * The row decides three things: what is written, whether it is written over the\n * range or in front of it, and how much text follows it. `append` is the\n * grammar's business and not the engine's — inviting another entry with a `, `\n * is a fact about font stacks, and an engine that appended one by default would\n * be guessing about every other language.\n *\n * @param text - the document.\n * @param range - the range the list was opened over.\n * @param item - the chosen row.\n * @returns the resulting text, caret, and the edit that produced them.\n */\nexport function applyCompletion(text: string, range: Range, item: SuggestionItem): AppliedCompletion {\n const from = clamp(Math.min(range.from, range.to), 0, text.length)\n const to = clamp(Math.max(range.from, range.to), from, text.length)\n const insert = item.insert ?? item.label\n const append = item.append ?? ''\n const offset = item.caretOffset ?? 0\n\n if (item.mode === 'before') {\n const head = text.slice(0, from)\n // The whitespace in front of the existing entry belonged to the comma before\n // it, so it is restored rather than doubled.\n const gap = head !== '' && !/\\s$/.test(head) ? ' ' : ''\n const rest = text.slice(from).replace(/^\\s+/, '')\n const written = `${gap}${insert}${redundant(append, rest) ? '' : append}`\n return {\n text: `${head}${written}${rest}`,\n caret: head.length + written.length + offset,\n range: { from: head.length, to: head.length + written.length },\n from,\n to: from,\n insert: written,\n }\n }\n\n const head = text.slice(0, from)\n const rest = text.slice(to)\n const written = `${insert}${redundant(append, rest) ? '' : append}`\n return {\n text: `${head}${written}${rest}`,\n caret: head.length + written.length + offset,\n range: { from: head.length, to: head.length + written.length },\n from,\n to,\n insert: written,\n }\n}\n\n/**\n * Whether an append would only repeat what the document already says.\n *\n * Accepting `running` immediately before an existing space must not produce two,\n * and accepting a font family immediately before an existing `, ` must not add\n * another comma. Whitespace is compared as whitespace rather than as the exact\n * characters, so a tab counts as the space an append was reaching for.\n * @param append - the row's `append` text.\n * @param rest - the document immediately after the range.\n * @returns whether the append should be left out.\n */\nfunction redundant(append: string, rest: string): boolean {\n if (append === '') return true\n return append.trim() === '' ? /^\\s/.test(rest) : rest.startsWith(append)\n}\n","// ─── hover: what the pointer is resting on ─────────────────────────────────\n//\n// A tooltip is only worth showing when it says something the text does not, and\n// there are exactly three things that qualify: a problem, a semantic mark the\n// grammar made, and the grammar's own explanation of a token. They are consulted\n// in that order and the first one that has something to say wins.\n//\n// A diagnostic leads deliberately. The other two describe what the text IS, and\n// the user resting the pointer on a red squiggle is asking what is WRONG with it\n// — answering \"circle: a full disc\" there would be technically true and useless,\n// and it is exactly the behaviour that makes people stop hovering.\n\nimport type { Decoration, Diagnostic, Grammar, HoverContext, HoverInfo, Severity } from './types.js'\nimport type { Inspection } from './inspect.js'\nimport { containsOffset, lineAt, lineStarts, tokenAt, wordInfoAt } from './text.js'\nimport { isResolvedGrammar, resolveGrammar, type ResolvedGrammar } from './scan.js'\n\n/** The word a severity is shown under, as VSCode titles its hovered diagnostics. */\nconst SEVERITY_TITLE: Record<Severity, string> = {\n error: 'Error',\n warning: 'Warning',\n info: 'Info',\n hint: 'Hint',\n}\n\n/**\n * Turn one diagnostic into a tooltip.\n *\n * Exported because a host that shows its own marker list wants the same wording,\n * and because a test should be able to assert the tooltip without going through\n * the ordering rules below.\n * @param diagnostic - the diagnostic.\n * @returns the tooltip.\n */\nexport function diagnosticHover(diagnostic: Diagnostic): HoverInfo {\n return {\n kind: 'diagnostic',\n title: SEVERITY_TITLE[diagnostic.severity],\n detail: diagnostic.source,\n body: diagnostic.detail === undefined ? diagnostic.message : `${diagnostic.message}\\n\\n${diagnostic.detail}`,\n range: { from: diagnostic.from, to: diagnostic.to },\n }\n}\n\n/**\n * Resolve what a hover should show at an offset.\n *\n * @param inspection - the current inspection.\n * @param grammar - the language.\n * @param offset - the character offset the pointer resolved to.\n * @returns the tooltip, or undefined when there is nothing to say.\n */\nexport function resolveHover<State>(\n inspection: Inspection<State>,\n grammar: Grammar<State> | ResolvedGrammar<State>,\n offset: number,\n): HoverInfo | undefined {\n const resolved = isResolvedGrammar(grammar) ? grammar : resolveGrammar(grammar)\n const { text, tokens, diagnostics, decorations, state } = inspection\n\n // ── a problem outranks a description ─────────────────────────────────────\n // The narrowest diagnostic wins when several overlap, so a squiggle inside a\n // wider warning still explains itself rather than its container.\n let covering: Diagnostic | undefined\n for (const diagnostic of diagnostics) {\n if (!containsOffset(diagnostic, offset)) continue\n if (covering === undefined || diagnostic.to - diagnostic.from < covering.to - covering.from) {\n covering = diagnostic\n }\n }\n if (covering !== undefined) return diagnosticHover(covering)\n\n // ── a mark the grammar made, combined with its own account of the token ──\n // Both, rather than one or the other. A decoration's title is short by design (\"in\n // effect: Geist Mono\") and the grammar's description is rich but says nothing about\n // the mark, so a tooltip that showed only one of them would always be missing the\n // half the reader wanted.\n const decoration: Decoration | undefined = decorations.find((entry) => containsOffset(entry, offset))\n const described = describeAt(inspection, resolved, offset)\n if (decoration?.title !== undefined) {\n return {\n kind: 'decoration',\n title: decoration.title,\n detail: described?.detail ?? described?.title,\n body: described?.body,\n range: { from: decoration.from, to: decoration.to },\n }\n }\n\n return described\n}\n\n/**\n * Ask the grammar what a token is.\n *\n * Split out because the decoration branch above wants the same answer and must not\n * build a second context for it — one parse, one description, however many tooltips\n * are made from it.\n * @param inspection - the current inspection.\n * @param resolved - the resolved grammar.\n * @param offset - the offset being described.\n * @returns the description, or undefined when the grammar has none.\n */\nfunction describeAt<State>(\n inspection: Inspection<State>,\n resolved: ResolvedGrammar<State>,\n offset: number,\n): HoverInfo | undefined {\n if (resolved.grammar.describe === undefined) return undefined\n const { text, tokens, diagnostics, state } = inspection\n const found = tokenAt(tokens, offset)\n // Whitespace is painted like anything else, so a token IS found in blank space — and a\n // grammar handed one will describe it, which is how resting the pointer on a gap produced a\n // tooltip naming the fallback scope. There is no thing under the pointer to explain, so the\n // grammar is told there is no token; a grammar that wants to say something about the\n // POSITION can still do so, because `describe` is called either way.\n const token = found === undefined || found.text.trim() === '' ? undefined : found\n const context: HoverContext<State> = {\n text,\n offset,\n token,\n word: wordInfoAt(text, offset, resolved.wordChars),\n line: lineAt(text, offset, lineStarts(text)),\n tokens,\n diagnostics,\n state,\n }\n return resolved.grammar.describe(context) ?? undefined\n}\n","// ─── grammar: the two identity functions authors actually want ──────────────\n//\n// Neither does anything at runtime, and that is not a joke at the reader's\n// expense: `defineGrammar` exists so `State` is inferred from `analyze` and then\n// enforced everywhere else. Written as a bare object literal, a grammar whose\n// `analyze` returns `{ entries: Entry[] }` would have every hook's `context.state`\n// typed as `unknown`, and the author would spend the afternoon casting.\n//\n// const grammar = defineGrammar({\n// id: 'my-language',\n// rules: [...],\n// analyze: (text) => ({ lines: text.split('\\n') }), // State is inferred\n// compose: [{\n// id: 'values',\n// range: (context) => ({ from: 0, to: context.caret }),\n// items: (context) => context.state.lines.map(...), // typed, not cast\n// }],\n// })\n\nimport type { CompletionSource, Grammar } from './types.js'\n\n/**\n * Declare a grammar, inferring its state type from `analyze`.\n * @param grammar - the grammar.\n * @returns the same grammar, typed.\n */\nexport function defineGrammar<State = unknown>(grammar: Grammar<State>): Grammar<State> {\n return grammar\n}\n\n/**\n * Declare a completion source, inferring the state type from its context.\n * @param source - the source.\n * @returns the same source, typed.\n */\nexport function defineCompletion<State = unknown>(\n source: CompletionSource<State>,\n): CompletionSource<State> {\n return source\n}\n","// ─── styles: the one stylesheet ─────────────────────────────────────────────\n//\n// The CSS lives in a TypeScript string so it can be injected with no build step\n// and no CSS loader, which is what keeps the library usable from a plain script\n// tag. `scripts/build-css.mjs` also writes it out as `dist/styles.css` for the\n// hosts that would rather link it, from this same string, so the two can never\n// disagree.\n//\n// The alignment contract\n// ----------------------\n// The painted layer sits behind the real textarea and draws the same characters, so it may\n// change only what does not move a glyph: colour, background, and text-decoration. Anything\n// that changes an advance — a different font, a weight, letter-spacing, a font-feature —\n// slides the paint off the character it belongs to, and by a different amount on every\n// character, so it reads as a rendering glitch rather than as a styling mistake.\n//\n// The two elements therefore share ONE rule for their typography, and that rule is the only\n// thing that has to hold. THE FONT ITSELF IS THE HOST'S CHOICE: a proportional face aligns just\n// as well as a monospace one, because the layer, the field, and the measuring mirror all read\n// the same computed font. `--litearea-font` is a variable like any other.\n//\n// What is NOT the host's choice is ligatures and kerning, which are forced off, and the reason\n// is subtler than \"a ligature would look wrong\". A ligature draws one glyph where the field\n// holds two characters — and the layer splits its spans wherever a diagnostic or a decoration\n// begins, which cuts a ligature in half. The field would then render one glyph and the layer\n// two, at different widths, and the rest of the line would slide. Turning them off removes the\n// possibility rather than relying on no span boundary ever landing inside a pair.\n\n/**\n * One colour per scope, in one list, because the variables and the rules that use them MUST\n * agree and once did not.\n *\n * Twenty-nine scope variables were declared here with no rule anywhere that consumed them. The\n * tokenizer painted the right classes, the variables were documented, the stylesheet looked\n * complete — and every scope rendered in the inherited text colour, so the editor had no syntax\n * colouring at all. Nothing in the DOM revealed it: the spans were correct. Generating both\n * halves from this list is the fix, and it is the kind of drift a browser check cannot catch\n * either, since a colourless token is a perfectly ordinary thing to find.\n *\n * A key is the FOLDED scope name, which is what a scope becomes as a class: `value.shape` is\n * written `value-shape` here because `scopeClass` turns its dots into hyphens.\n */\nconst SCOPE_PALETTE: ReadonlyArray<{ scope: string; light: string; dark?: string }> = [\n { scope: 'text', light: 'var(--litearea-fg)' },\n { scope: 'word', light: 'var(--litearea-fg)' },\n { scope: 'family', light: 'var(--litearea-fg)' },\n { scope: 'family-generic', light: '#7c3aed', dark: '#c4a2ff' },\n { scope: 'family-unknown', light: 'var(--litearea-warning)' },\n { scope: 'family-unclosed', light: 'var(--litearea-error)' },\n { scope: 'weight', light: 'var(--litearea-accent)' },\n { scope: 'weight-missing', light: 'var(--litearea-warning)' },\n { scope: 'state', light: 'var(--litearea-accent)' },\n { scope: 'property', light: '#7c3aed', dark: '#c4a2ff' },\n { scope: 'operator', light: 'var(--litearea-fg-dim)' },\n { scope: 'separator', light: 'var(--litearea-fg-dim)' },\n { scope: 'value-shape', light: '#0f766e', dark: '#5eead4' },\n { scope: 'value-color', light: '#0f766e', dark: '#5eead4' },\n { scope: 'value-pattern', light: '#0f766e', dark: '#5eead4' },\n { scope: 'value-motion', light: '#0f766e', dark: '#5eead4' },\n { scope: 'value-number', light: '#b45309', dark: '#fbbf24' },\n { scope: 'comment', light: 'var(--litearea-fg-dim)' },\n { scope: 'invalid', light: 'var(--litearea-error)' },\n { scope: 'keyword', light: 'var(--litearea-accent)' },\n { scope: 'string', light: '#0f766e', dark: '#5eead4' },\n { scope: 'number', light: '#b45309', dark: '#fbbf24' },\n]\n\n/**\n * The variable declarations for one colour scheme.\n * @param scheme - `light` declares every scope; `dark` declares only those that differ.\n * @returns one CSS declaration per line.\n */\nfunction scopeVariables(scheme: 'light' | 'dark'): string {\n return SCOPE_PALETTE.filter((entry) => scheme === 'light' || entry.dark !== undefined)\n .map((entry) => {\n const value = scheme === 'light' ? entry.light : entry.dark\n return ` --litearea-scope-${entry.scope}: ${String(value)};`\n })\n .join('\\n')\n}\n\n/**\n * The rules that spend those variables.\n * @returns one CSS rule per line.\n */\nfunction scopeRules(): string {\n return SCOPE_PALETTE.map(\n (entry) =>\n `.litearea-scope-${entry.scope} { color: var(--litearea-scope-${entry.scope}); }`,\n ).join('\\n')\n}\n\n/** Everything a scope or a mark is painted with comes from one of these. */\nexport const LITEAREA_STYLES = `\n.litearea {\n --litearea-font: ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace;\n --litearea-font-size: 13px;\n --litearea-line-height: 20px;\n --litearea-padding-block: 6px;\n --litearea-padding-inline: 10px;\n --litearea-radius: 8px;\n --litearea-fg: #1f2328;\n --litearea-fg-dim: #6b7280;\n --litearea-fg-strong: #111827;\n --litearea-bg: #ffffff;\n --litearea-bg-raised: #ffffff;\n --litearea-border: #d8dbe0;\n --litearea-border-focus: #4d6bfe;\n --litearea-accent: #4d6bfe;\n --litearea-accent-soft: rgba(77, 107, 254, 0.12);\n --litearea-selection: rgba(77, 107, 254, 0.22);\n --litearea-error: #e5484d;\n --litearea-warning: #d97706;\n --litearea-info: #4d6bfe;\n --litearea-hint: #8b8f97;\n --litearea-shadow: 0 6px 24px rgba(15, 23, 42, 0.14);\n\n${scopeVariables('light')}\n\n position: relative;\n display: block;\n color: var(--litearea-fg);\n}\n\n@media (prefers-color-scheme: dark) {\n .litearea {\n --litearea-fg: #e6e8eb;\n --litearea-fg-dim: #8b919b;\n --litearea-fg-strong: #ffffff;\n --litearea-bg: #1b1e24;\n --litearea-bg-raised: #23262c;\n --litearea-border: #363b44;\n${scopeVariables('dark')}\n --litearea-error: #ff6b6b;\n --litearea-warning: #f59e0b;\n --litearea-shadow: 0 6px 24px rgba(0, 0, 0, 0.5);\n }\n}\n\n/* ── the box ─────────────────────────────────────────────────────────────── */\n\n.litearea-box {\n position: relative;\n display: block;\n border: 1px solid var(--litearea-border);\n border-radius: var(--litearea-radius);\n background: var(--litearea-bg);\n transition: border-color 120ms ease;\n}\n\n.litearea-box:focus-within {\n border-color: var(--litearea-border-focus);\n}\n\n.litearea-invalid .litearea-box {\n border-color: var(--litearea-error);\n}\n\n/*\n * The layer and the field share this rule and nothing may be added to one alone.\n * Every property here is a property the mirror copies too — three elements, one\n * typography, or the paint drifts.\n */\n.litearea-layer,\n.litearea-input {\n box-sizing: border-box;\n width: 100%;\n margin: 0;\n padding: var(--litearea-padding-block) var(--litearea-padding-inline);\n border: none;\n font-family: var(--litearea-font);\n font-size: var(--litearea-font-size);\n font-weight: 400;\n font-style: normal;\n font-stretch: normal;\n font-variant-ligatures: none;\n font-kerning: none;\n font-feature-settings: \"liga\" 0, \"calt\" 0, \"dlig\" 0;\n line-height: var(--litearea-line-height);\n letter-spacing: normal;\n word-spacing: normal;\n text-transform: none;\n text-indent: 0;\n text-align: left;\n direction: ltr;\n tab-size: 2;\n white-space: pre-wrap;\n overflow-wrap: break-word;\n word-break: break-word;\n}\n\n.litearea-layer {\n position: absolute;\n inset: 0;\n overflow: hidden;\n pointer-events: none;\n user-select: none;\n}\n\n/*\n * When the box is clamped to its maximum height the field grows a scrollbar, and a\n * scrollbar narrows the text. If the layer kept the full width it would wrap\n * differently from the field and every colour would slide off its character, so the\n * field's measured scrollbar width is published as --litearea-scrollbar and added\n * here. The value is 0 whenever no scrollbar is shown.\n */\n.litearea-layer {\n padding-right: calc(var(--litearea-padding-inline) + var(--litearea-scrollbar, 0px));\n}\n\n.litearea-paint {\n position: relative;\n min-height: 100%;\n /* A zero-width space keeps the layer's last line box as tall as the field's:\n a trailing newline would otherwise collapse in the paint alone, and the box\n would jump the moment one was typed. */\n will-change: transform;\n}\n\n.litearea-input {\n position: relative;\n display: block;\n resize: none;\n background: transparent;\n color: transparent;\n caret-color: var(--litearea-fg);\n outline: none;\n overflow-y: hidden;\n}\n\n.litearea-growable .litearea-input {\n resize: none;\n}\n\n.litearea-resizable .litearea-input {\n resize: vertical;\n}\n\n.litearea-input::placeholder {\n color: var(--litearea-fg-dim);\n}\n\n.litearea-input::selection {\n background: var(--litearea-selection);\n}\n\n.litearea-readonly .litearea-input {\n caret-color: transparent;\n}\n\n/*\n * The rules that spend the variables, generated from the same list that declares them. There is\n * deliberately NO catch-all rule setting a property on every painted span: there was one, and a\n * class plus an element outranks a bare class on specificity, so it silently switched off every\n * squiggle in the library.\n *\n * A scope that is not in the list gets no colour from here, and a host writing a grammar of its\n * own styles it with a plain rule — .litearea-scope-my-thing { color: … } — since nothing in\n * this file competes for that selector.\n */\n${scopeRules()}\n\n.litearea-dec-effective {\n border-radius: 3px;\n background: var(--litearea-accent-soft);\n box-shadow: 0 0 0 1px var(--litearea-accent-soft);\n}\n\n/* The four shapes a diagnostic can take. Wavy for the two that mean \"fix this\", dotted for\n the two that mean \"worth knowing\" — the same distinction VSCode draws, and the reason\n severity is a class rather than an inline colour. */\n.litearea-diag-error {\n text-decoration-line: underline;\n text-decoration-style: wavy;\n text-decoration-color: var(--litearea-error);\n text-decoration-skip-ink: none;\n text-underline-offset: 3px;\n}\n\n.litearea-diag-warning {\n text-decoration-line: underline;\n text-decoration-style: wavy;\n text-decoration-color: var(--litearea-warning);\n text-decoration-skip-ink: none;\n text-underline-offset: 3px;\n}\n\n.litearea-diag-info {\n text-decoration-line: underline;\n text-decoration-style: dotted;\n text-decoration-color: var(--litearea-info);\n text-decoration-skip-ink: none;\n text-underline-offset: 3px;\n}\n\n.litearea-diag-hint {\n text-decoration-line: underline;\n text-decoration-style: dotted;\n text-decoration-color: var(--litearea-hint);\n text-decoration-skip-ink: none;\n text-underline-offset: 3px;\n}\n\n/* ── the completion list ─────────────────────────────────────────────────── */\n\n/*\n * The container holds two things and scrolls NEITHER of them: the list scrolls itself, and the\n * documentation is pinned below it. Putting the documentation inside the scroll range — which is\n * what this used to do — makes it unreachable with a long list and a long explanation: the\n * arrows move the active row rather than the scrollbar, so a keyboard user never sees it, and a\n * mouse user has to scroll down to read it and back up to reach the next row.\n */\n.litearea-popup {\n position: absolute;\n z-index: 30;\n display: none;\n flex-direction: column;\n max-width: 460px;\n padding: 4px;\n border: 1px solid var(--litearea-border);\n border-radius: 10px;\n background: var(--litearea-bg-raised);\n box-shadow: var(--litearea-shadow);\n font-family: var(--litearea-font);\n font-size: 12px;\n line-height: 18px;\n color: var(--litearea-fg);\n overflow: hidden;\n}\n\n.litearea-popup[data-open=\"true\"] {\n display: flex;\n}\n\n/* The rows, and the only part that scrolls. Its height is bounded so the documentation below\n always has somewhere to live. */\n.litearea-list {\n min-height: 0;\n max-height: 208px;\n overflow-y: auto;\n}\n\n/*\n * The explanation, pinned. Its own height is bounded and it scrolls ITSELF, so a long\n * explanation stays readable while the rows stay put — and arrowing to the next row swaps the\n * text in place instead of requiring a scroll back up.\n */\n.litearea-docs {\n flex: none;\n max-height: 132px;\n overflow-y: auto;\n margin: 4px -4px -4px;\n padding: 6px 10px;\n border-top: 1px solid var(--litearea-border);\n background: var(--litearea-bg);\n border-radius: 0 0 10px 10px;\n color: var(--litearea-fg);\n white-space: pre-wrap;\n}\n\n.litearea-popup[data-docs=\"false\"] .litearea-docs {\n display: none;\n}\n\n.litearea-row {\n display: flex;\n align-items: baseline;\n gap: 8px;\n padding: 3px 6px;\n border-radius: 6px;\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n}\n\n.litearea-row[aria-selected=\"true\"] {\n background: var(--litearea-accent-soft);\n}\n\n.litearea-rowKind {\n flex: none;\n width: 7px;\n height: 7px;\n border-radius: 2px;\n background: var(--litearea-fg-dim);\n transform: translateY(-1px);\n}\n\n.litearea-kind-family { background: var(--litearea-scope-family-generic); }\n.litearea-kind-generic { background: var(--litearea-scope-family-generic); }\n.litearea-kind-weight { background: var(--litearea-scope-weight); }\n.litearea-kind-state { background: var(--litearea-scope-state); }\n.litearea-kind-property { background: var(--litearea-scope-property); }\n.litearea-kind-value { background: var(--litearea-scope-value-shape); }\n.litearea-kind-number { background: var(--litearea-scope-value-number); }\n.litearea-kind-custom { background: var(--litearea-fg-dim); }\n\n.litearea-rowLabel {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.litearea-rowMatch {\n color: var(--litearea-accent);\n font-weight: 600;\n}\n\n.litearea-rowDetail {\n flex: none;\n color: var(--litearea-fg-dim);\n font-size: 11px;\n}\n\n.litearea-docsTitle {\n font-weight: 600;\n}\n\n.litearea-docsDetail {\n color: var(--litearea-fg-dim);\n}\n\n.litearea-docsBody {\n margin-top: 2px;\n color: var(--litearea-fg-dim);\n}\n\n/* ── the hover tooltip ───────────────────────────────────────────────────── */\n\n.litearea-tooltip {\n position: absolute;\n z-index: 40;\n display: none;\n max-width: 340px;\n padding: 6px 10px;\n border: 1px solid var(--litearea-border);\n border-radius: 8px;\n background: var(--litearea-bg-raised);\n box-shadow: var(--litearea-shadow);\n font-family: var(--litearea-font);\n font-size: 11px;\n line-height: 16px;\n color: var(--litearea-fg);\n pointer-events: none;\n white-space: pre-wrap;\n}\n\n.litearea-tooltip[data-open=\"true\"] {\n display: block;\n}\n\n.litearea-tooltipTitle {\n font-weight: 600;\n}\n\n.litearea-tooltipDetail {\n color: var(--litearea-fg-dim);\n}\n\n.litearea-tooltipBody {\n margin-top: 3px;\n color: var(--litearea-fg-dim);\n}\n\n.litearea-srOnly {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n`.trim()\n\n/**\n * Put the stylesheet in a document, once.\n *\n * Marked with a data attribute so two editors on one page, or two copies of the\n * library, do not stack two identical sheets — and so a host can find and replace\n * it.\n * @param ownerDocument - the document to install into.\n * @param nonce - an optional CSP nonce for the style element.\n * @returns the style element, or undefined when there is no document.\n */\nexport function injectStyles(\n ownerDocument: Document,\n nonce?: string,\n): HTMLStyleElement | undefined {\n if (ownerDocument === null || ownerDocument === undefined) return undefined\n const existing = ownerDocument.querySelector<HTMLStyleElement>('style[data-litearea-styles]')\n if (existing !== null) return existing\n const style = ownerDocument.createElement('style')\n style.dataset.liteareaStyles = ''\n if (nonce !== undefined) style.nonce = nonce\n style.textContent = LITEAREA_STYLES\n const head = ownerDocument.head ?? ownerDocument.documentElement\n if (head === null || head === undefined) return undefined\n head.appendChild(style)\n return style\n}\n\n/**\n * The class a scope is painted with.\n *\n * Dots and other punctuation are folded to hyphens, because a scope like\n * `value.shape` is a nice name to write and a terrible one to select: the CSS\n * would need a backslash before the dot at every use, and one forgotten escape\n * silently paints nothing.\n * @param scope - the scope name.\n * @returns the class name.\n */\nexport function scopeClass(scope: string): string {\n const folded = scope.replace(/[^A-Za-z0-9_-]+/g, '-').replace(/^-+|-+$/g, '')\n return folded === '' ? 'litearea-scope-text' : `litearea-scope-${folded}`\n}\n\n/** The class a decoration kind is painted with. */\nexport function decorationClass(kind: string): string {\n return `litearea-dec-${kind.replace(/[^A-Za-z0-9_-]+/g, '-')}`\n}\n\n/** The class a diagnostic severity is underlined with. */\nexport function severityClass(severity: string): string {\n return `litearea-diag-${severity.replace(/[^A-Za-z0-9_-]+/g, '-')}`\n}\n","// ─── support: what this browser can actually do ─────────────────────────────\n//\n// The engine is pure and needs nothing. This module is the only place that asks\n// the environment a question, so the answer is in one place and the rest of the\n// DOM layer can assume it.\n\n/** Whether a document is available at all, so an import is safe under Node. */\nexport function hasDocument(): boolean {\n return typeof document !== 'undefined' && document !== null\n}\n\n/**\n * Whether the browser still offers `document.execCommand`.\n *\n * It is deprecated, and it is also the only way to change a textarea's value while\n * keeping the browser's own undo stack intact — no modern input API can be driven\n * from script, because a synthetic event is untrusted and the browser refuses to\n * treat it as a user edit. So the check is not \"is this nice API available\" but\n * \"can this edit be undone\", and the editor degrades honestly when the answer is\n * no: the edit still lands, and the history it should have joined does not.\n * @returns whether an undo-preserving edit is possible.\n */\nexport function canEditThroughPipeline(): boolean {\n return hasDocument() && typeof document.execCommand === 'function'\n}\n\n/** Whether `caretPositionFromPoint` or its WebKit spelling exists. */\nexport function hasCaretHitTest(): boolean {\n if (!hasDocument()) return false\n const probe = document as Document & {\n caretPositionFromPoint?: unknown\n caretRangeFromPoint?: unknown\n }\n return (\n typeof probe.caretPositionFromPoint === 'function' ||\n typeof probe.caretRangeFromPoint === 'function'\n )\n}\n\n/**\n * The character offset a point in the viewport falls on, according to the browser.\n *\n * The browser is asked rather than the editor computing it, because hit-testing\n * wrapped, proportional text is exactly the kind of geometry a hand-written\n * measurement gets subtly wrong. A textarea's transparent text still lays out\n * normally, so the caret APIs answer for it correctly.\n * @param x - viewport x.\n * @param y - viewport y.\n * @returns the offset, or undefined when the browser cannot say.\n */\nexport function offsetFromPoint(x: number, y: number): number | undefined {\n if (!hasDocument()) return undefined\n const probe = document as Document & {\n caretPositionFromPoint?: (x: number, y: number) => { offsetNode: Node; offset: number } | null\n caretRangeFromPoint?: (x: number, y: number) => Range | null\n }\n if (typeof probe.caretPositionFromPoint === 'function') {\n const position = probe.caretPositionFromPoint(x, y)\n if (position !== null && position !== undefined) return position.offset\n return undefined\n }\n if (typeof probe.caretRangeFromPoint === 'function') {\n const range = probe.caretRangeFromPoint(x, y)\n if (range !== null && range !== undefined) return range.startOffset\n }\n return undefined\n}\n\n/**\n * Merge partial option objects without letting an explicit `undefined` win.\n *\n * `{ ...defaults, ...given }` looks right and is wrong the moment a caller passes\n * an optional field it did not fill in: the key exists, so it overwrites the\n * default with `undefined`, and the editor then behaves as if the option had been\n * switched off. This copies only the keys that were actually provided.\n * @param defaults - the base.\n * @param given - the overrides, which may be undefined.\n * @returns the merged object.\n */\nexport function withDefaults<T extends object>(defaults: T, given: Partial<T> | undefined): T {\n if (given === undefined) return { ...defaults }\n const merged = { ...defaults }\n for (const key of Object.keys(given) as Array<keyof T>) {\n const value = given[key]\n if (value !== undefined) merged[key] = value as T[keyof T]\n }\n return merged\n}\n","// ─── editing: changing a textarea without breaking its history ──────────────\n//\n// This is the module the whole library exists to get right.\n//\n// A textarea owns its own undo stack, and that stack is maintained by the\n// browser's editing pipeline — not by the value property. Assigning to\n// `field.value` replaces the text and DESTROYS the history, which is why a\n// controlled component that round-trips every keystroke through React state (or a\n// state setter of any kind) has no working Ctrl+Z. It also resets the caret to the\n// end, which is the other half of the same mistake.\n//\n// So the editor never writes `value` for an edit the user could have made. It\n// moves the selection and asks the browser to insert text, which the browser\n// records as one undoable edit:\n//\n// field.setSelectionRange(from, to)\n// document.execCommand('insertText', false, text) // ← undoable\n//\n// `execCommand` is deprecated, and there is no replacement. A synthetic\n// `beforeinput` or `InputEvent` is untrusted, so the browser will not run it\n// through the editing pipeline; `setRangeText` is the standard API and bypasses\n// the history entirely. Every editor that supports undo on a textarea uses this\n// call. Where it is missing the edit still happens through `setRangeText`, and the\n// caller is told plainly that the history did not get it, so a host can decide\n// whether that matters.\n\nimport { clamp } from '../core/text.js'\nimport { canEditThroughPipeline } from './support.js'\n\n/** A caret or selection, as offsets into the value. */\nexport interface TextSelection {\n /** The anchor end. Equal to `end` for a caret. */\n start: number\n /** The moving end. */\n end: number\n}\n\n/**\n * How an edit reached the document.\n *\n * `pipeline` means the browser recorded it and Ctrl+Z will undo it. `direct` means\n * the text changed and the history did not, which only happens where\n * `document.execCommand` is unavailable — a test environment, or a browser that\n * has finally removed it.\n */\nexport type EditOutcome = 'pipeline' | 'direct' | 'unchanged'\n\n/** Read the caret or selection out of a field. */\nexport function readSelection(field: HTMLTextAreaElement): TextSelection {\n const start = field.selectionStart ?? 0\n const end = field.selectionEnd ?? start\n return { start, end }\n}\n\n/**\n * Put a caret or selection into a field.\n *\n * Setting a selection moves the caret and nothing else: it does not touch the\n * value, so it cannot disturb the undo stack. This is what the editor uses instead\n * of re-rendering text to reposition the caret — the re-render was the bug.\n *\n * A range given the wrong way round is ordered rather than collapsed. `start` and\n * `end` are named for a caret and a selection, and a caller that computes them from a\n * backwards drag has still asked for that text to be selected; quietly selecting\n * nothing at the far end would be a silent wrong answer.\n * @param field - the textarea.\n * @param start - the anchor offset.\n * @param end - the moving offset; defaults to `start`.\n */\nexport function writeSelection(\n field: HTMLTextAreaElement,\n start: number,\n end: number = start,\n): void {\n const length = field.value.length\n const from = clamp(Math.min(start, end), 0, length)\n const to = clamp(Math.max(start, end), from, length)\n field.setSelectionRange(from, to)\n}\n\n/** The line height in force on a field, falling back to the computed font size. */\nexport function fieldLineHeight(field: HTMLTextAreaElement): number {\n const styles = field.ownerDocument.defaultView?.getComputedStyle(field)\n if (styles === null || styles === undefined) return 0\n const lineHeight = Number.parseFloat(styles.lineHeight)\n if (Number.isFinite(lineHeight)) return lineHeight\n const fontSize = Number.parseFloat(styles.fontSize)\n return Number.isFinite(fontSize) ? fontSize * 1.2 : 0\n}\n\n/**\n * Replace a range through the browser's editing pipeline, so it can be undone.\n *\n * The field is focused first because the pipeline only runs on the focused\n * element, and a completion accepted by mouse click would otherwise arrive after\n * the click had already blurred the field.\n * @param field - the textarea.\n * @param from - the first offset to replace.\n * @param to - the offset after the last.\n * @param text - what to put there. The empty string deletes.\n * @returns how the edit landed.\n */\nexport function replaceThroughPipeline(\n field: HTMLTextAreaElement,\n from: number,\n to: number,\n text: string,\n): EditOutcome {\n const start = clamp(Math.min(from, to), 0, field.value.length)\n const end = clamp(Math.max(from, to), start, field.value.length)\n if (start === end && text === '') return 'unchanged'\n\n if (field.ownerDocument.activeElement !== field) field.focus({ preventScroll: true })\n writeSelection(field, start, end)\n\n const before = field.value\n if (canEditThroughPipeline()) {\n try {\n field.ownerDocument.execCommand('insertText', false, text)\n } catch {\n // Firefox throws rather than returning false for some input types. Falling\n // through to the direct path is the right answer either way.\n }\n // The return value is not trustworthy across browsers, and it does not need to\n // be: the VALUE decides. A change we did not make ourselves is one the\n // browser's history already knows about, which is the whole point.\n if (field.value !== before) return 'pipeline'\n }\n\n field.setRangeText(text, start, end, 'end')\n if (field.value === before) return 'unchanged'\n dispatchInput(field, text)\n return 'direct'\n}\n\n/**\n * Fire the event the browser would have fired, for the direct path only.\n *\n * The pipeline path needs no help: the browser dispatches `input` itself, which is\n * exactly why the editor can treat both paths the same way downstream.\n * @param field - the textarea.\n * @param text - what was written.\n */\nexport function dispatchInput(field: HTMLTextAreaElement, text: string): void {\n const view = field.ownerDocument.defaultView\n const InputEventCtor = view === null ? undefined : (view as Window & { InputEvent?: typeof InputEvent }).InputEvent\n if (typeof InputEventCtor === 'function') {\n field.dispatchEvent(\n new InputEventCtor('input', { bubbles: true, inputType: 'insertText', data: text }),\n )\n return\n }\n field.dispatchEvent(new Event('input', { bubbles: true }))\n}\n\n/**\n * Undo, through the browser's own history.\n *\n * Exposed so a host can offer a button without reimplementing a stack, and so the\n * browser harness can drive the same path a keyboard shortcut drives.\n * @param field - the textarea.\n * @returns whether the call was possible at all. It cannot report whether anything\n * was actually undone, because no browser exposes that.\n */\nexport function undoField(field: HTMLTextAreaElement): boolean {\n if (!canEditThroughPipeline()) return false\n if (field.ownerDocument.activeElement !== field) field.focus({ preventScroll: true })\n try {\n return field.ownerDocument.execCommand('undo')\n } catch {\n return false\n }\n}\n\n/**\n * Redo, through the browser's own history.\n * @param field - the textarea.\n * @returns whether the call was possible at all.\n */\nexport function redoField(field: HTMLTextAreaElement): boolean {\n if (!canEditThroughPipeline()) return false\n if (field.ownerDocument.activeElement !== field) field.focus({ preventScroll: true })\n try {\n return field.ownerDocument.execCommand('redo')\n } catch {\n return false\n }\n}\n\n/**\n * Write a whole document into a field.\n *\n * Two paths, and the difference matters. `preserveHistory` selects everything and\n * inserts through the pipeline, so the replacement is one undoable edit and Ctrl+Z\n * brings the previous text back — the right behaviour for a Reset button. Without\n * it the value property is assigned, which is faster and clears the history, which\n * is the right behaviour when a host is loading a different document entirely.\n * @param field - the textarea.\n * @param next - the new text.\n * @param preserveHistory - whether the change should be undoable.\n * @returns how the write landed.\n */\nexport function writeDocument(\n field: HTMLTextAreaElement,\n next: string,\n preserveHistory = false,\n): EditOutcome {\n if (field.value === next) return 'unchanged'\n if (preserveHistory) return replaceThroughPipeline(field, 0, field.value.length, next)\n field.value = next\n writeSelection(field, next.length, next.length)\n return 'direct'\n}\n","// ─── mirror: measuring text the textarea will not tell us ───────────────────\n//\n// A textarea can report its `scrollHeight` and its selection offsets, and that is\n// the whole of it. It cannot say where the caret is on screen, and its\n// `scrollHeight` cannot be trusted while its own height is being changed — asking\n// for it means first collapsing the element, which reflows the page and makes the\n// box flicker on every keystroke.\n//\n// So a second element is kept offscreen with the field's exact typography and the\n// same box, and the question is asked of IT. Two jobs come out of the same\n// element: where the caret is, and how tall the content is. Both are pure\n// measurements of text, both need the same copied styles, and both are wrong in\n// the same way if a single property is missed — which is why there is one mirror\n// and not two.\n//\n// `visibility: hidden` rather than `display: none`, because a hidden element still\n// lays out and a removed one does not.\n\nimport { clamp } from '../core/text.js'\n\n/**\n * The properties that decide where a glyph lands.\n *\n * Anything in this list that the mirror does not copy makes every measurement\n * wrong by a little, and the failures are not obvious: a missing\n * `letter-spacing` moves the caret a fraction of a character per character, so the\n * popup drifts further off the longer the line is. The list is deliberately\n * exhaustive rather than \"the ones that seemed to matter\".\n */\nconst COPIED_PROPERTIES = [\n 'fontFamily',\n 'fontSize',\n 'fontWeight',\n 'fontStyle',\n 'fontStretch',\n 'fontVariantLigatures',\n 'fontKerning',\n 'fontFeatureSettings',\n 'lineHeight',\n 'letterSpacing',\n 'wordSpacing',\n 'textTransform',\n 'textIndent',\n 'textAlign',\n 'direction',\n 'tabSize',\n 'whiteSpace',\n 'overflowWrap',\n 'wordBreak',\n 'hyphens',\n 'paddingTop',\n 'paddingRight',\n 'paddingBottom',\n 'paddingLeft',\n 'borderTopWidth',\n 'borderRightWidth',\n 'borderBottomWidth',\n 'borderLeftWidth',\n 'borderTopStyle',\n 'borderRightStyle',\n 'borderBottomStyle',\n 'borderLeftStyle',\n 'boxSizing',\n] as const\n\n/** Where the caret is, in pixels relative to the field's border box. */\nexport interface CaretBox {\n /** Distance from the field's left border edge to the caret. */\n x: number\n /** Distance from the field's top border edge to the caret's line box. */\n y: number\n /** The height of the caret's line. */\n height: number\n /** The line height in force, whether or not it was declared. */\n lineHeight: number\n}\n\n/** A zero-width space: content that draws nothing and occupies a line. */\nconst SENTINEL = '\\u200b'\n\n/**\n * An offscreen element that lays text out exactly as a given textarea does.\n *\n * One instance per field is enough; the editor owns exactly one.\n */\nexport class TextMirror {\n /** The measuring element. Kept out of the document's flow by `position: fixed`. */\n readonly element: HTMLDivElement\n private readonly document: Document\n private readonly view: Window | undefined\n /** The field this mirror is currently shaped like. */\n private adopted: HTMLTextAreaElement | undefined\n /** The line height measured with the field, or 0 before the first measurement. */\n private measuredLineHeight = 0\n\n /**\n * @param ownerDocument - the document to create the element in.\n */\n constructor(ownerDocument: Document) {\n this.document = ownerDocument\n this.view = ownerDocument.defaultView ?? undefined\n this.element = ownerDocument.createElement('div')\n this.element.setAttribute('aria-hidden', 'true')\n this.element.dataset.liteareaPart = 'mirror'\n // `white-space: pre-wrap` is the one property both jobs depend on absolutely:\n // a newline has to break the line in the mirror exactly as it does in the\n // field, and a run of spaces has to survive.\n this.element.style.cssText = [\n 'position:fixed',\n 'top:0',\n 'left:0',\n 'visibility:hidden',\n 'pointer-events:none',\n 'z-index:-1',\n 'margin:0',\n 'overflow:hidden',\n 'white-space:pre-wrap',\n 'overflow-wrap:break-word',\n 'word-break:break-word',\n 'box-sizing:border-box',\n ].join(';')\n }\n\n /** Whether the mirror is in a document. */\n get mounted(): boolean {\n return this.element.isConnected\n }\n\n /**\n * Mount the mirror, once, so measurements have a layout to read.\n * @param parent - where to mount it. The body is right unless the document has none.\n */\n mount(parent?: Element): void {\n if (this.mounted) return\n const host = parent ?? this.document.body ?? this.document.documentElement\n if (host === null || host === undefined) return\n host.appendChild(this.element)\n }\n\n /**\n * Shape the mirror like a field.\n *\n * The width is the interesting part. It has to be the field's CONTENT width, or\n * text wraps in one and not the other — and the field's `clientWidth` is its\n * content plus padding but NOT its border, while the mirror is `border-box`. So\n * the borders are added back, and what is deliberately left out is the\n * scrollbar: a field clamped to its maximum height has one, and the text wraps\n * inside the narrower area above it.\n * @param field - the textarea to imitate.\n */\n adopt(field: HTMLTextAreaElement): void {\n this.mount()\n this.adopted = field\n const view = this.view\n if (view === null || view === undefined) return\n const styles = view.getComputedStyle(field)\n for (const property of COPIED_PROPERTIES) {\n this.element.style.setProperty(\n property.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`),\n styles.getPropertyValue(property.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)),\n )\n }\n const borderLeft = Number.parseFloat(styles.borderLeftWidth) || 0\n const borderRight = Number.parseFloat(styles.borderRightWidth) || 0\n this.element.style.width = `${String(field.clientWidth + borderLeft + borderRight)}px`\n this.measuredLineHeight = 0\n }\n\n /**\n * The line height in force, measured rather than assumed.\n *\n * `line-height: normal` is a real value and a common one, and it cannot be read\n * as a number — `parseFloat('normal')` is `NaN`. So it is measured by laying one\n * line of text out and taking the height, which is also the only way to be right\n * about a font whose normal leading is not 1.2.\n * @param field - the field to measure against.\n * @returns the line height in pixels.\n */\n lineHeight(field: HTMLTextAreaElement): number {\n if (this.measuredLineHeight > 0) return this.measuredLineHeight\n const view = this.view\n if (view === null || view === undefined) return 0\n const styles = view.getComputedStyle(field)\n const declared = Number.parseFloat(styles.lineHeight)\n if (Number.isFinite(declared) && declared > 0) {\n this.measuredLineHeight = declared\n return declared\n }\n this.adopt(field)\n this.setText('M')\n const padding = this.verticalPadding()\n const height = this.element.getBoundingClientRect().height - padding\n // A font that reports nothing usable still needs an answer, and 1.2 × the font\n // size is what `normal` means for essentially every font in practice.\n const fontSize = Number.parseFloat(styles.fontSize)\n const fallback = (Number.isFinite(fontSize) ? fontSize : 16) * 1.2\n this.measuredLineHeight = height > 0 ? height : fallback\n return this.measuredLineHeight\n }\n\n /** The mirror's vertical padding plus border, which every height includes. */\n verticalPadding(): number {\n const view = this.view\n if (view === null || view === undefined) return 0\n const styles = view.getComputedStyle(this.element)\n const sum =\n (Number.parseFloat(styles.paddingTop) || 0) +\n (Number.parseFloat(styles.paddingBottom) || 0) +\n (Number.parseFloat(styles.borderTopWidth) || 0) +\n (Number.parseFloat(styles.borderBottomWidth) || 0)\n return sum\n }\n\n /**\n * Put text in the mirror with nothing else in it.\n * @param text - the content.\n */\n setText(text: string): void {\n this.element.textContent = text\n }\n\n /**\n * The height a field needs to show a document without scrolling.\n *\n * The trailing-newline problem is handled here. A div with `white-space:\n * pre-wrap` and content ending in `\\n` does not lay out a final empty line — the\n * newline breaks the line but nothing follows it — so the measured height comes\n * back one line short and the field grows a scrollbar exactly when the user\n * presses Enter at the end. A zero-width space after the newline gives that last\n * line something to be.\n * @param field - the field being sized.\n * @param value - the text it holds.\n * @returns the border-box height the content requires.\n */\n contentHeight(field: HTMLTextAreaElement, value: string): number {\n this.adopt(field)\n const needsSentinel = value === '' || value.endsWith('\\n') || value.endsWith('\\r')\n this.setText(needsSentinel ? `${value}${SENTINEL}` : value)\n return this.element.getBoundingClientRect().height\n }\n\n /**\n * Where the caret sits, in pixels relative to the field's border box.\n *\n * The trick is a marker element holding the character AFTER the caret, measured\n * against the mirror. Everything before the caret lays out normally, so the\n * marker lands exactly where the next glyph will be — which is where the caret\n * is. At the end of the document there is no next character, so a zero-width\n * space stands in for it.\n *\n * The field's own scroll offset is subtracted, because the caret's position on\n * screen is what the popup has to be placed against, and a scrolled field moves\n * its text without moving its border box.\n *\n * @param field - the field the caret is in.\n * @param offset - the caret's character offset.\n * @returns the caret box, or undefined when there is no layout to measure.\n */\n caretBox(field: HTMLTextAreaElement, offset: number): CaretBox | undefined {\n const view = this.view\n if (view === null || view === undefined) return undefined\n this.adopt(field)\n const value = field.value\n const position = clamp(offset, 0, value.length)\n const before = value.slice(0, position)\n const after = value.slice(position)\n const next = after === '' ? SENTINEL : after.charAt(0)\n\n // Rebuilt rather than patched: the mirror is offscreen and measuring it is\n // cheap, while keeping incremental DOM in step with a fast typist is not.\n this.element.textContent = ''\n this.element.appendChild(this.document.createTextNode(before))\n const marker = this.document.createElement('span')\n marker.textContent = next\n // A span that can wrap would let the marker jump to the next line on its own,\n // which is exactly the wrong answer for a caret at a line end.\n marker.style.whiteSpace = 'pre'\n this.element.appendChild(marker)\n this.element.appendChild(this.document.createTextNode(after.slice(next.length)))\n\n const mirrorRect = this.element.getBoundingClientRect()\n const markerRect = marker.getBoundingClientRect()\n const lineHeight = this.lineHeight(field)\n return {\n x: markerRect.left - mirrorRect.left - field.scrollLeft,\n y: markerRect.top - mirrorRect.top - field.scrollTop,\n height: markerRect.height > 0 ? markerRect.height : lineHeight,\n lineHeight,\n }\n }\n\n /** Take the mirror out of the document. */\n destroy(): void {\n this.element.remove()\n this.adopted = undefined\n }\n\n /**\n * The field this mirror was last shaped like.\n * @returns the field, or undefined before {@link adopt}.\n */\n get field(): HTMLTextAreaElement | undefined {\n return this.adopted\n }\n}\n","// ─── overlay: the painted layer behind the field ────────────────────────────\n//\n// The layer draws the same characters as the textarea, in colour, and it is\n// positioned to share the field's box exactly. It never measures anything: the\n// segments come out of `buildSegments` in document order and are appended back to\n// back, so the browser's own text layout puts every character where the field put\n// it. The only thing this module does besides writing DOM is keep the layer\n// scrolled with the field.\n\nimport type { SegmentInput } from '../core/segments.js'\nimport { buildSegments, segmentClasses } from '../core/segments.js'\n\n/** How the layer turns a scope, a decoration, or a severity into a class. */\nexport interface OverlayClassNames {\n scope: (scope: string) => string\n decoration: (kind: string) => string\n severity: (severity: string) => string\n}\n\n/** The painted layer and the element that holds the paint. */\nexport class Overlay {\n /** The scroll container. Same box as the field. */\n readonly element: HTMLDivElement\n /** The element the spans are written into. */\n private readonly paint: HTMLDivElement\n private readonly document: Document\n private readonly classNames: OverlayClassNames\n /** What was painted last, so an unchanged document is not repainted. */\n private paintedText: string | undefined\n private paintedKey = ''\n\n /**\n * @param ownerDocument - the document to build in.\n * @param classNames - the three class-name mappings.\n */\n constructor(ownerDocument: Document, classNames: OverlayClassNames) {\n this.document = ownerDocument\n this.classNames = classNames\n this.element = ownerDocument.createElement('div')\n this.element.className = 'litearea-layer'\n this.element.setAttribute('aria-hidden', 'true')\n this.element.dataset.liteareaPart = 'layer'\n this.paint = ownerDocument.createElement('div')\n this.paint.className = 'litearea-paint'\n this.element.appendChild(this.paint)\n }\n\n /**\n * Paint a document.\n *\n * `key` is whatever the caller knows changed. When it and the text both match\n * the last call the work is skipped, which is what keeps a caret move or a\n * mouse hover from rebuilding every span on the page.\n * @param text - the document.\n * @param input - the tokens, decorations, and diagnostics.\n * @param key - a cheap signature of everything that affects the paint.\n * @param fallbackScope - the scope for characters no token covers.\n */\n render(text: string, input: SegmentInput, key: string, fallbackScope = 'text'): void {\n if (this.paintedText === text && this.paintedKey === key) return\n const segments = buildSegments(text, input, fallbackScope)\n const fragment = this.document.createDocumentFragment()\n for (const segment of segments) {\n const span = this.document.createElement('span')\n span.className = segmentClasses(\n segment,\n this.classNames.scope,\n this.classNames.decoration,\n this.classNames.severity,\n ).join(' ')\n if (segment.title !== undefined) span.title = segment.title\n span.textContent = segment.text\n fragment.appendChild(span)\n }\n this.paint.replaceChildren(fragment)\n this.paintedText = text\n this.paintedKey = key\n }\n\n /**\n * Follow the field's scroll position.\n *\n * The layer is `overflow: hidden` and its content is taller than its box exactly\n * when the field is: an auto-grown field has nothing to scroll and a field\n * clamped to its maximum height has everything to scroll. Copying the offset is\n * therefore enough, and it is more reliable than a transform, which can leave\n * the text on a half pixel.\n * @param field - the textarea.\n */\n syncScroll(field: HTMLTextAreaElement): void {\n if (this.element.scrollTop !== field.scrollTop) this.element.scrollTop = field.scrollTop\n if (this.element.scrollLeft !== field.scrollLeft) this.element.scrollLeft = field.scrollLeft\n }\n\n /** Forget what was painted, so the next render rebuilds. */\n invalidate(): void {\n this.paintedText = undefined\n this.paintedKey = ''\n }\n\n /** Take the layer out of the document. */\n destroy(): void {\n this.element.remove()\n this.paint.replaceChildren()\n }\n}\n","// ─── popup: the completion list ─────────────────────────────────────────────\n//\n// Three parts, and the split between them is the whole design:\n//\n// div.litearea-popup the positioned container; scrolls NOTHING\n// div.litearea-list the scroller, and the listbox role; holds rows only\n// div.litearea-docs the documentation, pinned below the list\n//\n// The documentation used to be appended INSIDE the scrolling element, after the rows, and\n// that made it unreachable in the one case it matters most: with a long list and a long\n// explanation, the explanation sat at the end of the scroll range, so a keyboard user could\n// never see it at all — the arrows move the active row, not the scrollbar — and a mouse user\n// had to scroll down to read it and then back up to reach the next row. Pinning it outside the\n// scroller fixes both, because the panel never moves when the list scrolls and never has to be\n// scrolled to in the first place.\n//\n// Two interaction details are also deliberate. A pick must not blur the field: a click fires\n// `mousedown` before `blur`, so the row listens for `mousedown`, cancels the default to keep\n// the focus, and accepts — listening for `click` instead means the field is already blurred by\n// the time the handler runs. And the list scrolls only as far as the active row needs, because\n// a list that re-centres on every arrow press looks like it is jumping.\n\nimport type { CompletionRow, SuggestionItem } from '../core/types.js'\nimport { highlightSegments } from '../core/rank.js'\n\n/** Where a floating element is allowed to sit. */\nexport interface AnchorBox {\n /** Distance from the positioning container's left edge. */\n x: number\n /** Distance from the positioning container's top edge. */\n y: number\n /** The height of the line the anchor sits on. */\n height: number\n}\n\n/** What the list tells its owner. */\nexport interface PopupHandlers {\n /** A row was chosen with the mouse. */\n accept(index: number): void\n /** The pointer moved over a row, which makes it active. */\n hover(index: number): void\n}\n\n/** The completion list, with its documentation panel. */\nexport class Popup {\n /** The positioned container. */\n readonly element: HTMLDivElement\n /** The scrolling element, which holds the rows and nothing else. */\n readonly list: HTMLDivElement\n private readonly document: Document\n private readonly handlers: PopupHandlers\n private rows: readonly CompletionRow[] = []\n private active = -1\n private open = false\n private showDocs = true\n private readonly docs: HTMLDivElement\n private readonly prefix: string\n\n /**\n * @param ownerDocument - the document to build in.\n * @param handlers - how to report a pick and a hover.\n * @param idPrefix - a stable prefix for row ids, so two editors do not collide.\n */\n constructor(ownerDocument: Document, handlers: PopupHandlers, idPrefix: string) {\n this.document = ownerDocument\n this.handlers = handlers\n this.prefix = idPrefix\n\n this.element = ownerDocument.createElement('div')\n this.element.className = 'litearea-popup'\n this.element.dataset.liteareaPart = 'popup'\n this.element.dataset.open = 'false'\n\n this.list = ownerDocument.createElement('div')\n this.list.className = 'litearea-list'\n this.list.setAttribute('role', 'listbox')\n this.list.id = `${idPrefix}-listbox`\n this.element.appendChild(this.list)\n\n this.docs = ownerDocument.createElement('div')\n this.docs.className = 'litearea-docs'\n this.docs.hidden = true\n this.element.appendChild(this.docs)\n\n // Bound to the list rather than to each row, so replacing every row on each keystroke does\n // not mean attaching and detaching listeners on every keystroke.\n this.list.addEventListener('mousedown', this.onMouseDown)\n this.list.addEventListener('mousemove', this.onMouseMove)\n }\n\n /** Whether the list is showing. */\n get isOpen(): boolean {\n return this.open\n }\n\n /** The active row's index, or -1. */\n get activeIndex(): number {\n return this.active\n }\n\n /** The rows currently shown. */\n get items(): readonly CompletionRow[] {\n return this.rows\n }\n\n /** The active row, when there is one. */\n get activeRow(): CompletionRow | undefined {\n return this.rows[this.active]\n }\n\n /** The id the field's `aria-controls` should name. It is the list, not the container. */\n get listId(): string {\n return this.list.id\n }\n\n /**\n * The id of the active row, for the field's `aria-activedescendant`.\n *\n * The list does not write that attribute itself: the field belongs to the editor, and a\n * floating list reaching out of its own subtree to find it is the kind of coupling that\n * breaks the moment the two are mounted somewhere unexpected.\n * @returns the row id, or undefined when no row is active.\n */\n get activeRowId(): string | undefined {\n return this.active >= 0 ? this.rowId(this.active) : undefined\n }\n\n /**\n * Show a list.\n * @param rows - the rows, already ranked.\n * @param active - the row to make active.\n * @param showDocs - whether to render the documentation panel.\n */\n show(rows: readonly CompletionRow[], active: number, showDocs: boolean): void {\n this.rows = rows\n this.active = active\n this.showDocs = showDocs\n this.open = true\n this.element.dataset.open = 'true'\n this.element.dataset.docs = showDocs ? 'true' : 'false'\n this.list.scrollTop = 0\n this.render()\n }\n\n /** Hide the list and forget its rows. */\n close(): void {\n if (!this.open) return\n this.open = false\n this.active = -1\n this.rows = []\n this.element.dataset.open = 'false'\n this.list.replaceChildren()\n this.docs.hidden = true\n this.docs.replaceChildren()\n }\n\n /**\n * Make a row active without rebuilding the list.\n * @param index - the row index.\n */\n setActive(index: number): void {\n if (index === this.active) return\n const previous = this.list.querySelector<HTMLElement>(`#${this.rowId(this.active)}`)\n if (previous !== null) previous.setAttribute('aria-selected', 'false')\n this.active = index\n const next = this.list.querySelector<HTMLElement>(`#${this.rowId(index)}`)\n if (next !== null) {\n next.setAttribute('aria-selected', 'true')\n // Only as far as needed, and only the LIST scrolls: the documentation panel is outside\n // this element, so moving the active row can never push the explanation out of sight.\n const top = next.offsetTop\n const bottom = top + next.offsetHeight\n if (top < this.list.scrollTop) this.list.scrollTop = top\n else if (bottom > this.list.scrollTop + this.list.clientHeight) {\n this.list.scrollTop = bottom - this.list.clientHeight\n }\n }\n this.renderDocs()\n }\n\n /**\n * Place the list under an anchor, flipping above it when there is no room below.\n *\n * The container's own box is what is measured, so the documentation panel counts towards the\n * height and a popup whose rows and explanation together would run off the bottom flips as a\n * whole rather than being cut in half.\n * @param anchor - the caret's box, in the container's coordinates.\n * @param container - the element the list is positioned against.\n * @param viewport - the visible area to stay inside.\n */\n place(anchor: AnchorBox, container: HTMLElement, viewport: { width: number; height: number }): void {\n const box = this.element.getBoundingClientRect()\n const containerBox = container.getBoundingClientRect()\n const gap = 4\n let top = anchor.y + anchor.height + gap\n if (containerBox.top + top + box.height > viewport.height - gap) {\n const above = anchor.y - box.height - gap\n // Flipping only helps if there is somewhere to flip TO; otherwise the list stays below\n // and is clamped by the max-heights in the stylesheet.\n if (containerBox.top + above >= gap) top = above\n }\n let left = anchor.x\n const maxLeft = containerBox.width - box.width\n if (left > maxLeft) left = Math.max(0, maxLeft)\n this.element.style.top = `${String(Math.round(top))}px`\n this.element.style.left = `${String(Math.round(left))}px`\n }\n\n /** Take the list out of the document. */\n destroy(): void {\n this.list.removeEventListener('mousedown', this.onMouseDown)\n this.list.removeEventListener('mousemove', this.onMouseMove)\n this.element.remove()\n this.list.replaceChildren()\n this.docs.replaceChildren()\n }\n\n /** The DOM id of a row, which `aria-activedescendant` points at. */\n rowId(index: number): string {\n return `${this.prefix}-row-${String(index)}`\n }\n\n // ── internals ────────────────────────────────────────────────────────────\n\n private render(): void {\n const fragment = this.document.createDocumentFragment()\n this.rows.forEach((row, index) => {\n const element = this.document.createElement('div')\n element.className = 'litearea-row'\n element.id = this.rowId(index)\n element.setAttribute('role', 'option')\n element.setAttribute('aria-selected', index === this.active ? 'true' : 'false')\n element.dataset.index = String(index)\n\n const kind = this.document.createElement('span')\n kind.className = `litearea-rowKind litearea-kind-${row.item.kind ?? 'value'}`\n element.appendChild(kind)\n\n const label = this.document.createElement('span')\n label.className = 'litearea-rowLabel'\n // Emphasised as segments rather than as markup: a font family may legitimately be called\n // `<b>`, and a list that built HTML from a label would either render it or have to escape\n // it, and both are wrong for text that came from the user's machine.\n for (const piece of highlightSegments(row.item.label, row.indices)) {\n if (piece.matched) {\n const mark = this.document.createElement('span')\n mark.className = 'litearea-rowMatch'\n mark.textContent = piece.text\n label.appendChild(mark)\n } else {\n label.appendChild(this.document.createTextNode(piece.text))\n }\n }\n element.appendChild(label)\n\n if (row.item.detail !== undefined) {\n const detail = this.document.createElement('span')\n detail.className = 'litearea-rowDetail'\n detail.textContent = row.item.detail\n element.appendChild(detail)\n }\n fragment.appendChild(element)\n })\n\n // Rows go in the list and nowhere else. The documentation is a sibling that is never\n // rebuilt here, so converting a long explanation cannot disturb the scroll position.\n this.list.replaceChildren(fragment)\n this.renderDocs()\n }\n\n /** Refresh the documentation panel from the active row. */\n private renderDocs(): void {\n const item: SuggestionItem | undefined = this.rows[this.active]?.item\n const hasDocs =\n this.showDocs &&\n this.open &&\n item !== undefined &&\n (item.documentation !== undefined || item.detail !== undefined)\n this.docs.hidden = !hasDocs\n if (!hasDocs || item === undefined) {\n this.docs.replaceChildren()\n return\n }\n const fragment = this.document.createDocumentFragment()\n const title = this.document.createElement('div')\n title.className = 'litearea-docsTitle'\n title.textContent = item.label\n fragment.appendChild(title)\n if (item.detail !== undefined) {\n const detail = this.document.createElement('div')\n detail.className = 'litearea-docsDetail'\n detail.textContent = item.detail\n fragment.appendChild(detail)\n }\n if (item.documentation !== undefined) {\n const body = this.document.createElement('div')\n body.className = 'litearea-docsBody'\n body.textContent = item.documentation\n fragment.appendChild(body)\n }\n this.docs.replaceChildren(fragment)\n // A new explanation is read from its beginning, which matters when the previous one was\n // long enough to have been scrolled.\n this.docs.scrollTop = 0\n }\n\n private readonly onMouseDown = (event: MouseEvent): void => {\n const row = (event.target as HTMLElement | null)?.closest<HTMLElement>('.litearea-row')\n if (row === null || row === undefined) return\n // Before blur, and cancelling the default is what keeps the field focused.\n event.preventDefault()\n const index = Number.parseInt(row.dataset.index ?? '-1', 10)\n if (Number.isInteger(index) && index >= 0) this.handlers.accept(index)\n }\n\n private readonly onMouseMove = (event: MouseEvent): void => {\n const row = (event.target as HTMLElement | null)?.closest<HTMLElement>('.litearea-row')\n if (row === null || row === undefined) return\n const index = Number.parseInt(row.dataset.index ?? '-1', 10)\n if (!Number.isInteger(index) || index < 0 || index === this.active) return\n this.handlers.hover(index)\n }\n}\n","// ─── tooltip: what the pointer is resting on ────────────────────────────────\n//\n// One floating element, positioned near the thing it describes and kept inside the\n// viewport. It never takes the pointer: a tooltip that can be hovered is a tooltip\n// that flickers, because moving the mouse onto it leaves the thing that opened it.\n//\n// The content is deliberately plain text, not markup. A grammar supplies strings,\n// those strings may be a font family called `<b>` or a value containing `#`, and a\n// tooltip that rendered them as HTML would either mis-render the text or have to\n// escape it — both wrong for text the user typed.\n\nimport type { HoverInfo } from '../core/types.js'\n\n/** Where a floating element is allowed to sit. */\nexport interface TooltipAnchor {\n /** Distance from the positioning container's left edge. */\n x: number\n /** Distance from the positioning container's top edge. */\n y: number\n /** The height of the anchored line or range. */\n height: number\n}\n\n/** The hover tooltip. */\nexport class Tooltip {\n /** The tooltip element. */\n readonly element: HTMLDivElement\n private readonly document: Document\n private open = false\n\n /**\n * @param ownerDocument - the document to build in.\n */\n constructor(ownerDocument: Document) {\n this.document = ownerDocument\n this.element = ownerDocument.createElement('div')\n this.element.className = 'litearea-tooltip'\n this.element.setAttribute('role', 'tooltip')\n this.element.dataset.liteareaPart = 'tooltip'\n this.element.dataset.open = 'false'\n }\n\n /** Whether the tooltip is showing. */\n get isOpen(): boolean {\n return this.open\n }\n\n /**\n * Show a hover.\n * @param info - what to say.\n * @param anchor - where the thing being described is.\n * @param container - the element the tooltip is positioned against.\n * @param viewport - the visible area to stay inside.\n */\n show(\n info: HoverInfo,\n anchor: TooltipAnchor,\n container: HTMLElement,\n viewport: { width: number; height: number },\n ): void {\n const fragment = this.document.createDocumentFragment()\n if (info.title !== undefined) {\n const title = this.document.createElement('div')\n title.className = 'litearea-tooltipTitle'\n title.textContent = info.title\n fragment.appendChild(title)\n }\n if (info.detail !== undefined && info.detail !== '') {\n const detail = this.document.createElement('div')\n detail.className = 'litearea-tooltipDetail'\n detail.textContent = info.detail\n fragment.appendChild(detail)\n }\n if (info.body !== undefined && info.body !== '') {\n const body = this.document.createElement('div')\n body.className = 'litearea-tooltipBody'\n body.textContent = info.body\n fragment.appendChild(body)\n }\n this.element.replaceChildren(fragment)\n this.open = true\n this.element.dataset.open = 'true'\n\n const box = this.element.getBoundingClientRect()\n const containerBox = container.getBoundingClientRect()\n const gap = 6\n let top = anchor.y + anchor.height + gap\n if (containerBox.top + top + box.height > viewport.height - gap) {\n const above = anchor.y - box.height - gap\n top = containerBox.top + above >= gap ? above : Math.max(0, viewport.height - gap - box.height - containerBox.top)\n }\n let left = anchor.x\n const overflowRight = containerBox.left + left + box.width - (viewport.width - gap)\n if (overflowRight > 0) left = Math.max(0, left - overflowRight)\n this.element.style.top = `${String(Math.round(top))}px`\n this.element.style.left = `${String(Math.round(left))}px`\n }\n\n /** Hide the tooltip. */\n hide(): void {\n if (!this.open) return\n this.open = false\n this.element.dataset.open = 'false'\n this.element.replaceChildren()\n }\n\n /** Take the tooltip out of the document. */\n destroy(): void {\n this.element.remove()\n this.element.replaceChildren()\n }\n}\n","// ─── editor: the element, and the interaction ───────────────────────────────\n//\n// This is where the four things the library promises are actually kept, and each\n// is a decision made here rather than a behaviour that emerged.\n//\n// **Undo survives, because the DOM owns the text.** The textarea is never given a\n// `value` after it is created. Every edit the user makes is the browser's own, and\n// every edit the editor makes on the user's behalf goes through the browser's\n// editing pipeline (`src/dom/editing.ts`). The highlight layer reads the text; it\n// never writes it. A framework binding on top must leave the element alone for the\n// same reason, which is why the React wrapper renders a bare div and hands the\n// element to this class.\n//\n// **The caret does not move, because nothing rewrites the text under it.** The\n// editors this replaces re-rendered the value on every keystroke and then tried to\n// put the caret back — a race the browser wins eventually, and the same mistake\n// that destroyed the undo stack. Here there is no re-render to lose a race with,\n// and the only caret writes are the ones a completion asked for.\n//\n// **The list behaves, because its range is frozen when it opens.** Filtering runs\n// against the recorded range instead of re-deriving one from a document that has\n// changed since, so the target cannot slide out from under the list while the user\n// types. Enter and Tab accept, Escape dismisses, Ctrl+Space opens on demand, and\n// the arrows move the selection without wrapping — the behaviour every editor has,\n// which is the whole point.\n//\n// **The box fits, because an offscreen mirror is measured instead of the field.**\n// Asking a textarea for its `scrollHeight` means collapsing it first, which\n// reflows the page and flickers on every keystroke. `src/dom/mirror.ts` keeps a\n// second element with the same typography and asks that instead.\n\nimport type {\n Completion,\n Decoration,\n Diagnostic,\n Grammar,\n HoverInfo,\n Range,\n Severity,\n SuggestionItem,\n} from '../core/types.js'\nimport type { Inspection } from '../core/inspect.js'\nimport type { SegmentInput } from '../core/segments.js'\nimport type { CompletionTrigger } from '../core/types.js'\nimport { applyCompletion, complete } from '../core/complete.js'\nimport { resolveHover } from '../core/hover.js'\nimport { inspect } from '../core/inspect.js'\nimport { resolveGrammar, isResolvedGrammar, type ResolvedGrammar } from '../core/scan.js'\nimport { clamp } from '../core/text.js'\nimport { decorationClass, injectStyles, scopeClass, severityClass } from '../styles.js'\nimport {\n readSelection,\n redoField,\n replaceThroughPipeline,\n undoField,\n writeDocument,\n writeSelection,\n type EditOutcome,\n type TextSelection,\n} from './editing.js'\nimport { TextMirror } from './mirror.js'\nimport { Overlay } from './overlay.js'\nimport { Popup } from './popup.js'\nimport { Tooltip } from './tooltip.js'\nimport { withDefaults } from './support.js'\n\n/** How the box follows its content. */\nexport interface LiteAreaSizing {\n /**\n * Whether the height follows the content, so that no scrollbar is shown while\n * the content fits. Default `true`.\n */\n autoGrow?: boolean\n /**\n * The fewest lines to show, written to the textarea's own `rows` attribute.\n *\n * The native attribute is set rather than only a pixel minimum, so the box has\n * the right height on the very first frame — before any measurement, and in a\n * document where the script never runs at all. Default 1.\n */\n minRows?: number\n /** The most lines to show before a scrollbar appears. */\n maxRows?: number\n /** A minimum height in pixels, in addition to `minRows`. */\n minHeight?: number\n /** A maximum height in pixels, in addition to `maxRows`. */\n maxHeight?: number\n}\n\n/** How the completion list behaves. */\nexport interface LiteAreaCompletion {\n /** Whether suggestions appear while typing. Default `true`. */\n auto?: boolean\n /**\n * Characters that open the list in addition to word characters.\n *\n * Empty by default, because a separator is the wrong moment to interrupt: it is\n * where the next token starts, which is the argument FOR opening there, and it\n * loses to the habit every reader already has — the editor this is modelled on\n * offers nothing on a space and waits for a letter or for `Ctrl+Space`. Nothing\n * is stranded by that. The list stays open once it is open, so a value typed\n * after a name is still filtered in place, and `Ctrl+Space` opens it on demand.\n * Set it to `' '` or `','` for a language where a separator really is where the\n * next token becomes guessable.\n */\n triggerCharacters?: string\n /** The most rows to offer. Default 100. */\n limit?: number\n /** Whether the documentation panel is shown. Default `true`. */\n showDocumentation?: boolean\n}\n\n/** How the hover tooltip behaves. */\nexport interface LiteAreaHover {\n /** Whether tooltips appear at all. Default `true`. */\n enabled?: boolean\n /** How long the pointer must rest, in milliseconds. Default 140. */\n delay?: number\n}\n\n/** Everything a host may configure. */\nexport interface LiteAreaOptions<State = unknown> {\n /** The language. Nothing else in this library knows anything about syntax. */\n grammar: Grammar<State> | ResolvedGrammar<State>\n /** The initial text. */\n value?: string\n /** Shown while the box is empty. */\n placeholder?: string\n /** Whether the user may edit. */\n readOnly?: boolean\n /** Whether the browser may spell-check. Default `false`, because a DSL is not prose. */\n spellCheck?: boolean\n /** The accessible name. */\n ariaLabel?: string\n /** An extra class on the wrapper. */\n className?: string\n /**\n * CSS custom properties for THIS instance, for per-instance theming.\n *\n * A key may be written `font`, `--litearea-font`, or any other `--…` name; the first two\n * forms mean the same thing, and a key that already starts with `--` is used verbatim so a\n * host's own properties work too. The value is used as written, so `'13px'`,\n * `'var(--my-ui-font)'`, and `'1.6'` are all fine.\n *\n * createEditor(target, {\n * grammar,\n * variables: { font: '\"Fira Code\", monospace', 'font-size': '14px', accent: '#c2410c' },\n * })\n *\n * CSS stays the theme language on purpose — the editor's whole appearance is already\n * described by custom properties, and a second vocabulary for the same facts would mean two\n * places to keep in step. This exists only so that ONE instance can be themed without a host\n * writing a stylesheet rule for it, and so that two editors on a page can differ.\n */\n variables?: Record<string, string>\n /** How the box follows its content. */\n sizing?: LiteAreaSizing\n /** How the list behaves, or `false` to switch completions off entirely. */\n completion?: LiteAreaCompletion | false\n /** How tooltips behave, or `false` to switch them off entirely. */\n hover?: LiteAreaHover | false\n /** Whether semantic decorations are painted. Default `true`. */\n decorations?: boolean\n /** Whether to inject the stylesheet. Default `true`. */\n injectStyles?: boolean\n /** A CSP nonce for the injected stylesheet. */\n styleNonce?: string\n /** Called after a user edit, with the new text. Not called for programmatic writes. */\n onChange?: (value: string) => void\n /** Called when the caret or selection moves. */\n onSelectionChange?: (selection: TextSelection) => void\n /** Called when the problem list changes. */\n onDiagnostics?: (diagnostics: readonly Diagnostic[]) => void\n /** Called when the list opens, filters, or closes. */\n onCompletion?: (completion: Completion | undefined) => void\n /** Called when a tooltip appears or goes away. */\n onHover?: (info: HoverInfo | undefined) => void\n}\n\n/** The sizing with its defaults filled in. */\ntype ResolvedSizing = Required<Pick<LiteAreaSizing, 'autoGrow' | 'minRows'>> &\n Pick<LiteAreaSizing, 'maxRows' | 'minHeight' | 'maxHeight'>\n\n/** The completion settings with their defaults filled in. */\ntype ResolvedCompletion = Required<LiteAreaCompletion>\n\n/** The hover settings with their defaults filled in. */\ntype ResolvedHover = Required<LiteAreaHover>\n\n/** How many rows a Page key moves through. */\nconst PAGE_STEP = 8\n\n/**\n * A code editor over a textarea.\n *\n * The tree it builds:\n *\n * div.litearea ← the positioning container, and this.element\n * div.litearea-box ← the border, the radius, and the focus ring\n * div.litearea-layer ← the painted text, behind and inert\n * textarea ← the real field: transparent text, visible caret\n * div.litearea-popup ← the completion list\n * div.litearea-tooltip ← the hover tooltip\n *\n * The layer is inside the box while the floating elements are outside it, because\n * the box clips nothing and a list that had to fit inside a rounded border would be\n * cut off at the bottom.\n */\nexport class LiteArea<State = unknown> {\n /** The positioning container. Put this in the page. */\n readonly element: HTMLDivElement\n /** The real field. Exposed for a host that needs the element itself. */\n readonly input: HTMLTextAreaElement\n\n private readonly document: Document\n private readonly view: Window | undefined\n /**\n * The grammar as the host declared it, kept so {@link refresh} can re-resolve it.\n *\n * Mutable on purpose, and it is what lets a host pass a live object — a proxy\n * reading the newest props, say — without the editor having to be rebuilt when the\n * language changes. A rebuild would throw away the undo history, which is the one\n * thing this library must not do, so re-resolving is the only acceptable answer.\n */\n private declaredGrammar: Grammar<State>\n /** The grammar the engine is currently running, with its defaults filled in. */\n private grammar: ResolvedGrammar<State>\n private readonly box: HTMLDivElement\n private readonly overlay: Overlay\n private readonly popup: Popup\n private readonly tooltip: Tooltip\n private readonly mirror: TextMirror\n private readonly sizing: ResolvedSizing\n private readonly completion: ResolvedCompletion | undefined\n private readonly hover: ResolvedHover | undefined\n private readonly paintDecorations: boolean\n private readonly handlers: LiteAreaOptions<State>\n private readonly injectedStyle: HTMLStyleElement | undefined\n private readonly instanceId: string\n private readonly fontsReady: Promise<unknown> | undefined\n\n /** The current inspection, and the text it was computed from. */\n private current: Inspection<State> | undefined\n private currentText: string | undefined\n /** Bumped whenever the inspection changes, so the painter can skip work. */\n private revision = 0\n /** The list on screen, with the range frozen when it opened. */\n private completionState: Completion | undefined\n /** True during an IME composition, when no completion may run. */\n private composing = false\n /** True while the editor itself is writing, so its own edit does not re-open the list. */\n private applying = false\n /** The height and overflow last written, so unchanged values are not rewritten. */\n private appliedHeight = -1\n private appliedOverflow = ''\n private appliedScrollbar = -1\n /** The offset the tooltip last described, so a resting pointer does not re-query. */\n private hoverOffset: number | undefined\n /** The custom properties this instance set, so one that disappears can be removed. */\n private appliedVariables = new Set<string>()\n private hoverTimer: number | undefined\n /** Watches for a width change, which invalidates wrapping and the box height. */\n private resizeObserver: ResizeObserver | undefined\n private observedWidth = -1\n /**\n * A signature of the last announced problem list, so the host is told once.\n *\n * Starts as `undefined` rather than as the empty string, because \"no problems\" is a\n * real signature and a host waiting to be told that the list is clear would otherwise\n * never hear it — it would keep whatever it was showing before the editor existed.\n */\n private announced: string | undefined\n private destroyed = false\n\n /**\n * @param options - the grammar, the initial text, and the behaviour to use.\n */\n constructor(options: LiteAreaOptions<State>) {\n const probe = typeof document === 'undefined' ? undefined : document\n if (probe === undefined) {\n throw new Error('litearea: an editor needs a document, and there is none in this environment')\n }\n this.document = probe\n this.view = probe.defaultView ?? undefined\n this.handlers = options\n // A caller may hand over either the grammar as written or one already resolved;\n // both are accepted so a hot path can skip the work.\n const declared = options.grammar\n this.declaredGrammar = isResolvedGrammar(declared) ? declared.grammar : declared\n this.grammar = resolveGrammar(this.declaredGrammar)\n this.instanceId = `litearea-${Math.random().toString(36).slice(2, 9)}`\n\n this.sizing = withDefaults<ResolvedSizing>(\n { autoGrow: true, minRows: 1 },\n options.sizing as Partial<ResolvedSizing> | undefined,\n )\n // A word character opens the list; a separator does not, unless the grammar's\n // host asks for one by name. The list does not need a separator to be helpful\n // — it is already open while the next token is typed, and it re-filters in\n // place — and opening on a space spends the one keystroke a reader is least\n // willing to have interrupted.\n this.completion =\n options.completion === false\n ? undefined\n : withDefaults<ResolvedCompletion>(\n { auto: true, triggerCharacters: '', limit: 100, showDocumentation: true },\n options.completion,\n )\n this.hover =\n options.hover === false\n ? undefined\n : withDefaults<ResolvedHover>({ enabled: true, delay: 140 }, options.hover)\n this.paintDecorations = options.decorations !== false\n\n if (options.injectStyles !== false) {\n this.injectedStyle = injectStyles(this.document, options.styleNonce)\n }\n\n // ── the element tree ───────────────────────────────────────────────────\n this.element = this.document.createElement('div')\n this.element.className =\n options.className === undefined ? 'litearea' : `litearea ${options.className}`\n this.element.classList.add(this.sizing.autoGrow ? 'litearea-growable' : 'litearea-resizable')\n if (options.readOnly === true) this.element.classList.add('litearea-readonly')\n if (options.variables !== undefined) this.applyVariables(options.variables)\n\n this.box = this.document.createElement('div')\n this.box.className = 'litearea-box'\n this.element.appendChild(this.box)\n\n this.overlay = new Overlay(this.document, {\n scope: scopeClass,\n decoration: decorationClass,\n severity: severityClass,\n })\n this.box.appendChild(this.overlay.element)\n\n this.input = this.document.createElement('textarea')\n this.input.className = 'litearea-input'\n this.input.dataset.liteareaPart = 'input'\n this.input.spellcheck = options.spellCheck === true\n this.input.autocomplete = 'off'\n this.input.setAttribute('autocorrect', 'off')\n this.input.setAttribute('autocapitalize', 'off')\n this.input.setAttribute('wrap', 'soft')\n this.input.readOnly = options.readOnly === true\n // The native attribute, so the first frame is already the right height.\n this.input.rows = this.sizing.minRows\n if (options.placeholder !== undefined) this.input.placeholder = options.placeholder\n if (options.ariaLabel !== undefined) this.input.setAttribute('aria-label', options.ariaLabel)\n this.input.setAttribute('aria-autocomplete', this.completion === undefined ? 'none' : 'list')\n this.input.setAttribute('aria-expanded', 'false')\n this.input.setAttribute('role', 'combobox')\n // Written exactly once, before any listener exists, so it is the element's own\n // initial content rather than a programmatic overwrite of it.\n this.input.value = options.value ?? ''\n this.box.appendChild(this.input)\n\n this.popup = new Popup(\n this.document,\n {\n accept: (index) => {\n this.acceptCompletion(index)\n },\n hover: (index) => {\n this.setActive(index)\n },\n },\n this.instanceId,\n )\n this.element.appendChild(this.popup.element)\n this.input.setAttribute('aria-controls', this.popup.listId)\n\n this.tooltip = new Tooltip(this.document)\n this.element.appendChild(this.tooltip.element)\n\n this.mirror = new TextMirror(this.document)\n this.mirror.mount(this.document.body ?? this.document.documentElement)\n\n // A width change invalidates both measurements: text wraps differently, and so\n // does the paint. This is also what performs the FIRST useful measurement, since\n // the constructor runs before the caller has mounted anything and an unmounted\n // field has no width to measure against.\n const Observer = (this.view as (Window & { ResizeObserver?: typeof ResizeObserver }) | undefined)\n ?.ResizeObserver\n if (typeof Observer === 'function') {\n this.resizeObserver = new Observer(() => {\n const width = this.element.clientWidth\n if (width === this.observedWidth) return\n this.observedWidth = width\n this.mirror.adopt(this.input)\n this.resize(this.input.value)\n this.placePopup()\n })\n this.resizeObserver.observe(this.element)\n }\n\n const fonts = (this.document as Document & { fonts?: { ready?: Promise<unknown> } }).fonts\n this.fontsReady = fonts?.ready\n\n this.bind()\n this.sync()\n // A web font arriving after the first paint changes every metric the mirror\n // copied, so the box is re-measured once it lands. Without this the editor is a\n // few pixels off until something else makes it re-layout, which is the classic\n // \"it looks wrong until you click it\" bug.\n if (this.fontsReady !== undefined) {\n void this.fontsReady.then(() => {\n if (!this.destroyed) this.refresh()\n })\n }\n }\n\n // ── what a host reads ──────────────────────────────────────────────────────\n\n /** The current text. */\n get value(): string {\n return this.input.value\n }\n\n /** The caret or selection. */\n get selection(): TextSelection {\n return readSelection(this.input)\n }\n\n /** The last inspection, or undefined before the first one. */\n get inspection(): Inspection<State> | undefined {\n return this.current\n }\n\n /** The problems the grammar found. */\n get diagnostics(): readonly Diagnostic[] {\n return this.current?.diagnostics ?? []\n }\n\n /** The list on screen, when one is. */\n get currentCompletion(): Completion | undefined {\n return this.completionState\n }\n\n /** Whether the editor has focus. */\n get focused(): boolean {\n return this.document.activeElement === this.input\n }\n\n // ── what a host calls ─────────────────────────────────────────────────────\n\n /**\n * Replace the text.\n *\n * `preserveHistory` writes through the editing pipeline, so the replacement is\n * one undoable edit and Ctrl+Z brings the old text back — what a Reset button\n * wants. Without it the value property is assigned, which is faster and clears\n * the history, which is what loading a different document wants.\n *\n * This is the only path that writes the text, and it is never used for an edit\n * the user could have made.\n * @param next - the new text.\n * @param preserveHistory - whether Ctrl+Z should be able to undo it.\n * @returns how the write landed.\n */\n setValue(next: string, preserveHistory = false): EditOutcome {\n if (this.input.value === next) return 'unchanged'\n // Marked as the editor's own write, because a history-preserving write fires an\n // `input` event and everything downstream listens for one. Without this the caller is\n // handed its own change back through `onChange`, and a host that stores what it is\n // told would write its own value twice.\n this.applying = true\n let outcome: EditOutcome\n try {\n outcome = writeDocument(this.input, next, preserveHistory)\n } finally {\n this.applying = false\n }\n this.sync()\n return outcome\n }\n\n /**\n * Put the caret somewhere.\n * @param start - the anchor offset.\n * @param end - the moving offset; defaults to `start`.\n */\n setSelection(start: number, end: number = start): void {\n writeSelection(this.input, start, end)\n this.updateCompletionForCaret()\n }\n\n /** Move the caret into the field. */\n focus(): void {\n this.input.focus()\n }\n\n /** Undo, through the browser's history. */\n undo(): boolean {\n const done = undoField(this.input)\n if (done) this.sync()\n return done\n }\n\n /** Redo, through the browser's history. */\n redo(): boolean {\n const done = redoField(this.input)\n if (done) this.sync()\n return done\n }\n\n /**\n * Set CSS custom properties on the wrapper, replacing whatever this method set last time.\n *\n * A property that has disappeared from the record is removed rather than left behind, so a\n * host can un-theme by passing a smaller object. Properties set by other means — a stylesheet,\n * or the wrapper's inline style directly — are not touched, and a removed one falls back to\n * whatever CSS says.\n *\n * Safe to call at any time after construction. The constructor uses the private write-only\n * half, because re-measuring needs the field, the mirror, and the overlay, none of which exist\n * until it has finished.\n * @param next - the properties, keyed as {@link LiteAreaOptions.variables} describes.\n */\n setVariables(next: Readonly<Record<string, string>>): void {\n this.applyVariables(next)\n // A font or a line height changes every measurement, so the box is re-measured rather than\n // waiting for the next keystroke to notice.\n this.mirror.adopt(this.input)\n this.appliedHeight = -1\n this.sync()\n }\n\n /** Write the properties, and forget the ones that are gone. No re-measure. */\n private applyVariables(next: Readonly<Record<string, string>>): void {\n const keep = new Set<string>()\n for (const [key, value] of Object.entries(next)) {\n const name = variableName(key)\n keep.add(name)\n this.element.style.setProperty(name, value)\n }\n for (const name of this.appliedVariables) {\n if (!keep.has(name)) this.element.style.removeProperty(name)\n }\n this.appliedVariables = keep\n }\n\n /**\n * Re-read the document with the same text.\n *\n * For a host whose grammar depends on something outside it — an installed font\n * list that has just been re-read, a palette that changed — and for the moment a\n * web font finishes loading.\n *\n * The grammar is re-resolved here, which is what makes a live grammar object\n * work: a host that rebuilds its rules on every render can call `refresh()` and\n * the editor picks the new ones up without being rebuilt, so the undo history\n * survives a language change.\n */\n refresh(): void {\n this.grammar = resolveGrammar(this.declaredGrammar)\n this.current = undefined\n this.currentText = undefined\n this.mirror.adopt(this.input)\n this.overlay.invalidate()\n this.appliedHeight = -1\n this.appliedOverflow = ''\n this.appliedScrollbar = -1\n this.sync()\n }\n\n /** Open the completion list on demand, as Ctrl+Space does. */\n showCompletions(): void {\n if (this.completion === undefined) return\n this.openCompletion('explicit')\n }\n\n /** Close the completion list. */\n hideCompletions(): void {\n this.closeCompletion()\n }\n\n /** Remove the editor and every listener it owns. */\n destroy(): void {\n if (this.destroyed) return\n this.destroyed = true\n this.unbind()\n this.resizeObserver?.disconnect()\n this.resizeObserver = undefined\n if (this.hoverTimer !== undefined) this.view?.clearTimeout(this.hoverTimer)\n this.popup.destroy()\n this.tooltip.destroy()\n this.overlay.destroy()\n this.mirror.destroy()\n // The injected sheet is shared by every editor on the page, so it stays:\n // removing it would unstyle the others.\n void this.injectedStyle\n this.element.remove()\n }\n\n // ── the pipeline ──────────────────────────────────────────────────────────\n\n /**\n * Bring everything up to date with the field.\n *\n * The inspection is cached on the text, so moving the caret or scrolling costs\n * nothing beyond the paint — and the paint itself is skipped when neither the\n * text nor the analysis changed.\n */\n private sync(): void {\n const text = this.input.value\n if (this.current === undefined || this.currentText !== text) {\n this.current = inspect(text, this.grammar)\n this.currentText = text\n this.revision += 1\n }\n const inspection = this.current\n this.paint(inspection)\n this.resize(text)\n this.overlay.syncScroll(this.input)\n this.announceDiagnostics(inspection)\n }\n\n /** Paint the layer, and mark the box when a problem is an error. */\n private paint(inspection: Inspection<State>): void {\n const painting: SegmentInput = {\n tokens: inspection.tokens,\n decorations: this.paintDecorations ? inspection.decorations : [],\n diagnostics: inspection.diagnostics,\n }\n const key = [\n String(this.revision),\n this.paintDecorations ? 'd' : '-',\n String(painting.decorations.length),\n String(painting.diagnostics.length),\n ].join(':')\n this.overlay.render(inspection.text, painting, key, this.grammar.fallbackScope)\n const hasError = inspection.diagnostics.some((diagnostic) => diagnostic.severity === 'error')\n this.element.classList.toggle('litearea-invalid', hasError)\n this.input.setAttribute('aria-invalid', hasError ? 'true' : 'false')\n }\n\n /** Tell the host, once, when the problem list actually changed. */\n private announceDiagnostics(inspection: Inspection<State>): void {\n if (this.handlers.onDiagnostics === undefined) return\n const key = inspection.diagnostics\n .map(\n (diagnostic) =>\n `${String(diagnostic.from)}:${diagnostic.code ?? ''}:${diagnostic.message}`,\n )\n .join('|')\n if (key === this.announced) return\n this.announced = key\n this.handlers.onDiagnostics(inspection.diagnostics)\n }\n\n /**\n * Size the box to its content.\n *\n * The mirror has no scrollbar, so its measurement is the height the content wants\n * with the full width available — which is exactly the number that decides whether\n * a scrollbar is needed at all. If it fits under the maximum, the height becomes\n * the content height and the overflow stays hidden, which is the promise of \"grow\n * and shrink so no scrollbar is ever shown\". If it does not fit, the height is\n * clamped and the overflow becomes `auto`.\n *\n * Clamping introduces a second problem that is easy to miss: a scrollbar narrows\n * the text, so the field rewraps, so the PAINT no longer wraps the same way and\n * every coloured span slides off its character. The measured scrollbar width is\n * therefore published as a custom property, and the stylesheet adds it to the\n * layer's own right padding so the two keep wrapping identically.\n *\n * An UNMOUNTED field is skipped rather than measured. Before the element is in the\n * document it has no layout, so its `clientWidth` is zero, the mirror wraps at every\n * character, and the measurement comes back several times too tall — a wrong height\n * that then has to be corrected on the next keystroke, which is what a box that\n * jumps on first focus actually is. The `ResizeObserver` installed at construction\n * does the first real measurement as soon as there is a width to measure against.\n * @param text - the current text.\n */\n private resize(text: string): void {\n if (!this.sizing.autoGrow) {\n // Still adopted, because caret geometry depends on the mirror being shaped like\n // the field even when the field's height is the host's business.\n this.mirror.adopt(this.input)\n return\n }\n if (!this.input.isConnected || this.input.clientWidth === 0) return\n const chrome = this.mirror.verticalPadding()\n const lineHeight = this.mirror.lineHeight(this.input)\n const minPx = Math.max(\n this.sizing.minHeight ?? 0,\n lineHeight * (this.sizing.minRows ?? 1) + chrome,\n )\n const maxCandidate = Math.min(\n this.sizing.maxHeight ?? Number.POSITIVE_INFINITY,\n this.sizing.maxRows === undefined\n ? Number.POSITIVE_INFINITY\n : lineHeight * this.sizing.maxRows + chrome,\n )\n // A maximum below the minimum is a host mistake, and honouring it would make\n // the box smaller than the host was told it could be.\n const maxPx = Math.max(maxCandidate, minPx)\n\n const content = this.mirror.contentHeight(this.input, text)\n const wanted = clamp(Math.max(content, minPx), minPx, maxPx)\n const overflow = content > wanted + 0.5 ? 'auto' : 'hidden'\n\n if (Math.abs(wanted - this.appliedHeight) > 0.5) {\n this.input.style.height = `${String(Math.round(wanted))}px`\n this.appliedHeight = wanted\n }\n if (overflow !== this.appliedOverflow) {\n this.input.style.overflowY = overflow\n this.appliedOverflow = overflow\n }\n // Read AFTER the overflow is applied, because that is when a scrollbar exists\n // and therefore when there is a width to report.\n const scrollbar = overflow === 'auto' ? this.input.offsetWidth - this.input.clientWidth : 0\n const width = Math.max(0, scrollbar)\n if (width !== this.appliedScrollbar) {\n this.element.style.setProperty('--litearea-scrollbar', `${String(width)}px`)\n this.appliedScrollbar = width\n }\n }\n\n // ── completion ────────────────────────────────────────────────────────────\n\n /** The caret's offset, clamped into the text. */\n private caret(): number {\n return clamp(readSelection(this.input).start, 0, this.input.value.length)\n }\n\n /** Resolve and show a list for the caret. */\n private openCompletion(trigger: CompletionTrigger): void {\n if (this.completion === undefined || this.current === undefined) return\n // The source that answered last time is passed back so the same one answers again\n // while it stays eligible. The RANGE is deliberately not held: it is recomputed from\n // the caret on every call, so it grows with the word being typed.\n const result = complete(this.current, this.grammar, {\n text: this.input.value,\n caret: this.caret(),\n trigger,\n previousSourceId: this.completionState?.sourceId,\n limit: this.completion.limit,\n })\n if (result === undefined || result.rows.length === 0) {\n this.closeCompletion()\n return\n }\n this.completionState = result\n this.popup.show(result.rows, 0, this.completion.showDocumentation)\n this.input.setAttribute('aria-expanded', 'true')\n this.syncActiveDescendant()\n this.placePopup()\n this.handlers.onCompletion?.(result)\n }\n\n /** Close the list and tell the host. */\n private closeCompletion(): void {\n if (this.completionState === undefined && !this.popup.isOpen) return\n this.completionState = undefined\n this.popup.close()\n this.input.setAttribute('aria-expanded', 'false')\n this.input.removeAttribute('aria-activedescendant')\n this.handlers.onCompletion?.(undefined)\n }\n\n /** Keep the field's `aria-activedescendant` pointing at the active row. */\n private syncActiveDescendant(): void {\n const id = this.popup.activeRowId\n if (id === undefined) this.input.removeAttribute('aria-activedescendant')\n else this.input.setAttribute('aria-activedescendant', id)\n }\n\n /** Put the list under the caret. */\n private placePopup(): void {\n if (this.completionState === undefined) return\n const box = this.mirror.caretBox(this.input, this.caret())\n if (box === undefined) return\n // The mirror reports relative to the field's border box; the list is positioned\n // against the wrapper. Measuring both rects is used rather than `offsetLeft`\n // arithmetic, because `offsetParent` changes as soon as a host wraps the editor\n // in something positioned, and the caret must not notice.\n const inputRect = this.input.getBoundingClientRect()\n const elementRect = this.element.getBoundingClientRect()\n this.popup.place(\n {\n x: inputRect.left - elementRect.left + box.x,\n y: inputRect.top - elementRect.top + box.y,\n height: box.height,\n },\n this.element,\n { width: this.view?.innerWidth ?? 0, height: this.view?.innerHeight ?? 0 },\n )\n }\n\n /**\n * Take the active row.\n * @param index - the row to take.\n * @param commitCharacter - a character typed to trigger the pick, written after\n * the completion so the keystroke is not swallowed.\n */\n private acceptCompletion(index: number, commitCharacter?: string): void {\n const state = this.completionState\n const row: SuggestionItem | undefined = this.popup.items[index]?.item\n if (state === undefined || row === undefined) return\n const applied = applyCompletion(this.input.value, state.range, row)\n this.applying = true\n try {\n // Only the range that changed is written, and it goes through the editing\n // pipeline, so Ctrl+Z undoes the completion as one edit and the rest of the\n // document — and its history — is untouched.\n replaceThroughPipeline(this.input, applied.from, applied.to, applied.insert)\n writeSelection(this.input, applied.caret)\n if (commitCharacter !== undefined) {\n replaceThroughPipeline(this.input, applied.caret, applied.caret, commitCharacter)\n writeSelection(this.input, applied.caret + commitCharacter.length)\n }\n } finally {\n this.applying = false\n }\n this.closeCompletion()\n this.sync()\n const inspection = this.current\n if (inspection !== undefined) {\n this.grammar.grammar.onAccept?.({\n text: this.input.value,\n caret: this.caret(),\n item: row,\n state: inspection.state,\n })\n }\n }\n\n /** Decide what an edit does to the list. */\n private updateCompletionAfterInput(data: string, deletion: boolean): void {\n if (this.completion === undefined || this.applying || this.composing) return\n if (this.input.readOnly) return\n if (deletion) {\n // Deleting inside an open list re-filters it; deleting with no list open opens\n // nothing, because a backspace is not a request for suggestions.\n if (this.completionState !== undefined) this.openCompletion('auto')\n return\n }\n if (this.completionState !== undefined) {\n this.openCompletion('auto')\n return\n }\n if (!this.completion.auto) return\n if (!this.shouldAutoOpen(data)) return\n this.openCompletion('auto')\n }\n\n /** Whether a keystroke is a reason to offer suggestions. */\n private shouldAutoOpen(data: string): boolean {\n if (data === '' || this.completion === undefined) return false\n const last = data.slice(-1)\n if (this.completion.triggerCharacters.includes(last)) return true\n return this.grammar.wordChars.test(last)\n }\n\n /** Close a list the caret has left. */\n private updateCompletionForCaret(): void {\n const state = this.completionState\n if (state === undefined) return\n const caret = this.caret()\n if (caret < state.range.from || caret > state.range.to) this.closeCompletion()\n else this.placePopup()\n }\n\n // ── hover ─────────────────────────────────────────────────────────────────\n\n /** Start, or restart, the timer that shows a tooltip. */\n private queueHover(offset: number, event: MouseEvent): void {\n if (this.hover === undefined || !this.hover.enabled || this.current === undefined) return\n if (offset === this.hoverOffset && this.tooltip.isOpen) return\n this.hoverOffset = offset\n this.hideTooltip()\n const clientX = event.clientX\n const clientY = event.clientY\n this.hoverTimer = this.view?.setTimeout(() => {\n this.hoverTimer = undefined\n this.showHover(offset, clientX, clientY)\n }, this.hover.delay)\n }\n\n /** Resolve and show a tooltip. */\n private showHover(offset: number, clientX: number, clientY: number): void {\n if (this.current === undefined || this.destroyed) return\n const info = resolveHover(this.current, this.grammar, offset)\n if (info === undefined) {\n this.hideTooltip()\n return\n }\n const rect = this.element.getBoundingClientRect()\n const lineHeight = this.mirror.lineHeight(this.input)\n this.tooltip.show(\n info,\n { x: clientX - rect.left, y: clientY - rect.top, height: lineHeight },\n this.element,\n { width: this.view?.innerWidth ?? 0, height: this.view?.innerHeight ?? 0 },\n )\n this.handlers.onHover?.(info)\n }\n\n /** Hide the tooltip and forget what it described. */\n private hideTooltip(): void {\n if (this.hoverTimer !== undefined) {\n this.view?.clearTimeout(this.hoverTimer)\n this.hoverTimer = undefined\n }\n if (!this.tooltip.isOpen) return\n this.tooltip.hide()\n this.handlers.onHover?.(undefined)\n }\n\n // ── events ────────────────────────────────────────────────────────────────\n\n /** Attach every listener. */\n private bind(): void {\n this.input.addEventListener('input', this.onInput)\n this.input.addEventListener('keydown', this.onKeyDown)\n this.input.addEventListener('scroll', this.onScroll)\n this.input.addEventListener('click', this.onCaretMoved)\n this.input.addEventListener('keyup', this.onKeyUp)\n this.input.addEventListener('select', this.onCaretMoved)\n this.input.addEventListener('blur', this.onBlur)\n this.input.addEventListener('mousemove', this.onMouseMove)\n this.input.addEventListener('mouseleave', this.onMouseLeave)\n this.input.addEventListener('compositionstart', this.onCompositionStart)\n this.input.addEventListener('compositionend', this.onCompositionEnd)\n this.document.addEventListener('selectionchange', this.onSelectionChange)\n }\n\n /** Detach every listener. */\n private unbind(): void {\n this.input.removeEventListener('input', this.onInput)\n this.input.removeEventListener('keydown', this.onKeyDown)\n this.input.removeEventListener('scroll', this.onScroll)\n this.input.removeEventListener('click', this.onCaretMoved)\n this.input.removeEventListener('keyup', this.onKeyUp)\n this.input.removeEventListener('select', this.onCaretMoved)\n this.input.removeEventListener('blur', this.onBlur)\n this.input.removeEventListener('mousemove', this.onMouseMove)\n this.input.removeEventListener('mouseleave', this.onMouseLeave)\n this.input.removeEventListener('compositionstart', this.onCompositionStart)\n this.input.removeEventListener('compositionend', this.onCompositionEnd)\n this.document.removeEventListener('selectionchange', this.onSelectionChange)\n }\n\n private readonly onInput = (event: Event): void => {\n this.sync()\n const input = event as InputEvent\n const type = input.inputType ?? ''\n const deletion = type.startsWith('delete')\n const data = typeof input.data === 'string' ? input.data : ''\n // Typing is not a request for a tooltip, and leaving one up over text that has\n // moved is worse than not having shown it.\n this.hideTooltip()\n this.updateCompletionAfterInput(data, deletion)\n if (!this.applying) this.handlers.onChange?.(this.input.value)\n }\n\n private readonly onKeyDown = (event: KeyboardEvent): void => {\n // First, because a keystroke a row asked for is a pick and not text.\n if (this.commitCharacter(event)) return\n\n if (event.key === 'Escape') {\n if (this.popup.isOpen) {\n event.preventDefault()\n this.closeCompletion()\n return\n }\n this.hideTooltip()\n return\n }\n\n if (event.key === ' ' && (event.ctrlKey || event.metaKey)) {\n event.preventDefault()\n if (this.popup.isOpen) this.closeCompletion()\n else this.openCompletion('explicit')\n return\n }\n\n if (!this.popup.isOpen) return\n const last = this.popup.items.length - 1\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault()\n // No wrapping, because a list that jumps from the end back to the start on\n // one arrow press is a list nobody can navigate deliberately.\n this.setActive(Math.min(this.popup.activeIndex + 1, last))\n return\n case 'ArrowUp':\n event.preventDefault()\n this.setActive(Math.max(this.popup.activeIndex - 1, 0))\n return\n case 'PageDown':\n event.preventDefault()\n this.setActive(Math.min(this.popup.activeIndex + PAGE_STEP, last))\n return\n case 'PageUp':\n event.preventDefault()\n this.setActive(Math.max(this.popup.activeIndex - PAGE_STEP, 0))\n return\n case 'Enter':\n event.preventDefault()\n this.acceptCompletion(this.popup.activeIndex)\n return\n case 'Tab':\n event.preventDefault()\n this.acceptCompletion(this.popup.activeIndex)\n return\n default:\n return\n }\n }\n\n /**\n * Whether a keystroke is a commit character for the active row.\n *\n * Typing `=` at the end of `shape` takes the `shape=` row and keeps the\n * character, rather than either swallowing the keystroke or leaving the row to be\n * clicked. A row opts in; nothing has a commit character by default.\n * @param event - the key event.\n * @returns whether the keystroke was consumed.\n */\n private commitCharacter(event: KeyboardEvent): boolean {\n if (!this.popup.isOpen) return false\n if (event.key.length !== 1 || event.ctrlKey || event.metaKey || event.altKey) return false\n const characters = this.popup.activeRow?.item.commitCharacters\n if (characters === undefined || !characters.includes(event.key)) return false\n event.preventDefault()\n this.acceptCompletion(this.popup.activeIndex, event.key)\n return true\n }\n\n /** Make a row active and keep the ARIA pointer in step. */\n private setActive(index: number): void {\n this.popup.setActive(index)\n this.syncActiveDescendant()\n }\n\n private readonly onScroll = (): void => {\n this.overlay.syncScroll(this.input)\n this.placePopup()\n this.hideTooltip()\n }\n\n private readonly onCaretMoved = (): void => {\n this.updateCompletionForCaret()\n this.handlers.onSelectionChange?.(readSelection(this.input))\n }\n\n private readonly onKeyUp = (event: KeyboardEvent): void => {\n // Shift+Arrow and Home/End move the caret without an `input` event, and a list\n // left open over a caret that has walked out of its range would complete the\n // wrong thing.\n if (event.key.startsWith('Arrow') || event.key === 'Home' || event.key === 'End') {\n this.updateCompletionForCaret()\n }\n }\n\n private readonly onSelectionChange = (): void => {\n if (this.document.activeElement !== this.input) return\n this.handlers.onSelectionChange?.(readSelection(this.input))\n }\n\n private readonly onBlur = (): void => {\n // A pick beats this, because the list cancels the default on `mousedown`; a\n // genuine blur closes everything.\n this.closeCompletion()\n this.hideTooltip()\n }\n\n private readonly onMouseMove = (event: MouseEvent): void => {\n if (this.hover === undefined || !this.hover.enabled) return\n if (this.popup.isOpen) {\n this.hideTooltip()\n return\n }\n // The BROWSER is asked where the pointer is in the text, rather than the editor\n // measuring wrapped proportional glyphs by hand — which is exactly the geometry\n // a hand-written measurement always gets slightly wrong.\n const offset = caretOffsetFromPoint(this.document, event.clientX, event.clientY)\n if (offset === undefined) return\n this.queueHover(offset, event)\n }\n\n private readonly onMouseLeave = (): void => {\n this.hoverOffset = undefined\n this.hideTooltip()\n }\n\n private readonly onCompositionStart = (): void => {\n this.composing = true\n this.closeCompletion()\n }\n\n private readonly onCompositionEnd = (): void => {\n this.composing = false\n this.sync()\n }\n}\n\n/**\n * The full custom-property name for a key a host may have written in a few ways.\n *\n * `font`, `litearea-font`, and `--litearea-font` all mean the same property; a key that already\n * begins with `--` is used verbatim, so `--litearea-font` and a host's own `--my-brand` both\n * work without the editor having to guess which prefix was meant.\n * @param key - the key as written.\n * @returns the custom-property name.\n */\nfunction variableName(key: string): string {\n if (key.startsWith('--')) return key\n return key.startsWith('litearea-') ? `--${key}` : `--litearea-${key}`\n}\n\n/**\n * The caret offset a viewport point falls on.\n *\n * A free function so the editor does not reach into the document for it, and so the\n * two spellings of the API live in one place.\n * @param ownerDocument - the document.\n * @param x - viewport x.\n * @param y - viewport y.\n * @returns the offset, or undefined when the browser cannot say.\n */\nfunction caretOffsetFromPoint(\n ownerDocument: Document,\n x: number,\n y: number,\n): number | undefined {\n const probe = ownerDocument as Document & {\n caretPositionFromPoint?: (x: number, y: number) => { offset: number } | null\n caretRangeFromPoint?: (x: number, y: number) => Range | null\n }\n if (typeof probe.caretPositionFromPoint === 'function') {\n return probe.caretPositionFromPoint(x, y)?.offset\n }\n if (typeof probe.caretRangeFromPoint === 'function') {\n return probe.caretRangeFromPoint(x, y)?.startOffset\n }\n return undefined\n}\n\n/** A severity, re-exported so a host can narrow a diagnostic without importing core. */\nexport type EditorSeverity = Severity\n\n/** A range, re-exported for the same reason. */\nexport type EditorRange = Range\n\n/** A decoration, re-exported for the same reason. */\nexport type EditorDecoration = Decoration\n","// ─── create: the one-line entry point ───────────────────────────────────────\n//\n// The class exists for a host that wants to hold the instance and drive it. This\n// exists for the far more common case of wanting an editor in an element and not\n// much else.\n\nimport { LiteArea, type LiteAreaOptions } from './editor.js'\n\n/**\n * Build an editor and put it in an element.\n *\n * The `refresh` after mounting is not a formality. A textarea that is not in the\n * document has no layout, so it has no width, so nothing can be measured against it\n * — and a measurement taken then is not merely imprecise, it wraps the text at every\n * character and comes back several times too tall. The editor's own\n * `ResizeObserver` would correct it on the next frame, which means one frame of a box\n * at the wrong height. Measuring again here, synchronously, means the first frame is\n * already right.\n * @param target - where to mount it. Its contents are appended to, not replaced.\n * @param options - the grammar, the initial text, and the behaviour to use.\n * @returns the editor, so the caller can drive it.\n */\nexport function createEditor<State = unknown>(\n target: Element,\n options: LiteAreaOptions<State>,\n): LiteArea<State> {\n const editor = new LiteArea(options)\n target.appendChild(editor.element)\n editor.refresh()\n return editor\n}\n"]}
|