@vscode/markdown-editor 0.0.2-0 → 0.0.2-2

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.
Files changed (96) hide show
  1. package/dist/_observables/assert.d.ts +2 -0
  2. package/dist/_observables/deps.d.ts +28 -0
  3. package/dist/_observables/disposables.d.ts +19 -0
  4. package/dist/_observables/equals.d.ts +32 -0
  5. package/dist/_observables/index.d.ts +2 -0
  6. package/dist/_observables/observableInternal/base.d.ts +172 -0
  7. package/dist/_observables/observableInternal/changeTracker.d.ts +44 -0
  8. package/dist/_observables/observableInternal/commonFacade/cancellation.d.ts +24 -0
  9. package/dist/_observables/observableInternal/commonFacade/deps.d.ts +24 -0
  10. package/dist/_observables/observableInternal/debugLocation.d.ts +21 -0
  11. package/dist/_observables/observableInternal/debugName.d.ts +33 -0
  12. package/dist/_observables/observableInternal/experimental/deferUnobserve.d.ts +16 -0
  13. package/dist/_observables/observableInternal/experimental/reducer.d.ts +37 -0
  14. package/dist/_observables/observableInternal/experimental/utils.d.ts +15 -0
  15. package/dist/_observables/observableInternal/index.d.ts +25 -0
  16. package/dist/_observables/observableInternal/logging/consoleObservableLogger.d.ts +40 -0
  17. package/dist/_observables/observableInternal/logging/debugGetDependencyGraph.d.ts +4 -0
  18. package/dist/_observables/observableInternal/logging/debugger/debuggerRpc.d.ts +4 -0
  19. package/dist/_observables/observableInternal/logging/debugger/devToolsLogger.d.ts +43 -0
  20. package/dist/_observables/observableInternal/logging/debugger/rpc.d.ts +41 -0
  21. package/dist/_observables/observableInternal/logging/debugger/utils.d.ts +13 -0
  22. package/dist/_observables/observableInternal/logging/logging.d.ts +30 -0
  23. package/dist/_observables/observableInternal/map.d.ts +18 -0
  24. package/dist/_observables/observableInternal/observables/baseObservable.d.ts +58 -0
  25. package/dist/_observables/observableInternal/observables/constObservable.d.ts +5 -0
  26. package/dist/_observables/observableInternal/observables/derived.d.ts +46 -0
  27. package/dist/_observables/observableInternal/observables/derivedImpl.d.ts +83 -0
  28. package/dist/_observables/observableInternal/observables/lazyObservableValue.d.ts +27 -0
  29. package/dist/_observables/observableInternal/observables/observableFromEvent.d.ts +37 -0
  30. package/dist/_observables/observableInternal/observables/observableSignal.d.ts +11 -0
  31. package/dist/_observables/observableInternal/observables/observableSignalFromEvent.d.ts +5 -0
  32. package/dist/_observables/observableInternal/observables/observableValue.d.ts +37 -0
  33. package/dist/_observables/observableInternal/observables/observableValueOpts.d.ts +8 -0
  34. package/dist/_observables/observableInternal/reactions/autorun.d.ts +56 -0
  35. package/dist/_observables/observableInternal/reactions/autorunImpl.d.ts +53 -0
  36. package/dist/_observables/observableInternal/set.d.ts +17 -0
  37. package/dist/_observables/observableInternal/transaction.d.ts +27 -0
  38. package/dist/_observables/observableInternal/utils/promise.d.ts +75 -0
  39. package/dist/_observables/observableInternal/utils/runOnChange.d.ts +7 -0
  40. package/dist/_observables/observableInternal/utils/utils.d.ts +43 -0
  41. package/dist/_observables/observableInternal/utils/utilsCancellation.d.ts +10 -0
  42. package/dist/_observables/observableInternal/utils/valueWithChangeEvent.d.ts +10 -0
  43. package/dist/_observables/utils.d.ts +15 -0
  44. package/dist/index.d.ts +1769 -6
  45. package/dist/observables.d.ts +4 -1
  46. package/package.json +1 -1
  47. package/dist/commands/cursorCommands.d.ts +0 -13
  48. package/dist/commands/editCommands.d.ts +0 -14
  49. package/dist/commands/index.d.ts +0 -4
  50. package/dist/commands/selectionCommands.d.ts +0 -6
  51. package/dist/commands/types.d.ts +0 -26
  52. package/dist/core/geometry.d.ts +0 -37
  53. package/dist/core/index.d.ts +0 -8
  54. package/dist/core/lengthEdit.d.ts +0 -38
  55. package/dist/core/offsetRange.d.ts +0 -26
  56. package/dist/core/selection.d.ts +0 -13
  57. package/dist/core/sourceOffset.d.ts +0 -1
  58. package/dist/core/stringEdit.d.ts +0 -27
  59. package/dist/core/stringValue.d.ts +0 -8
  60. package/dist/core/wordUtils.d.ts +0 -6
  61. package/dist/highlighter/defaultMonacoSyntaxHighlighter.d.ts +0 -20
  62. package/dist/highlighter/index.d.ts +0 -3
  63. package/dist/highlighter/monacoSyntaxHighlighter.d.ts +0 -38
  64. package/dist/highlighter/syntaxHighlighter.d.ts +0 -67
  65. package/dist/model/cursorNavigation.d.ts +0 -7
  66. package/dist/model/editorModel.d.ts +0 -54
  67. package/dist/model/index.d.ts +0 -4
  68. package/dist/model/measuredLayoutModel.d.ts +0 -50
  69. package/dist/parser/_micromarkAdapter.d.ts +0 -7
  70. package/dist/parser/ast.d.ts +0 -274
  71. package/dist/parser/index.d.ts +0 -4
  72. package/dist/parser/parse.d.ts +0 -2
  73. package/dist/parser/parser.d.ts +0 -14
  74. package/dist/parser/reconcile.d.ts +0 -33
  75. package/dist/parser/test/getAnnotatedSource.d.ts +0 -2
  76. package/dist/parser/test/snapshot.d.ts +0 -9
  77. package/dist/parser/visualizeAst.d.ts +0 -33
  78. package/dist/test/random.d.ts +0 -16
  79. package/dist/view/content/blockView.d.ts +0 -179
  80. package/dist/view/content/documentView.d.ts +0 -41
  81. package/dist/view/content/dom.d.ts +0 -16
  82. package/dist/view/content/katexEditableIdentifiers.d.ts +0 -36
  83. package/dist/view/content/viewNode.d.ts +0 -93
  84. package/dist/view/editorController.d.ts +0 -34
  85. package/dist/view/editorView.d.ts +0 -100
  86. package/dist/view/fixture/astViewerView.d.ts +0 -27
  87. package/dist/view/fixture/cyclingTsHighlighter.d.ts +0 -17
  88. package/dist/view/fixture/debugColors.d.ts +0 -26
  89. package/dist/view/fixture/monacoDebugPanel.d.ts +0 -7
  90. package/dist/view/index.d.ts +0 -9
  91. package/dist/view/measuredLayoutDebugView.d.ts +0 -70
  92. package/dist/view/parts/cursorView.d.ts +0 -29
  93. package/dist/view/parts/selectionView.d.ts +0 -57
  94. package/dist/view/viewData.d.ts +0 -251
  95. package/dist/view/visualLineMap.d.ts +0 -157
  96. package/dist/view/visualizeViewTree.d.ts +0 -5
package/dist/index.d.ts CHANGED
@@ -1,6 +1,1769 @@
1
- export * from './core/index.js';
2
- export * from './parser/index.js';
3
- export * from './model/index.js';
4
- export * from './commands/index.js';
5
- export * from './view/index.js';
6
- export * from './highlighter/index.js';
1
+ import { Disposable } from './_observables/index';
2
+ import { IDisposable } from './_observables/index';
3
+ import { IObservable } from './_observables/index';
4
+ import { IObservableWithChange } from './_observables/index';
5
+ import { ISettableObservable } from './_observables/index';
6
+ import { ITransaction } from './_observables/index';
7
+ import { MonarchTokenizer } from 'monaco-editor/esm/vs/editor/standalone/common/monarch/monarchLexer.js';
8
+
9
+ /** Every concrete node kind, for exhaustive consumer-side dispatch. */
10
+ export declare type AnyAstNode = TextAstNode | MarkerAstNode | GlueAstNode | ThematicBreakAstNode | StrongAstNode | EmphasisAstNode | StrikethroughAstNode | InlineCodeAstNode | InlineMathAstNode | LinkAstNode | ImageAstNode | HeadingAstNode | ParagraphAstNode | CodeBlockAstNode | MathBlockAstNode | BlockQuoteAstNode | ListAstNode | ListItemAstNode | TableAstNode | TableRowAstNode | TableCellAstNode | DocumentAstNode;
11
+
12
+ declare type AnyViewData = DocumentViewData | BlockViewData | InlineViewData | ListItemViewData | TableRowViewData | TableCellViewData | MarkerViewData | GlueViewData;
13
+
14
+ export declare abstract class AstNode {
15
+ abstract readonly kind: string;
16
+ abstract get children(): readonly AstNode[];
17
+ /**
18
+ * A stable identity. Every node has one: it is minted on construction and
19
+ * carried across edits by reconciliation, so a node that survives an edit
20
+ * (even with changed content) keeps the same id.
21
+ */
22
+ readonly id: number;
23
+ /** Rebuild this node with each child replaced by `map.get(child) ?? child`. */
24
+ abstract mapChildren(map: ReadonlyMap<AstNode, AstNode>): AstNode;
25
+ private _length;
26
+ get length(): number;
27
+ /**
28
+ * True when `other` has the same content. Containers compare children *by
29
+ * identity* (`===`): bottom-up reconciliation substitutes reused old
30
+ * instances into the fresh tree first, so equal children already share
31
+ * instances — keeping this O(children), not O(subtree). Leaves have no
32
+ * children, so {@link _localEquals} is their whole comparison.
33
+ */
34
+ structurallyEqual(other: AstNode): boolean;
35
+ /** Compares only this node's own scalar fields (kind/length already match). */
36
+ protected _localEquals(_other: this): boolean;
37
+ /**
38
+ * A copy of this node that adopts `id`. Reconciliation uses this to carry an
39
+ * old identity onto a node whose content changed. Nodes are immutable value
40
+ * holders, so a shallow prototype copy with `id` overridden is sound.
41
+ */
42
+ cloneWithId(id: number): this;
43
+ }
44
+
45
+ export declare interface AstVisualization {
46
+ $fileExtension: 'ast.w';
47
+ source: string;
48
+ root: AstVisualizationNode;
49
+ }
50
+
51
+ declare interface AstVisualizationNode {
52
+ label: string;
53
+ range: [start: number, endExclusive: number];
54
+ children?: AstVisualizationNode[];
55
+ }
56
+
57
+ export declare type BlockAstNode = HeadingAstNode | ParagraphAstNode | CodeBlockAstNode | MathBlockAstNode | ThematicBreakAstNode | BlockQuoteAstNode | ListAstNode | TableAstNode;
58
+
59
+ /**
60
+ * One block's place in the rendered document.
61
+ *
62
+ * `height` is in CSS pixels. It is either a real DOM measurement
63
+ * (`isMeasured: true`) or an estimate produced when the block is not
64
+ * currently mounted (`isMeasured: false`). Estimates exist so virtual
65
+ * rendering can size the scroll container without mounting every block.
66
+ *
67
+ * `visualLineMap` and `viewNode` are set only when the block is mounted
68
+ * and measured. Cursor positioning, selection painting and up/down
69
+ * navigation read through `visualLineMap`; the debug view walks
70
+ * `viewNode` to enumerate text leaves for per-character introspection.
71
+ * Unmeasured blocks have neither.
72
+ */
73
+ export declare interface BlockMeasurement {
74
+ readonly block: BlockAstNode;
75
+ readonly absoluteStart: number;
76
+ readonly height: number;
77
+ readonly isMeasured: boolean;
78
+ readonly visualLineMap: VisualLineMap | undefined;
79
+ readonly viewNode: ViewNode | undefined;
80
+ }
81
+
82
+ export declare class BlockQuoteAstNode extends AstNode {
83
+ readonly content: readonly (MarkerAstNode | BlockAstNode | GlueAstNode)[];
84
+ readonly kind = "blockQuote";
85
+ constructor(content: readonly (MarkerAstNode | BlockAstNode | GlueAstNode)[]);
86
+ get children(): readonly AstNode[];
87
+ get blocks(): readonly BlockAstNode[];
88
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
89
+ }
90
+
91
+ declare class BlockQuoteViewData {
92
+ readonly ast: BlockQuoteAstNode;
93
+ readonly content: readonly AnyViewData[];
94
+ readonly kind = "blockQuote";
95
+ constructor(ast: BlockQuoteAstNode, content: readonly AnyViewData[]);
96
+ }
97
+
98
+ declare type BlockViewData = HeadingViewData | ParagraphViewData | CodeBlockViewData | MathBlockViewData | ThematicBreakViewData | BlockQuoteViewData | ListViewData | TableViewData;
99
+
100
+ /**
101
+ * Base view node for everything the editor renders, generic over the
102
+ * {@link AnyViewData view-data} it renders so subclasses get a precisely-typed
103
+ * {@link data} (e.g. `BlockViewNode<HeadingViewData>`). Every view-data kind has
104
+ * a subclass whose constructor builds the node's DOM and, recursively,
105
+ * constructs its child view nodes — so *constructing a node is rendering it*.
106
+ * There is no separate render pass: the view tree is the result of construction,
107
+ * and {@link createViewNode} is the single entry point that turns a `ViewData`
108
+ * into a node (reusing a `previous` node untouched when it still matches).
109
+ *
110
+ * The name is historical — it is the base for inline and leaf nodes too — but
111
+ * top-level blocks are always instances of it, and {@link element}/{@link block}
112
+ * are the conveniences {@link EditorView} uses for those.
113
+ */
114
+ export declare class BlockViewNode<T extends AnyViewData = AnyViewData> extends ViewNode {
115
+ readonly data: T;
116
+ constructor(data: T, dom: globalThis.Node, children: readonly ViewNode[]);
117
+ get block(): BlockAstNode;
118
+ get element(): HTMLElement;
119
+ /**
120
+ * Whether this already-built node can stand in for `data` unchanged. The
121
+ * builder preserves view-data identity for any subtree whose ast and
122
+ * selection-derived flags are unchanged (see `buildDocumentViewData`), so a
123
+ * single identity check captures "nothing in my subtree changed" — and its
124
+ * whole subtree, and any session it owns, are kept as-is.
125
+ */
126
+ canReuse(data: AnyViewData): boolean;
127
+ /**
128
+ * Called by the view after this block is mounted and measured, with the
129
+ * block's rendered height in px. The default is a no-op; subclasses whose
130
+ * active/inactive renderings have different intrinsic heights (e.g. a math
131
+ * block) override this to remember a height to reserve across the toggle.
132
+ */
133
+ recordMeasuredHeight(_height: number): void;
134
+ }
135
+
136
+ export declare interface BlockViewOptions {
137
+ readonly renderCustomCodeBlock?: (language: string, content: string) => HTMLElement | undefined;
138
+ readonly onToggleCheckbox?: (item: ListItemAstNode, newChecked: boolean) => void;
139
+ /**
140
+ * Opens a link's URL. Called when the user activates a link: a plain click
141
+ * while the link's block is inactive (rendered), or a Ctrl/Cmd+click while it
142
+ * is active (source shown). Defaults to `window.open(url, '_blank')`.
143
+ */
144
+ readonly onOpenLink?: (url: string, event: MouseEvent) => void;
145
+ /**
146
+ * Colours fenced code blocks. When set, a code block's content is rendered
147
+ * as a sequence of token spans instead of one plain text node. This is the
148
+ * non-incremental path: the snapshot is read once at render time.
149
+ */
150
+ readonly syntaxHighlighter?: ISyntaxHighlighter;
151
+ /**
152
+ * Pluggable renderer for the *inactive* (rendered) form of a math node —
153
+ * both `$$…$$` blocks and inline `$…$`. When set and it returns a result,
154
+ * its {@link MathRendering.dom} replaces the default opaque `katex.render`
155
+ * output, and its {@link MathRendering.segments} let parts of the rendered
156
+ * math (e.g. individual identifier glyphs) map back to source ranges so the
157
+ * caret can land inside them. Returning `undefined` falls back to the
158
+ * default whole-node KaTeX leaf. The active (source) form is unaffected.
159
+ *
160
+ * This is the seam used to explore in-place editing of rendered math (see
161
+ * `katexEditableIdentifiers.ts`).
162
+ */
163
+ readonly renderMath?: (request: MathRenderRequest) => MathRendering | undefined;
164
+ }
165
+
166
+ export declare class CodeBlockAstNode extends AstNode {
167
+ readonly language: string;
168
+ readonly content: readonly (MarkerAstNode | GlueAstNode)[];
169
+ readonly kind = "codeBlock";
170
+ private _previous?;
171
+ private _contentEdit?;
172
+ constructor(language: string, content: readonly (MarkerAstNode | GlueAstNode)[]);
173
+ get children(): readonly AstNode[];
174
+ get openFence(): MarkerAstNode | undefined;
175
+ get closeFence(): MarkerAstNode | undefined;
176
+ get code(): MarkerAstNode | undefined;
177
+ /** Relative start offset of the {@link code} marker within this block. */
178
+ get codeOffset(): number;
179
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
180
+ protected _localEquals(o: this): boolean;
181
+ /**
182
+ * A copy of this block carrying an incremental link to `previous`:
183
+ * `contentEdit` (in the block's *content* coordinates) turns `previous`'s
184
+ * content into this one. Uses a weak reference so the previous tree can be
185
+ * garbage-collected.
186
+ */
187
+ withCodeDiff(previous: CodeBlockAstNode, contentEdit: StringEdit): CodeBlockAstNode;
188
+ /**
189
+ * When this block was incrementally derived from `previous` (same
190
+ * fences/language, edit entirely within the content), returns the
191
+ * content-coordinate edit; otherwise `undefined`.
192
+ */
193
+ getDiff(previous: CodeBlockAstNode): CodeBlockDiff | undefined;
194
+ }
195
+
196
+ /**
197
+ * Describes how a {@link CodeBlockAstNode} was incrementally derived from a previous
198
+ * one: {@link stringEdit} (in the block's *content* coordinates) turns the
199
+ * previous content into this one.
200
+ */
201
+ declare interface CodeBlockDiff {
202
+ readonly stringEdit: StringEdit;
203
+ }
204
+
205
+ declare class CodeBlockViewData {
206
+ readonly ast: CodeBlockAstNode;
207
+ /** Active: render the fenced source; inactive: the (custom/highlighted) block. */
208
+ readonly showMarkup: boolean;
209
+ readonly content: readonly AnyViewData[];
210
+ readonly kind = "codeBlock";
211
+ constructor(ast: CodeBlockAstNode,
212
+ /** Active: render the fenced source; inactive: the (custom/highlighted) block. */
213
+ showMarkup: boolean, content: readonly AnyViewData[]);
214
+ }
215
+
216
+ /**
217
+ * A fenced code block. It owns its incremental
218
+ * {@link ISyntaxHighlighterDocument} session: constructing the node creates (or
219
+ * adopts from `previous`) the session, and disposing the node disposes it, so
220
+ * colouring stays incremental across edits — the session is reused and
221
+ * `update`d rather than rebuilt. A node at any depth owns a session; the only
222
+ * difference today is that the parser links `getDiff` for top-level code blocks
223
+ * only, so a nested block currently builds a fresh session on each rebuild.
224
+ */
225
+ export declare class CodeBlockViewNode extends BlockViewNode<CodeBlockViewData> {
226
+ private _session;
227
+ /**
228
+ * Subscription that re-tokenises the rendered `<code>` in place whenever the
229
+ * session advances its {@link ISyntaxHighlighterDocument.snapshot} *without*
230
+ * a source edit (an async grammar finishing, a live recolour). It is tied to
231
+ * this node's lifetime, but like {@link _session} it must be disposed
232
+ * manually: a node reused as `previous` for a rebuild is never `dispose`d
233
+ * (see {@link reconcileDomChildren}), so the rebuilding constructor disposes
234
+ * its predecessor's subscription explicitly.
235
+ */
236
+ private _snapshotSub;
237
+ constructor(data: CodeBlockViewData, options: BlockViewOptions | undefined, previous: ViewNode | undefined);
238
+ dispose(): void;
239
+ }
240
+
241
+ /**
242
+ * A {@link MonacoSyntaxHighlighter} preloaded with a handful of common Monarch
243
+ * grammars (plus the usual short aliases). Unknown languages fall back to an
244
+ * unstyled single token, so the highlighter is always safe to call.
245
+ *
246
+ * The Monarch runtime and grammar definitions are injected so this package
247
+ * depends on `monaco-editor` for types only.
248
+ */
249
+ export declare function createDefaultMonacoSyntaxHighlighter(monaco: IMonarchApi, grammars: IDefaultMonarchGrammars): MonacoSyntaxHighlighter;
250
+
251
+ export declare type CursorCommand = (ctx: CursorCommandContext) => SourceOffset;
252
+
253
+ export declare interface CursorCommandContext {
254
+ readonly text: string;
255
+ readonly selection: Selection_2;
256
+ readonly document: DocumentAstNode;
257
+ readonly activeBlock: BlockAstNode | undefined;
258
+ }
259
+
260
+ export declare const cursorDocumentEnd: CursorCommand;
261
+
262
+ export declare const cursorDocumentStart: CursorCommand;
263
+
264
+ export declare const cursorDown: VisualCursorCommand;
265
+
266
+ export declare const cursorLeft: CursorCommand;
267
+
268
+ export declare const cursorLineEnd: CursorCommand;
269
+
270
+ export declare const cursorLineStart: CursorCommand;
271
+
272
+ export declare const cursorMoveLeft: CursorCommand;
273
+
274
+ export declare interface CursorMoveResult {
275
+ readonly offset: SourceOffset;
276
+ readonly desiredColumn: number | undefined;
277
+ }
278
+
279
+ export declare const cursorMoveRight: CursorCommand;
280
+
281
+ export declare const cursorRight: CursorCommand;
282
+
283
+ export declare const cursorUp: VisualCursorCommand;
284
+
285
+ /**
286
+ * Owns the blinking cursor DOM element.
287
+ *
288
+ * The rendering pipeline is a single `derived` whose compute callback
289
+ * asks the {@link VisualLineMap} for the caret rect at the current
290
+ * offset, writes it to {@link element}, and returns a
291
+ * {@link CursorViewRendering} value as proof. An autorun keeps the
292
+ * derived subscribed.
293
+ */
294
+ export declare class CursorView extends Disposable {
295
+ private readonly _parent;
296
+ readonly element: HTMLElement;
297
+ readonly rendering: IObservable<CursorViewRendering>;
298
+ constructor(_parent: HTMLElement, options: CursorViewOptions);
299
+ }
300
+
301
+ export declare interface CursorViewOptions {
302
+ readonly offset: IObservable<SourceOffset | undefined>;
303
+ readonly visualLineMap: IObservable<VisualLineMap>;
304
+ }
305
+
306
+ export declare class CursorViewRendering {
307
+ readonly offset: SourceOffset;
308
+ readonly visible: boolean;
309
+ readonly rect: Rect2D;
310
+ constructor(offset: SourceOffset, visible: boolean, rect: Rect2D);
311
+ }
312
+
313
+ export declare const cursorWordLeft: CursorCommand;
314
+
315
+ export declare const cursorWordRight: CursorCommand;
316
+
317
+ export declare const deleteLeft: EditCommand;
318
+
319
+ export declare const deleteRight: EditCommand;
320
+
321
+ export declare const deleteWordLeft: EditCommand;
322
+
323
+ export declare const deleteWordRight: EditCommand;
324
+
325
+ export declare class DocumentAstNode extends AstNode {
326
+ readonly content: readonly (BlockAstNode | GlueAstNode)[];
327
+ readonly kind = "document";
328
+ constructor(content: readonly (BlockAstNode | GlueAstNode)[]);
329
+ get children(): readonly AstNode[];
330
+ get blocks(): readonly BlockAstNode[];
331
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
332
+ }
333
+
334
+ /** A mounted block: its view node paired with where it starts in the source. */
335
+ export declare interface DocumentBlock {
336
+ readonly node: BlockViewNode;
337
+ readonly absoluteStart: number;
338
+ }
339
+
340
+ /** A top-level block plus the document-level state the renderer applies to it. */
341
+ declare interface DocumentBlockViewData {
342
+ readonly ast: BlockAstNode;
343
+ readonly absoluteStart: number;
344
+ /** Whether the selection reaches this block (drives `md-block-active`). */
345
+ readonly isActive: boolean;
346
+ readonly view: BlockViewData;
347
+ }
348
+
349
+ /** A mounted document child: a block or a run of inter-block glue. */
350
+ declare interface DocumentChildViewData {
351
+ readonly absoluteStart: number;
352
+ /** For a block: selection reaches it. For glue: a neighbouring block is active. */
353
+ readonly isActive: boolean;
354
+ readonly view: BlockViewData | GlueViewData;
355
+ readonly kind: 'block' | 'glue';
356
+ }
357
+
358
+ /**
359
+ * The view-data root. Mirrors {@link DocumentAstNode}: {@link blocks} holds only
360
+ * its top-level blocks (each wrapped with where it starts and whether it is
361
+ * active), while {@link children} additionally interleaves the rendered
362
+ * document-level glue (the blank lines between blocks) in source order.
363
+ */
364
+ declare class DocumentViewData {
365
+ readonly ast: DocumentAstNode;
366
+ readonly blocks: readonly DocumentBlockViewData[];
367
+ /**
368
+ * Blocks and inter-block glue interleaved in source order — the actual
369
+ * mount sequence. {@link blocks} is the block-only projection used for
370
+ * measurement and selection.
371
+ */
372
+ readonly children: readonly DocumentChildViewData[];
373
+ readonly kind = "document";
374
+ constructor(ast: DocumentAstNode, blocks: readonly DocumentBlockViewData[],
375
+ /**
376
+ * Blocks and inter-block glue interleaved in source order — the actual
377
+ * mount sequence. {@link blocks} is the block-only projection used for
378
+ * measurement and selection.
379
+ */
380
+ children: readonly DocumentChildViewData[]);
381
+ }
382
+
383
+ /**
384
+ * Immutable view of the document's block sequence — the document-level
385
+ * analogue of {@link BlockViewNode}. Each {@link create} maps the
386
+ * {@link DocumentViewData} (the AST overlaid with selection-derived flags) to
387
+ * the block sequence, reusing the previous node's blocks by view-data identity,
388
+ * rebuilding only what changed, and patching its {@link contentDomNode}'s
389
+ * children to match.
390
+ *
391
+ * Like a {@link BlockViewNode}, it owns its DOM: the first `create` allocates
392
+ * the content element, and every later `create` keeps the previous node's
393
+ * element rather than making a new one. The element is therefore stable
394
+ * across rebuilds:
395
+ *
396
+ * create(viewData, …, old).contentDomNode === old.contentDomNode
397
+ *
398
+ * so a parent can mount it once and never re-parent it.
399
+ *
400
+ * Because it is rebuilt rather than mutated, {@link EditorView} can hold the
401
+ * whole block cache as one value and simply swap it each frame, instead of
402
+ * carrying a mutable entry array and the reconcile bookkeeping itself.
403
+ *
404
+ * It is itself a {@link ViewNode} (the root of the view-node tree), so DOM ↔
405
+ * source mapping such as {@link ViewNode.resolveSource} is inherited: a hit on
406
+ * any descendant lifts up the parent chain to here, yielding an absolute
407
+ * document offset.
408
+ */
409
+ export declare class DocumentViewNode extends ViewNode {
410
+ readonly blocks: readonly DocumentBlock[];
411
+ static create(viewData: DocumentViewData, options: BlockViewOptions | undefined, previous: DocumentViewNode | undefined): DocumentViewNode;
412
+ private constructor();
413
+ /** The stable content element this document mounts its children into. */
414
+ get contentDomNode(): HTMLElement;
415
+ }
416
+
417
+ /**
418
+ * A DOM node paired with a caret offset inside it. The node is an arbitrary
419
+ * {@link globalThis.Node} (a Text node for a caret inside text, an Element for
420
+ * a hit on element-only content), and `offset` is the caret offset within it.
421
+ */
422
+ export declare interface DomPosition {
423
+ readonly node: globalThis.Node;
424
+ readonly offset: number;
425
+ }
426
+
427
+ export declare type EditCommand = (ctx: CursorCommandContext) => {
428
+ readonly edit: StringEdit;
429
+ readonly selection: Selection_2;
430
+ } | undefined;
431
+
432
+ /**
433
+ * Translates raw browser input (mouse, keyboard, EditContext) into model
434
+ * mutations. Knows about DOM event types but never reads/writes the DOM
435
+ * directly — it asks the {@link EditorView} to broker DOM↔source-offset
436
+ * conversions so the model stays free of view types.
437
+ *
438
+ * Owns the only non-derivable controller state:
439
+ * - `_desiredColumn` — sticky column for up/down navigation
440
+ */
441
+ export declare class EditorController extends Disposable {
442
+ private readonly _model;
443
+ private readonly _view;
444
+ private _desiredColumn;
445
+ constructor(_model: EditorModel, _view: EditorView);
446
+ private readonly _handleTextUpdate;
447
+ private readonly _handleMouseDown;
448
+ private _makeCursorContext;
449
+ private _makeVisualCursorContext;
450
+ private _executeCursorCommand;
451
+ private _executeEditCommand;
452
+ private _executeVisualCursorCommand;
453
+ /** Move the cursor down one visual line (Arrow Down). */
454
+ cursorDown(extend?: boolean): void;
455
+ /** Move the cursor up one visual line (Arrow Up). */
456
+ cursorUp(extend?: boolean): void;
457
+ private readonly _handleCopy;
458
+ private readonly _handleCut;
459
+ private readonly _handlePaste;
460
+ private _selectedText;
461
+ private readonly _handleKeyDown;
462
+ }
463
+
464
+ export declare class EditorModel {
465
+ private readonly _parser;
466
+ /**
467
+ * The most recent edit applied to {@link sourceText}, used by
468
+ * {@link document} to let the parser link incrementally edited code
469
+ * blocks. Only trusted when it exactly bridges the previous and current
470
+ * source text (see {@link document}).
471
+ */
472
+ private _pendingEdit;
473
+ readonly sourceText: ISettableObservable<StringValue, void>;
474
+ /**
475
+ * The current selection, or `undefined` when the editor has no caret
476
+ * (e.g. an inactive/unfocused rendering).
477
+ */
478
+ readonly selection: ISettableObservable<Selection_2 | undefined, void>;
479
+ /**
480
+ * Forces the rendered active-block set. `undefined` (the default)
481
+ * derives the set from the current selection range (see
482
+ * {@link activeBlocks}). The sentinel {@link NO_ACTIVE_BLOCKS} forces
483
+ * "no active block" — useful in fixtures that always want the
484
+ * collapsed/inactive rendering.
485
+ */
486
+ readonly activeBlocksOverride: ISettableObservable<readonly BlockAstNode[] | typeof NO_ACTIVE_BLOCKS | undefined, void>;
487
+ readonly cursorOffset: IObservableWithChange<number | undefined, void>;
488
+ /**
489
+ * The parsed document. Threads the previous document into the parser so
490
+ * unchanged blocks keep their object identity across reparses (see
491
+ * {@link MarkdownParser.parse}). Writing `previous` inside the compute is
492
+ * a safe optimization: `derived` only recomputes when `sourceText`
493
+ * changes, and the result is structurally identical to a full reparse.
494
+ */
495
+ readonly document: IObservableWithChange<DocumentAstNode, void>;
496
+ /**
497
+ * Block that contains the cursor (selection's active end). Used by
498
+ * cursor navigation to know which block's marker ranges count as
499
+ * visible. Unaffected by {@link activeBlocksOverride} because
500
+ * navigation is independent of rendering.
501
+ */
502
+ readonly activeBlock: IObservableWithChange<BlockAstNode | undefined, void>;
503
+ /**
504
+ * All blocks whose source range intersects the current selection.
505
+ * The rendering side uses this to decide which blocks render in
506
+ * their expanded (markers-visible) form. When the selection is
507
+ * collapsed this is a one-element set holding {@link activeBlock}.
508
+ */
509
+ readonly activeBlocks: IObservableWithChange<Set<BlockAstNode>, void>;
510
+ applyEdit(edit: StringEdit): void;
511
+ applyEditForSelection(edit: StringEdit): void;
512
+ }
513
+
514
+ /**
515
+ * Pure-render view of an {@link EditorModel}.
516
+ *
517
+ * Invariant (the whole point of this file):
518
+ *
519
+ * view(model + Δ) = view(model) + Δ
520
+ *
521
+ * The DOM the view produces is a function of the model. The only state the
522
+ * view holds is *DOM management*: the cached `BlockViewNode` instances and the
523
+ * `EditContext`. Anything that influences correctness but is not derivable
524
+ * from the model lives elsewhere:
525
+ *
526
+ * - measured heights and per-block visual line maps → {@link MeasuredLayoutModel}
527
+ * - desired column, drag-time freeze → EditorController
528
+ *
529
+ * The view does not own a controller — callers construct an
530
+ * `EditorController` separately and pass it the view, so input handling is
531
+ * explicit and the view stays a pure renderer.
532
+ *
533
+ * The view writes into the measured-layout model as a side effect of
534
+ * rendering. It never reads its own measurements during rendering, so
535
+ * there is no feedback loop.
536
+ */
537
+ export declare class EditorView extends Disposable {
538
+ private readonly _model;
539
+ private readonly _options?;
540
+ readonly element: HTMLElement;
541
+ readonly editContext: EditContext;
542
+ readonly measuredLayout: MeasuredLayoutModel;
543
+ private readonly _cursorView;
544
+ private readonly _selectionView;
545
+ /**
546
+ * The mounted block sequence, in source order. Rebuilt (not mutated) each
547
+ * frame by {@link DocumentViewNode.create}; the view just swaps one
548
+ * immutable node for the next. Never used for source-of-truth lookups
549
+ * (those go through the measured-layout model).
550
+ */
551
+ private readonly _document;
552
+ /** The current view-node tree (AST overlaid with rendered DOM), for debugging. */
553
+ get documentViewNode(): IObservable<DocumentViewNode | undefined>;
554
+ /**
555
+ * Last frame's view-data overlay, threaded back into
556
+ * {@link buildDocumentViewData} so any subtree whose ast and selection flags
557
+ * are unchanged keeps its view-data object — which lets the renderer reuse
558
+ * its DOM by identity.
559
+ */
560
+ private _previousViewData;
561
+ /** The current view-data tree (AST overlaid with selection flags), for debugging. */
562
+ private readonly _viewData;
563
+ get viewData(): IObservable<DocumentViewData | undefined>;
564
+ /**
565
+ * The block cache projected for views (selection painting) that need to
566
+ * react to mount/unmount. Derived from {@link _document}, so it stays in
567
+ * lock-step without any manual bookkeeping.
568
+ */
569
+ private readonly _selectionBlocksObs;
570
+ constructor(_model: EditorModel, _options?: EditorViewOptions | undefined);
571
+ focus(): void;
572
+ /**
573
+ * Client coordinates → absolute source offset (any block). Used during
574
+ * drag to keep extending the selection even when the pointer leaves the
575
+ * original block.
576
+ */
577
+ resolveOffsetFromPoint(point: Point2D): SourceOffset | undefined;
578
+ /**
579
+ * Whether a client point falls on the rendered document content, as
580
+ * opposed to the surrounding editor padding (the green area). Uses DOM
581
+ * containment rather than the content node's bounding box so that markers
582
+ * which overflow into the padding (e.g. a heading's `##`, which renders in
583
+ * the left margin) still count as content. Overlays (cursor, selection)
584
+ * have `pointer-events: none`, so the hit-test sees through them.
585
+ */
586
+ isPointInContent(point: Point2D): boolean;
587
+ private readonly _renderAutorun;
588
+ /** Current mounted blocks, or empty before the first render. */
589
+ private get _blocks();
590
+ /**
591
+ * Measure each mounted block's rect and per-block visual line map, then
592
+ * publish the result into the {@link MeasuredLayoutModel}. The model
593
+ * is not read here, so there is no feedback loop into the render autorun.
594
+ */
595
+ private _publishMeasurements;
596
+ }
597
+
598
+ export declare interface EditorViewOptions extends BlockViewOptions {
599
+ /**
600
+ * Extra class names added to the editor root element, e.g. a theme class
601
+ * such as `'md-theme-default'` or `'github-markdown-theme'`. Theme styles
602
+ * are scoped under these classes, so the editor is unstyled (base chrome
603
+ * only) unless a theme class is supplied.
604
+ */
605
+ readonly classNames?: readonly string[];
606
+ }
607
+
608
+ export declare class EmphasisAstNode extends AstNode {
609
+ readonly openMarker: MarkerAstNode;
610
+ readonly content: readonly (InlineAstNode | GlueAstNode)[];
611
+ readonly closeMarker: MarkerAstNode;
612
+ readonly kind = "emphasis";
613
+ constructor(openMarker: MarkerAstNode, content: readonly (InlineAstNode | GlueAstNode)[], closeMarker: MarkerAstNode);
614
+ get children(): readonly AstNode[];
615
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
616
+ }
617
+
618
+ declare class EmphasisViewData {
619
+ readonly ast: EmphasisAstNode;
620
+ readonly content: readonly AnyViewData[];
621
+ readonly kind = "emphasis";
622
+ constructor(ast: EmphasisAstNode, content: readonly AnyViewData[]);
623
+ }
624
+
625
+ /**
626
+ * Source offset (relative to `root`) of the node with `target`'s id, or
627
+ * `undefined` when it is not in the tree. Ids are stable across edits, so this
628
+ * locates a node even after reconciliation has rebuilt the tree around it.
629
+ */
630
+ export declare function findNodeOffsetById(root: AstNode, target: AstNode): number | undefined;
631
+
632
+ export declare function findWordAt(text: string, offset: number): {
633
+ start: number;
634
+ end: number;
635
+ };
636
+
637
+ export declare function findWordBoundaryLeft(text: string, offset: number): number;
638
+
639
+ export declare function findWordBoundaryRight(text: string, offset: number): number;
640
+
641
+ export declare function getAnnotatedSource(node: AstNode, source: string, offset?: number): string;
642
+
643
+ /** Non-semantic syntactic glue: whitespace, padding, table pipes. */
644
+ export declare class GlueAstNode extends LeafAstNode {
645
+ readonly content: string;
646
+ readonly glueKind?: string | undefined;
647
+ readonly kind = "glue";
648
+ constructor(content: string, glueKind?: string | undefined);
649
+ protected _localEquals(o: this): boolean;
650
+ }
651
+
652
+ declare class GlueViewData {
653
+ readonly ast: GlueAstNode;
654
+ readonly visible: boolean;
655
+ /**
656
+ * Whether a source newline in this glue gets a visible `↵`. True only in
657
+ * inline flow, where the newline collapses to a space and the `↵` reveals
658
+ * the line ending hiding there; between block-level siblings (list items,
659
+ * block children) the break is already visible, so no `↵` is drawn.
660
+ */
661
+ readonly decorateNewline: boolean;
662
+ readonly kind = "glue";
663
+ constructor(ast: GlueAstNode, visible: boolean,
664
+ /**
665
+ * Whether a source newline in this glue gets a visible `↵`. True only in
666
+ * inline flow, where the newline collapses to a space and the `↵` reveals
667
+ * the line ending hiding there; between block-level siblings (list items,
668
+ * block children) the break is already visible, so no `↵` is drawn.
669
+ */
670
+ decorateNewline: boolean);
671
+ }
672
+
673
+ export declare class HeadingAstNode extends AstNode {
674
+ readonly level: 1 | 2 | 3 | 4 | 5 | 6;
675
+ readonly marker: MarkerAstNode;
676
+ readonly content: readonly (InlineAstNode | GlueAstNode)[];
677
+ readonly kind = "heading";
678
+ constructor(level: 1 | 2 | 3 | 4 | 5 | 6, marker: MarkerAstNode, content: readonly (InlineAstNode | GlueAstNode)[]);
679
+ get children(): readonly AstNode[];
680
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
681
+ protected _localEquals(o: this): boolean;
682
+ }
683
+
684
+ declare class HeadingViewData {
685
+ readonly ast: HeadingAstNode;
686
+ readonly content: readonly AnyViewData[];
687
+ readonly kind = "heading";
688
+ constructor(ast: HeadingAstNode, content: readonly AnyViewData[]);
689
+ }
690
+
691
+ /** The Monarch language definitions the default highlighter wires up. */
692
+ export declare interface IDefaultMonarchGrammars {
693
+ typescript: unknown;
694
+ javascript: unknown;
695
+ css: unknown;
696
+ html: unknown;
697
+ python: unknown;
698
+ rust: unknown;
699
+ shell: unknown;
700
+ }
701
+
702
+ export declare class ImageAstNode extends AstNode {
703
+ readonly alt: string;
704
+ readonly url: string;
705
+ readonly content: readonly (MarkerAstNode | GlueAstNode)[];
706
+ readonly kind = "image";
707
+ constructor(alt: string, url: string, content: readonly (MarkerAstNode | GlueAstNode)[]);
708
+ get children(): readonly AstNode[];
709
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
710
+ protected _localEquals(o: this): boolean;
711
+ }
712
+
713
+ declare class ImageViewData {
714
+ readonly ast: ImageAstNode;
715
+ /** Active: render the `![alt](url)` source; inactive: the `<img>`. */
716
+ readonly showMarkup: boolean;
717
+ readonly content: readonly AnyViewData[];
718
+ readonly kind = "image";
719
+ constructor(ast: ImageAstNode,
720
+ /** Active: render the `![alt](url)` source; inactive: the `<img>`. */
721
+ showMarkup: boolean, content: readonly AnyViewData[]);
722
+ }
723
+
724
+ /**
725
+ * The slice of monaco's Monarch internals the highlighter needs at runtime.
726
+ *
727
+ * `monaco-editor` is only a *type* dependency of this package; the caller (who
728
+ * owns a real monaco runtime) passes these in, keeping monaco out of the bundle.
729
+ */
730
+ export declare interface IMonarchApi {
731
+ /** Compiles a Monarch language definition into the internal lexer form. */
732
+ compile(languageId: string, json: unknown): unknown;
733
+ MonarchTokenizer: new (languageService: unknown, standaloneThemeService: unknown, languageId: string, lexer: unknown, configurationService: unknown) => MonarchTokenizer;
734
+ }
735
+
736
+ export declare type InlineAstNode = TextAstNode | StrongAstNode | EmphasisAstNode | StrikethroughAstNode | InlineCodeAstNode | InlineMathAstNode | LinkAstNode | ImageAstNode;
737
+
738
+ export declare class InlineCodeAstNode extends AstNode {
739
+ readonly content: readonly (MarkerAstNode | GlueAstNode)[];
740
+ readonly kind = "inlineCode";
741
+ constructor(content: readonly (MarkerAstNode | GlueAstNode)[]);
742
+ get children(): readonly AstNode[];
743
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
744
+ }
745
+
746
+ declare class InlineCodeViewData {
747
+ readonly ast: InlineCodeAstNode;
748
+ readonly content: readonly AnyViewData[];
749
+ readonly kind = "inlineCode";
750
+ constructor(ast: InlineCodeAstNode, content: readonly AnyViewData[]);
751
+ }
752
+
753
+ export declare class InlineMathAstNode extends AstNode {
754
+ readonly content: readonly (MarkerAstNode | GlueAstNode)[];
755
+ readonly kind = "inlineMath";
756
+ constructor(content: readonly (MarkerAstNode | GlueAstNode)[]);
757
+ get children(): readonly AstNode[];
758
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
759
+ }
760
+
761
+ declare class InlineMathViewData {
762
+ readonly ast: InlineMathAstNode;
763
+ /** Active: render the `$…$` source; inactive: the KaTeX output. */
764
+ readonly showMarkup: boolean;
765
+ readonly content: readonly AnyViewData[];
766
+ readonly kind = "inlineMath";
767
+ constructor(ast: InlineMathAstNode,
768
+ /** Active: render the `$…$` source; inactive: the KaTeX output. */
769
+ showMarkup: boolean, content: readonly AnyViewData[]);
770
+ }
771
+
772
+ declare type InlineViewData = TextViewData | StrongViewData | EmphasisViewData | StrikethroughViewData | InlineCodeViewData | InlineMathViewData | LinkViewData | ImageViewData;
773
+
774
+ /**
775
+ * A Markdown hard line break: a `\n` whose preceding line ends with two spaces.
776
+ * Any spaces already trailing the insertion point count toward the two, so the
777
+ * line never accumulates more than the two needed to form the break.
778
+ */
779
+ export declare const insertHardLineBreak: EditCommand;
780
+
781
+ export declare const insertLineBreak: EditCommand;
782
+
783
+ export declare const insertParagraph: EditCommand;
784
+
785
+ export declare function insertText(text: string): EditCommand;
786
+
787
+ /**
788
+ * An immutable view of one document's tokens at a point in time. It may be a
789
+ * thin view over the highlighter's mutable state: once the underlying document
790
+ * advances, calling a stale snapshot is allowed to throw.
791
+ *
792
+ * Token stability: across snapshots `S1 -> S2` (with the change delivered as a
793
+ * {@link LengthEdit}), `getTokens(r)` returns the same tokens for any range `r`
794
+ * not touched by that edit. Only ranges the edit reports as changed may recolour.
795
+ */
796
+ export declare interface ISyntaxHighlightedSnapshot {
797
+ /**
798
+ * Tokens covering a region that contains `queryRange`. Tokens are never
799
+ * split: the returned {@link SnapshotTokens.range} is `queryRange` *grown*
800
+ * to whole-token boundaries, so a token that straddles an end of
801
+ * `queryRange` is returned in full. The result is dense over that grown
802
+ * range — `sum(token.length) === range.length` — which is why the range is
803
+ * returned alongside the tokens.
804
+ */
805
+ getTokens(queryRange: OffsetRange): SnapshotTokens;
806
+ }
807
+
808
+ export declare interface ISyntaxHighlighter {
809
+ create(language: string, initialText: string): ISyntaxHighlighterDocument;
810
+ }
811
+
812
+ export declare interface ISyntaxHighlighterDocument extends IDisposable {
813
+ /**
814
+ * Apply a source edit. The {@link snapshot} updates synchronously within
815
+ * `tx`, and the change it carries is the *minimal* {@link LengthEdit} that
816
+ * actually re-coloured — not the whole document.
817
+ */
818
+ update(edit: StringEdit, tx: ITransaction): void;
819
+ /**
820
+ * The current snapshot. Its change reason is a {@link LengthEdit} mapping
821
+ * the previous snapshot's offsets to this one's wherever tokens changed.
822
+ */
823
+ readonly snapshot: IObservableWithChange<ISyntaxHighlightedSnapshot, LengthEdit>;
824
+ }
825
+
826
+ declare abstract class LeafAstNode extends AstNode {
827
+ abstract readonly content: string;
828
+ get children(): readonly AstNode[];
829
+ get length(): number;
830
+ mapChildren(): AstNode;
831
+ }
832
+
833
+ /**
834
+ * A set of disjoint, sorted {@link LengthReplacement}s — the length-only
835
+ * counterpart of {@link StringEdit}. Used as the change reason of an
836
+ * observable so observers learn which offset ranges of the previous value map
837
+ * to which ranges of the new value (and thus what to invalidate) without
838
+ * carrying the new content itself.
839
+ */
840
+ export declare class LengthEdit {
841
+ static readonly empty: LengthEdit;
842
+ static single(replacement: LengthReplacement): LengthEdit;
843
+ static replace(replaceRange: OffsetRange, newLength: number): LengthEdit;
844
+ readonly replacements: readonly LengthReplacement[];
845
+ constructor(replacements: readonly LengthReplacement[]);
846
+ get isEmpty(): boolean;
847
+ equals(other: LengthEdit): boolean;
848
+ toString(): string;
849
+ }
850
+
851
+ /**
852
+ * A single "the text in `replaceRange` now spans `newLength` characters"
853
+ * statement. Unlike {@link StringReplacement} it carries no text — it only
854
+ * describes *where* and *by how much* something changed, not *what to*.
855
+ *
856
+ * For syntax highlighting it means: the characters that used to occupy
857
+ * `replaceRange` are replaced by `newLength` characters whose tokens may now
858
+ * be coloured differently. A same-length replacement (`replaceRange.length ===
859
+ * newLength`) therefore means "these characters kept their positions but got
860
+ * re-coloured".
861
+ */
862
+ export declare class LengthReplacement {
863
+ readonly replaceRange: OffsetRange;
864
+ readonly newLength: number;
865
+ static replace(replaceRange: OffsetRange, newLength: number): LengthReplacement;
866
+ constructor(replaceRange: OffsetRange, newLength: number);
867
+ get lengthDelta(): number;
868
+ equals(other: LengthReplacement): boolean;
869
+ toString(): string;
870
+ }
871
+
872
+ export declare class LinkAstNode extends AstNode {
873
+ readonly url: string;
874
+ readonly content: readonly (MarkerAstNode | InlineAstNode | GlueAstNode)[];
875
+ readonly kind = "link";
876
+ constructor(url: string, content: readonly (MarkerAstNode | InlineAstNode | GlueAstNode)[]);
877
+ get children(): readonly AstNode[];
878
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
879
+ protected _localEquals(o: this): boolean;
880
+ }
881
+
882
+ declare class LinkViewData {
883
+ readonly ast: LinkAstNode;
884
+ readonly content: readonly AnyViewData[];
885
+ readonly kind = "link";
886
+ constructor(ast: LinkAstNode, content: readonly AnyViewData[]);
887
+ }
888
+
889
+ export declare class ListAstNode extends AstNode {
890
+ readonly ordered: boolean;
891
+ readonly content: readonly (ListItemAstNode | GlueAstNode)[];
892
+ readonly kind = "list";
893
+ constructor(ordered: boolean, content: readonly (ListItemAstNode | GlueAstNode)[]);
894
+ get children(): readonly AstNode[];
895
+ get items(): readonly ListItemAstNode[];
896
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
897
+ protected _localEquals(o: this): boolean;
898
+ }
899
+
900
+ export declare class ListItemAstNode extends AstNode {
901
+ readonly marker: MarkerAstNode;
902
+ readonly content: readonly (BlockAstNode | GlueAstNode)[];
903
+ readonly checked?: boolean | undefined;
904
+ readonly leadingTrivia?: GlueAstNode | undefined;
905
+ readonly kind = "listItem";
906
+ constructor(marker: MarkerAstNode, content: readonly (BlockAstNode | GlueAstNode)[], checked?: boolean | undefined, leadingTrivia?: GlueAstNode | undefined);
907
+ get children(): readonly AstNode[];
908
+ get blocks(): readonly BlockAstNode[];
909
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
910
+ protected _localEquals(o: this): boolean;
911
+ }
912
+
913
+ declare class ListItemViewData {
914
+ readonly ast: ListItemAstNode;
915
+ /** Whether the selection reaches this item (reveals its markers). */
916
+ readonly isActive: boolean;
917
+ readonly content: readonly AnyViewData[];
918
+ /** 1-based list nesting depth, used to size the indentation gutter. */
919
+ readonly level: number;
920
+ readonly kind = "listItem";
921
+ constructor(ast: ListItemAstNode,
922
+ /** Whether the selection reaches this item (reveals its markers). */
923
+ isActive: boolean, content: readonly AnyViewData[],
924
+ /** 1-based list nesting depth, used to size the indentation gutter. */
925
+ level: number);
926
+ }
927
+
928
+ declare class ListViewData {
929
+ readonly ast: ListAstNode;
930
+ readonly content: readonly AnyViewData[];
931
+ readonly kind = "list";
932
+ constructor(ast: ListAstNode, content: readonly AnyViewData[]);
933
+ }
934
+
935
+ /**
936
+ * Parses markdown into a {@link DocumentAstNode}.
937
+ *
938
+ * When given the `previous` document and the `edit` that produced the new
939
+ * text, it reuses unchanged subtrees and carries node identities across the
940
+ * edit (see {@link parseIncremental}), so views can diff cheaply and code
941
+ * blocks keep their incremental highlighting sessions.
942
+ */
943
+ export declare class MarkdownParser {
944
+ parse(text: StringValue, previous?: DocumentAstNode, edit?: StringEdit): DocumentAstNode;
945
+ }
946
+
947
+ /** A semantic syntax marker (heading `#`, fences, brackets, list bullet, …). */
948
+ export declare class MarkerAstNode extends LeafAstNode {
949
+ readonly markerKind: string;
950
+ readonly content: string;
951
+ readonly kind = "marker";
952
+ constructor(markerKind: string, content: string);
953
+ protected _localEquals(o: this): boolean;
954
+ }
955
+
956
+ declare class MarkerViewData {
957
+ readonly ast: MarkerAstNode;
958
+ readonly visible: boolean;
959
+ readonly kind = "marker";
960
+ constructor(ast: MarkerAstNode, visible: boolean);
961
+ }
962
+
963
+ export declare class MathBlockAstNode extends AstNode {
964
+ readonly content: readonly (MarkerAstNode | GlueAstNode)[];
965
+ readonly kind = "mathBlock";
966
+ constructor(content: readonly (MarkerAstNode | GlueAstNode)[]);
967
+ get children(): readonly AstNode[];
968
+ get code(): MarkerAstNode | undefined;
969
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
970
+ }
971
+
972
+ declare class MathBlockViewData {
973
+ readonly ast: MathBlockAstNode;
974
+ /** Active: render the source; inactive: the KaTeX output. */
975
+ readonly showMarkup: boolean;
976
+ readonly content: readonly AnyViewData[];
977
+ readonly kind = "mathBlock";
978
+ constructor(ast: MathBlockAstNode,
979
+ /** Active: render the source; inactive: the KaTeX output. */
980
+ showMarkup: boolean, content: readonly AnyViewData[]);
981
+ }
982
+
983
+ /** Result of a {@link BlockViewOptions.renderMath} renderer. */
984
+ export declare interface MathRendering {
985
+ /** Host element to mount (the rendered math output). */
986
+ readonly dom: HTMLElement;
987
+ /** Source-mapped spans within {@link dom} (need not tile the whole node). */
988
+ readonly segments: readonly MathSourceSegment[];
989
+ }
990
+
991
+ /** Input to a {@link BlockViewOptions.renderMath} renderer. */
992
+ export declare interface MathRenderRequest {
993
+ /** The LaTeX source of the math content (without the `$$`/`$` fences). */
994
+ readonly latex: string;
995
+ /** `true` for a `$$…$$` block, `false` for inline `$…$`. */
996
+ readonly displayMode: boolean;
997
+ /** CSS class the host element must carry (editor styling/measurement hooks). */
998
+ readonly className: string;
999
+ /** Full source length of the math node (fences/`$` included). */
1000
+ readonly nodeLength: number;
1001
+ /** Offset of {@link latex} within the node (i.e. after the opening fence/`$`). */
1002
+ readonly contentStart: number;
1003
+ }
1004
+
1005
+ /**
1006
+ * A span of the rendered math output that maps to a slice of source. The
1007
+ * renderer reports these for the parts it can map (e.g. identifier glyphs);
1008
+ * the editor tiles the gaps between them so the whole math node stays mapped.
1009
+ */
1010
+ export declare interface MathSourceSegment {
1011
+ /** A DOM node (ideally a Text node) within the rendered output. */
1012
+ readonly dom: globalThis.Node;
1013
+ /** Start offset of the mapped slice, relative to the math node's start. */
1014
+ readonly start: number;
1015
+ /** Source length of the mapped slice. */
1016
+ readonly length: number;
1017
+ }
1018
+
1019
+ /**
1020
+ * Immutable record of one rendered debug frame.
1021
+ */
1022
+ export declare class MeasuredLayoutDebugRendering {
1023
+ readonly blockCount: number;
1024
+ readonly mountedCount: number;
1025
+ readonly lineCount: number;
1026
+ /** Absolute source offsets that map to a rendered DOM character. */
1027
+ readonly mappedOffsets: ReadonlySet<number>;
1028
+ constructor(blockCount: number, mountedCount: number, lineCount: number,
1029
+ /** Absolute source offsets that map to a rendered DOM character. */
1030
+ mappedOffsets: ReadonlySet<number>);
1031
+ }
1032
+
1033
+ /**
1034
+ * Debug view for a {@link MeasuredLayoutModel}.
1035
+ *
1036
+ * Exposes two DOM nodes the caller can place independently:
1037
+ *
1038
+ * - {@link overlayElement} — absolutely positioned; the caller mounts it
1039
+ * inside the editor element so dashed line-bands and run-boxes line up
1040
+ * with the editor's client coordinates.
1041
+ * - {@link infoElement} — block-flow; the caller mounts it as a sibling
1042
+ * *below* the editor. Contains the per-block summary table that used
1043
+ * to live on the overlay.
1044
+ *
1045
+ * Same pattern as `CursorView` / `SelectionView`: the rendering pipeline
1046
+ * is a single `derived` whose compute callback writes the DOM and returns
1047
+ * a {@link MeasuredLayoutDebugRendering} value as proof. An autorun keeps
1048
+ * the derived subscribed.
1049
+ */
1050
+ export declare class MeasuredLayoutDebugView extends Disposable {
1051
+ private readonly _overlayParent;
1052
+ readonly overlayElement: HTMLElement;
1053
+ readonly infoElement: HTMLElement;
1054
+ readonly rendering: IObservable<MeasuredLayoutDebugRendering>;
1055
+ /** Absolute source offsets that map to a rendered DOM character. */
1056
+ readonly mappedOffsets: IObservable<ReadonlySet<number>>;
1057
+ /** Whether the dashed line-bands and run boxes are drawn (persisted). */
1058
+ private readonly _showLineRects;
1059
+ constructor(_overlayParent: HTMLElement, options: MeasuredLayoutDebugViewOptions);
1060
+ }
1061
+
1062
+ export declare interface MeasuredLayoutDebugViewOptions {
1063
+ readonly model: MeasuredLayoutModel;
1064
+ /**
1065
+ * DEBUG ONLY. Maps an absolute source offset to a fill color for that
1066
+ * character's glyph rect. The fixture passes the same function to the
1067
+ * raw-source view so a character and its rect share one color — a
1068
+ * mismatch exposes a source ↔ DOM mapping bug.
1069
+ */
1070
+ readonly colorForOffset?: (offset: number) => string | undefined;
1071
+ /**
1072
+ * DEBUG ONLY. Shared "currently hovered source offset". When set, the
1073
+ * overlay isolates the matching glyph rect; the fixture passes the same
1074
+ * observable to the raw-source view so hovering either side highlights the
1075
+ * same character in both. Hovering a rect writes this; `undefined` clears.
1076
+ */
1077
+ readonly hoveredOffset?: ISettableObservable<number | undefined>;
1078
+ }
1079
+
1080
+ /**
1081
+ * The set of measurements/estimates the view has produced for the current
1082
+ * document. This is the "view → derived facts about layout" channel: the
1083
+ * view writes here as a side effect of rendering and measuring; the
1084
+ * controller (and selection/cursor rendering) reads from here.
1085
+ *
1086
+ * Keeping these facts in their own observable model — instead of as ad-hoc
1087
+ * fields on the view — preserves the invariant
1088
+ *
1089
+ * view(model + Δ) = view(model) + Δ
1090
+ *
1091
+ * i.e. the view becomes a pure function of (EditorModel, MeasuredLayoutModel).
1092
+ * Everything else that depends on layout (controller, commands) goes
1093
+ * through this model and never touches view fields directly.
1094
+ */
1095
+ export declare class MeasuredLayoutModel {
1096
+ readonly measurements: ISettableObservable<readonly BlockMeasurement[], void>;
1097
+ /**
1098
+ * Concatenated visual line map across all mounted blocks. Lines are
1099
+ * left in DOM (client-coordinate) y order — each per-block map already
1100
+ * uses absolute client coordinates from `getClientRects()`, so the
1101
+ * concatenation is well-formed without re-sorting.
1102
+ */
1103
+ readonly visualLineMap: IObservableWithChange<VisualLineMap, void>;
1104
+ }
1105
+
1106
+ /**
1107
+ * {@link ISyntaxHighlighter} backed by monaco's Monarch tokenizer.
1108
+ *
1109
+ * Highlighting is synchronous and incremental: an edit only re-runs the
1110
+ * tokenizer from the first changed line onward (earlier lines and their saved
1111
+ * end-states are reused), and the {@link LengthEdit} delivered with the new
1112
+ * snapshot is the minimal char range whose colour actually changed.
1113
+ *
1114
+ * Only Monarch's *classic* tokenizer path is used, which needs neither a theme
1115
+ * nor the DOM, so this runs headless (Node, workers) as well as in the browser.
1116
+ */
1117
+ export declare class MonacoSyntaxHighlighter implements ISyntaxHighlighter {
1118
+ private readonly _monaco;
1119
+ private readonly _grammars;
1120
+ private readonly _tokenizers;
1121
+ /**
1122
+ * @param _monaco The Monarch runtime ({@link IMonarchApi}), injected so this
1123
+ * package depends on `monaco-editor` for types only.
1124
+ * @param _grammars Maps a language id to its Monarch language definition.
1125
+ */
1126
+ constructor(_monaco: IMonarchApi, _grammars: ReadonlyMap<string, unknown>);
1127
+ create(language: string, initialText: string): ISyntaxHighlighterDocument;
1128
+ dispose(): void;
1129
+ private _tokenizerFor;
1130
+ }
1131
+
1132
+ /**
1133
+ * Move the cursor one position left or right, skipping over hidden marker
1134
+ * ranges in inactive blocks (and inactive items of an active list).
1135
+ */
1136
+ export declare function nextCursorPosition(doc: DocumentAstNode, activeBlock: BlockAstNode | undefined, cursor: number, direction: 'left' | 'right'): number;
1137
+
1138
+ declare const NO_ACTIVE_BLOCKS: unique symbol;
1139
+
1140
+ export declare class OffsetRange {
1141
+ readonly start: number;
1142
+ readonly endExclusive: number;
1143
+ static fromTo(start: number, endExclusive: number): OffsetRange;
1144
+ static ofLength(length: number): OffsetRange;
1145
+ static ofStartAndLength(start: number, length: number): OffsetRange;
1146
+ static emptyAt(offset: number): OffsetRange;
1147
+ constructor(start: number, endExclusive: number);
1148
+ get isEmpty(): boolean;
1149
+ get length(): number;
1150
+ delta(offset: number): OffsetRange;
1151
+ deltaStart(offset: number): OffsetRange;
1152
+ deltaEnd(offset: number): OffsetRange;
1153
+ contains(offset: number): boolean;
1154
+ containsRange(other: OffsetRange): boolean;
1155
+ intersects(other: OffsetRange): boolean;
1156
+ intersectsOrTouches(other: OffsetRange): boolean;
1157
+ intersect(other: OffsetRange): OffsetRange | undefined;
1158
+ join(other: OffsetRange): OffsetRange;
1159
+ isBefore(other: OffsetRange): boolean;
1160
+ isAfter(other: OffsetRange): boolean;
1161
+ substring(str: string): string;
1162
+ slice<T>(arr: readonly T[]): T[];
1163
+ equals(other: OffsetRange): boolean;
1164
+ toString(): string;
1165
+ }
1166
+
1167
+ export declare class ParagraphAstNode extends AstNode {
1168
+ readonly content: readonly (InlineAstNode | GlueAstNode)[];
1169
+ readonly kind = "paragraph";
1170
+ constructor(content: readonly (InlineAstNode | GlueAstNode)[]);
1171
+ get children(): readonly AstNode[];
1172
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1173
+ }
1174
+
1175
+ declare class ParagraphViewData {
1176
+ readonly ast: ParagraphAstNode;
1177
+ readonly content: readonly AnyViewData[];
1178
+ readonly kind = "paragraph";
1179
+ constructor(ast: ParagraphAstNode, content: readonly AnyViewData[]);
1180
+ }
1181
+
1182
+ /**
1183
+ * Immutable point in 2D space, in CSS-pixel client coordinates.
1184
+ */
1185
+ export declare class Point2D {
1186
+ readonly x: number;
1187
+ readonly y: number;
1188
+ static readonly ZERO: Point2D;
1189
+ constructor(x: number, y: number);
1190
+ translate(dx: number, dy: number): Point2D;
1191
+ }
1192
+
1193
+ /**
1194
+ * Immutable axis-aligned rectangle in 2D space, in CSS-pixel client
1195
+ * coordinates. `x`/`y` is the top-left corner, growing right/down.
1196
+ *
1197
+ * Half-open in both dimensions: `right` and `bottom` are excluded.
1198
+ */
1199
+ export declare class Rect2D {
1200
+ readonly x: number;
1201
+ readonly y: number;
1202
+ readonly width: number;
1203
+ readonly height: number;
1204
+ static readonly EMPTY: Rect2D;
1205
+ static fromPointPoint(left: number, top: number, right: number, bottom: number): Rect2D;
1206
+ static fromPointSize(x: number, y: number, width: number, height: number): Rect2D;
1207
+ private constructor();
1208
+ get left(): number;
1209
+ get top(): number;
1210
+ get right(): number;
1211
+ get bottom(): number;
1212
+ get topLeft(): Point2D;
1213
+ containsX(x: number): boolean;
1214
+ containsY(y: number): boolean;
1215
+ containsPoint(p: Point2D): boolean;
1216
+ /** Same y/height, zero-width band at `x = this.left`. Useful for caret rects derived from a line. */
1217
+ withZeroWidthAt(x: number): Rect2D;
1218
+ translate(dx: number, dy: number): Rect2D;
1219
+ }
1220
+
1221
+ export declare const selectAll: SelectionCommand;
1222
+
1223
+ export declare function selectBlock(ctx: CursorCommandContext, blockRange: OffsetRange): Selection_2;
1224
+
1225
+ declare class Selection_2 {
1226
+ readonly anchor: SourceOffset;
1227
+ readonly active: SourceOffset;
1228
+ static collapsed(offset: SourceOffset): Selection_2;
1229
+ constructor(anchor: SourceOffset, active: SourceOffset);
1230
+ get isCollapsed(): boolean;
1231
+ get isForward(): boolean;
1232
+ get range(): OffsetRange;
1233
+ collapseToActive(): Selection_2;
1234
+ withActive(active: SourceOffset): Selection_2;
1235
+ }
1236
+ export { Selection_2 as Selection }
1237
+
1238
+ /**
1239
+ * One mounted block, as far as selection painting is concerned. The view
1240
+ * supplies its block cache in this shape so the selection layer never has
1241
+ * to reach back into private view state.
1242
+ */
1243
+ export declare interface SelectionBlock {
1244
+ readonly block: BlockAstNode;
1245
+ readonly absoluteStart: number;
1246
+ readonly viewNode: ViewNode;
1247
+ readonly element: HTMLElement;
1248
+ }
1249
+
1250
+ export declare type SelectionCommand = (ctx: CursorCommandContext, offset: SourceOffset) => Selection_2;
1251
+
1252
+ export declare interface SelectionRect {
1253
+ readonly x: number;
1254
+ readonly y: number;
1255
+ readonly width: number;
1256
+ readonly height: number;
1257
+ }
1258
+
1259
+ /**
1260
+ * Owns the SVG overlay that paints the selection.
1261
+ *
1262
+ * Rendering is *line-based*, not glyph-based:
1263
+ *
1264
+ * 1. Each {@link VisualLine} overlapping the selection produces one rect
1265
+ * using the full line-box height (so the selection has even, line-
1266
+ * height bands instead of jagged glyph rects).
1267
+ * 2. Inter-block gaps fully inside the selection become connector rects.
1268
+ * 3. All rects are grouped into vertically-adjacent clusters and each
1269
+ * cluster is rendered as a single connected polygon with rounded
1270
+ * corners.
1271
+ *
1272
+ * To keep the polygon connected without gaps, "middle" lines (any line
1273
+ * that is neither the first nor the last selected line in the document)
1274
+ * are extended to their full line extent, while the first and last lines
1275
+ * are clipped to the actual selection start/end. This is the standard
1276
+ * envelope shape used by IDE selection rendering.
1277
+ */
1278
+ export declare class SelectionView extends Disposable {
1279
+ private readonly _parent;
1280
+ readonly element: SVGSVGElement;
1281
+ readonly rendering: IObservable<SelectionViewRendering>;
1282
+ private readonly _path;
1283
+ constructor(_parent: HTMLElement, options: SelectionViewOptions);
1284
+ }
1285
+
1286
+ export declare interface SelectionViewOptions {
1287
+ readonly selection: IObservable<Selection_2 | undefined>;
1288
+ readonly visualLineMap: IObservable<VisualLineMap>;
1289
+ readonly blocks: IObservable<readonly SelectionBlock[]>;
1290
+ }
1291
+
1292
+ export declare class SelectionViewRendering {
1293
+ readonly rects: readonly SelectionRect[];
1294
+ constructor(rects: readonly SelectionRect[]);
1295
+ }
1296
+
1297
+ export declare const selectWord: SelectionCommand;
1298
+
1299
+ /**
1300
+ * A run of {@link Token}s together with the exact {@link OffsetRange} they
1301
+ * cover.
1302
+ *
1303
+ * Because tokens are returned whole (never clipped), this is the natural unit
1304
+ * of structural comparison: for any region untouched by an edit, two snapshots
1305
+ * return an equal `SnapshotTokens` (same `range`, same token lengths/classes).
1306
+ */
1307
+ export declare interface SnapshotTokens {
1308
+ readonly range: OffsetRange;
1309
+ readonly tokens: readonly Token[];
1310
+ }
1311
+
1312
+ export declare type SourceOffset = number;
1313
+
1314
+ export declare class StrikethroughAstNode extends AstNode {
1315
+ readonly openMarker: MarkerAstNode;
1316
+ readonly content: readonly (InlineAstNode | GlueAstNode)[];
1317
+ readonly closeMarker: MarkerAstNode;
1318
+ readonly kind = "strikethrough";
1319
+ constructor(openMarker: MarkerAstNode, content: readonly (InlineAstNode | GlueAstNode)[], closeMarker: MarkerAstNode);
1320
+ get children(): readonly AstNode[];
1321
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1322
+ }
1323
+
1324
+ declare class StrikethroughViewData {
1325
+ readonly ast: StrikethroughAstNode;
1326
+ readonly content: readonly AnyViewData[];
1327
+ readonly kind = "strikethrough";
1328
+ constructor(ast: StrikethroughAstNode, content: readonly AnyViewData[]);
1329
+ }
1330
+
1331
+ export declare class StringEdit {
1332
+ static readonly empty: StringEdit;
1333
+ static single(replacement: StringReplacement): StringEdit;
1334
+ static replace(range: OffsetRange, text: string): StringEdit;
1335
+ static insert(offset: number, text: string): StringEdit;
1336
+ static delete(range: OffsetRange): StringEdit;
1337
+ readonly replacements: readonly StringReplacement[];
1338
+ constructor(replacements: readonly StringReplacement[]);
1339
+ get isEmpty(): boolean;
1340
+ apply(base: string): string;
1341
+ inverse(original: string): StringEdit;
1342
+ equals(other: StringEdit): boolean;
1343
+ mapOffset(offset: number): number;
1344
+ toString(): string;
1345
+ }
1346
+
1347
+ export declare class StringReplacement {
1348
+ readonly replaceRange: OffsetRange;
1349
+ readonly newText: string;
1350
+ static insert(offset: number, text: string): StringReplacement;
1351
+ static replace(range: OffsetRange, text: string): StringReplacement;
1352
+ static delete(range: OffsetRange): StringReplacement;
1353
+ constructor(replaceRange: OffsetRange, newText: string);
1354
+ get isEmpty(): boolean;
1355
+ equals(other: StringReplacement): boolean;
1356
+ toString(): string;
1357
+ }
1358
+
1359
+ export declare class StringValue {
1360
+ readonly value: string;
1361
+ constructor(value: string);
1362
+ get length(): number;
1363
+ substring(range: OffsetRange): string;
1364
+ toString(): string;
1365
+ }
1366
+
1367
+ export declare class StrongAstNode extends AstNode {
1368
+ readonly openMarker: MarkerAstNode;
1369
+ readonly content: readonly (InlineAstNode | GlueAstNode)[];
1370
+ readonly closeMarker: MarkerAstNode;
1371
+ readonly kind = "strong";
1372
+ constructor(openMarker: MarkerAstNode, content: readonly (InlineAstNode | GlueAstNode)[], closeMarker: MarkerAstNode);
1373
+ get children(): readonly AstNode[];
1374
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1375
+ }
1376
+
1377
+ declare class StrongViewData {
1378
+ readonly ast: StrongAstNode;
1379
+ readonly content: readonly AnyViewData[];
1380
+ readonly kind = "strong";
1381
+ constructor(ast: StrongAstNode, content: readonly AnyViewData[]);
1382
+ }
1383
+
1384
+ export declare class TableAstNode extends AstNode {
1385
+ readonly content: readonly (TableRowAstNode | GlueAstNode)[];
1386
+ readonly kind = "table";
1387
+ constructor(content: readonly (TableRowAstNode | GlueAstNode)[]);
1388
+ get children(): readonly AstNode[];
1389
+ private get _rows();
1390
+ get headerRow(): TableRowAstNode | undefined;
1391
+ get delimiterRow(): TableRowAstNode | undefined;
1392
+ get bodyRows(): readonly TableRowAstNode[];
1393
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1394
+ }
1395
+
1396
+ export declare class TableCellAstNode extends AstNode {
1397
+ readonly content: readonly (InlineAstNode | MarkerAstNode | GlueAstNode)[];
1398
+ readonly kind = "tableCell";
1399
+ constructor(content: readonly (InlineAstNode | MarkerAstNode | GlueAstNode)[]);
1400
+ get children(): readonly AstNode[];
1401
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1402
+ }
1403
+
1404
+ declare class TableCellViewData {
1405
+ readonly ast: TableCellAstNode;
1406
+ /** Whether the selection reaches this cell (reveals its inline markers). */
1407
+ readonly isActive: boolean;
1408
+ /** Whether the owning table is active (reveals the structural pipes). */
1409
+ readonly showTableGlue: boolean;
1410
+ readonly content: readonly AnyViewData[];
1411
+ readonly kind = "tableCell";
1412
+ constructor(ast: TableCellAstNode,
1413
+ /** Whether the selection reaches this cell (reveals its inline markers). */
1414
+ isActive: boolean,
1415
+ /** Whether the owning table is active (reveals the structural pipes). */
1416
+ showTableGlue: boolean, content: readonly AnyViewData[]);
1417
+ }
1418
+
1419
+ export declare class TableRowAstNode extends AstNode {
1420
+ readonly content: readonly (TableCellAstNode | GlueAstNode)[];
1421
+ readonly kind = "tableRow";
1422
+ constructor(content: readonly (TableCellAstNode | GlueAstNode)[]);
1423
+ get children(): readonly AstNode[];
1424
+ get cells(): readonly TableCellAstNode[];
1425
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1426
+ }
1427
+
1428
+ declare class TableRowViewData {
1429
+ readonly ast: TableRowAstNode;
1430
+ readonly isDelimiter: boolean;
1431
+ readonly content: readonly AnyViewData[];
1432
+ readonly kind = "tableRow";
1433
+ constructor(ast: TableRowAstNode, isDelimiter: boolean, content: readonly AnyViewData[]);
1434
+ }
1435
+
1436
+ declare class TableViewData {
1437
+ readonly ast: TableAstNode;
1438
+ readonly content: readonly AnyViewData[];
1439
+ readonly kind = "table";
1440
+ constructor(ast: TableAstNode, content: readonly AnyViewData[]);
1441
+ }
1442
+
1443
+ /**
1444
+ * Source range (relative to `item`) of a task list item's `[x]`/`[ ]`
1445
+ * checkbox, or `undefined` when the item is not a task item. The checkbox is
1446
+ * plain glue in the AST, so a host that wants to toggle it locates the literal
1447
+ * `[x]`/`[ ]` token here.
1448
+ */
1449
+ export declare function taskCheckboxRange(item: ListItemAstNode): OffsetRange | undefined;
1450
+
1451
+ /** Real document text (an {@link InlineAstNode}). */
1452
+ export declare class TextAstNode extends LeafAstNode {
1453
+ readonly content: string;
1454
+ readonly kind = "text";
1455
+ constructor(content: string);
1456
+ protected _localEquals(o: this): boolean;
1457
+ }
1458
+
1459
+ declare class TextViewData {
1460
+ readonly ast: TextAstNode;
1461
+ readonly showWhitespace: boolean;
1462
+ readonly leftWordBoundary: boolean;
1463
+ readonly rightWordBoundary: boolean;
1464
+ readonly kind = "text";
1465
+ /**
1466
+ * Whether non-obvious whitespace in this text is revealed (block is active).
1467
+ * `leftWordBoundary`/`rightWordBoundary` say whether the inline sibling on
1468
+ * that side ends/starts with visible word content (e.g. inline code, a link,
1469
+ * emphasis); a single space touching such a sibling is obvious and stays
1470
+ * undecorated, just like a space between two words within this leaf.
1471
+ */
1472
+ constructor(ast: TextAstNode, showWhitespace: boolean, leftWordBoundary?: boolean, rightWordBoundary?: boolean);
1473
+ }
1474
+
1475
+ export declare class ThematicBreakAstNode extends AstNode {
1476
+ readonly content: readonly (MarkerAstNode | GlueAstNode)[];
1477
+ readonly kind = "thematicBreak";
1478
+ constructor(content: readonly (MarkerAstNode | GlueAstNode)[]);
1479
+ get children(): readonly AstNode[];
1480
+ get marker(): MarkerAstNode | undefined;
1481
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1482
+ }
1483
+
1484
+ declare class ThematicBreakViewData {
1485
+ readonly ast: ThematicBreakAstNode;
1486
+ /** Active: reveal the source markup (`---`) instead of the rendered rule. */
1487
+ readonly showMarkup: boolean;
1488
+ /** Marker (and any absorbed trailing glue), rendered only when active. */
1489
+ readonly content: readonly AnyViewData[];
1490
+ readonly kind = "thematicBreak";
1491
+ constructor(ast: ThematicBreakAstNode,
1492
+ /** Active: reveal the source markup (`---`) instead of the rendered rule. */
1493
+ showMarkup: boolean,
1494
+ /** Marker (and any absorbed trailing glue), rendered only when active. */
1495
+ content: readonly AnyViewData[]);
1496
+ }
1497
+
1498
+ /**
1499
+ * A coloured run of `length` characters. Tokens are *dense* and *offset-free*:
1500
+ * a snapshot's tokens for a range cover it exactly, back to back, so
1501
+ * `sum(token.length) === range.length`. A token never stores where it is — its
1502
+ * position is implied by the lengths of the tokens before it, mirroring how the
1503
+ * rest of the editor keeps source offsets out of its data structures.
1504
+ */
1505
+ export declare class Token {
1506
+ readonly length: number;
1507
+ /** CSS class for this run, or `undefined` for an unstyled run. */
1508
+ readonly className: string | undefined;
1509
+ constructor(length: number,
1510
+ /** CSS class for this run, or `undefined` for an unstyled run. */
1511
+ className: string | undefined);
1512
+ }
1513
+
1514
+ /**
1515
+ * Immutable view of an AST node. Pairs `ast` with its rendered `dom` and a
1516
+ * mirror of `ast.children` as ViewNode children. Source offsets are NEVER
1517
+ * stored — they are recomputed by walking and summing `ast.length` of
1518
+ * preceding siblings, just like the AST itself.
1519
+ *
1520
+ * Leaves are ViewNodes with no children. A leaf whose `dom` is a Text node
1521
+ * participates in source mapping; a leaf whose `dom` is an Element does not
1522
+ * (e.g. KaTeX-rendered math, or `<hr>` for a thematic break).
1523
+ */
1524
+ export declare class ViewNode extends Disposable {
1525
+ readonly ast: AstNode;
1526
+ readonly dom: globalThis.Node;
1527
+ private _children;
1528
+ constructor(ast: AstNode, dom: globalThis.Node, children?: readonly ViewNode[]);
1529
+ /** This node's view children (a mirror of `ast.children`). */
1530
+ get children(): readonly ViewNode[];
1531
+ /**
1532
+ * Replace this node's children in place, disposing the old ones and
1533
+ * re-pointing the new ones' parent to this node. The node value is still
1534
+ * conceptually immutable with respect to its `ast`/`dom` *identity*; this
1535
+ * is used only when a node patches its own DOM subtree in place (a code
1536
+ * block re-tokenising on a highlighter recolour), where the source-mapping
1537
+ * leaves must follow the new DOM text nodes without rebuilding the node
1538
+ * itself.
1539
+ */
1540
+ protected _replaceChildren(children: readonly ViewNode[]): void;
1541
+ dispose(): void;
1542
+ /**
1543
+ * The number of source characters this node spans. Defaults to the length
1544
+ * of its {@link ast}; a synthetic leaf that subdivides one ast node (a
1545
+ * decorated-whitespace character, a code-block token span) shares that ast
1546
+ * for identity but overrides this with the length of its own slice, so the
1547
+ * renderer never has to fabricate an AST node just to carry a length.
1548
+ */
1549
+ get sourceLength(): number;
1550
+ /**
1551
+ * The DOM node a parent mounts for this child. It is {@link dom} for almost
1552
+ * everything; a marker is the exception — its `dom` is the inner Text node
1553
+ * (so source ↔ DOM mapping lands on it) while the node it mounts is the
1554
+ * wrapping `<span>`.
1555
+ */
1556
+ get mountNode(): globalThis.Node;
1557
+ /** The view node that rendered this node's parent, or `undefined` for a root. */
1558
+ get parent(): ViewNode | undefined;
1559
+ /**
1560
+ * Closest view node owning `domNode`: the node itself if registered, else
1561
+ * the nearest registered ancestor. Returns `undefined` if the DOM node is
1562
+ * outside any view tree.
1563
+ */
1564
+ static forDom(domNode: globalThis.Node | null): ViewNode | undefined;
1565
+ /**
1566
+ * This node's start offset within its parent's local source space: the sum
1567
+ * of the `ast.length` of the siblings before it. Polymorphic via
1568
+ * {@link _localOffsetOfChild} so a parent whose children do not map
1569
+ * linearly (e.g. it hides or reorders some) can override how its children
1570
+ * are placed.
1571
+ */
1572
+ localOffsetInParent(): number;
1573
+ /** Start offset of `child` within this node's local source space. */
1574
+ protected _localOffsetOfChild(child: ViewNode): number;
1575
+ /**
1576
+ * Map a DOM hit that lands on THIS node's own representation into a source
1577
+ * range in this node's local space `[0, ast.length)`. Polymorphic: a text
1578
+ * leaf maps the caret offset 1:1; an element-only node (KaTeX math, `<hr>`,
1579
+ * an image, a hidden marker) has no internal text mapping and snaps to its
1580
+ * start by default — subclasses may override (e.g. to snap to the nearer
1581
+ * edge by x).
1582
+ */
1583
+ getLocalSourceRange(pos: DomPosition): OffsetRange;
1584
+ /**
1585
+ * DOM hit (any node + offset within it) → source offset relative to THIS
1586
+ * node, or `undefined` when the hit is outside this node's subtree. Enters
1587
+ * the tree at the closest owning view node ({@link forDom}), maps the hit
1588
+ * into that node's local space ({@link getLocalSourceRange}), then lifts the
1589
+ * range up the parent chain — adding each node's {@link localOffsetInParent} —
1590
+ * until it reaches this node.
1591
+ */
1592
+ resolveSource(pos: DomPosition): number | undefined;
1593
+ /**
1594
+ * Source offset → DOM position. `nodeOffset` is the absolute source
1595
+ * offset of THIS node's start. Returns a position into a DOM Text node,
1596
+ * descending into children based on accumulated lengths.
1597
+ */
1598
+ sourceToDom(localSourceOffset: number, nodeSourceOffset?: number): DomPosition | undefined;
1599
+ /** Visit every text-bearing leaf in this subtree with its absolute offset. */
1600
+ forEachTextLeaf(nodeOffset: number, visitor: (leaf: ViewNode, leafOffset: number) => void): void;
1601
+ }
1602
+
1603
+ export declare type VisualCursorCommand = (ctx: VisualCursorCommandContext) => CursorMoveResult;
1604
+
1605
+ export declare interface VisualCursorCommandContext extends CursorCommandContext {
1606
+ readonly lineMap: VisualLineMap;
1607
+ readonly desiredColumn: number | undefined;
1608
+ }
1609
+
1610
+ export declare function visualizeAst(root: AstNode, source: string): AstVisualization;
1611
+
1612
+ /**
1613
+ * One visual line of rendered text: a horizontal band
1614
+ * (`rect.top`..`rect.bottom`) split into one or more {@link VisualRun}s
1615
+ * arranged left-to-right.
1616
+ */
1617
+ export declare class VisualLine {
1618
+ readonly rect: Rect2D;
1619
+ readonly runs: readonly VisualRun[];
1620
+ constructor(rect: Rect2D, runs: readonly VisualRun[]);
1621
+ containsOffset(offset: SourceOffset): boolean;
1622
+ /**
1623
+ * How `offset` relates to this line's runs:
1624
+ * - `'covers'`: a run starts at or strictly contains the offset
1625
+ * (`start <= offset < endExclusive`) — the caret belongs on this line.
1626
+ * - `'end'`: the offset is only some run's trailing boundary
1627
+ * (`offset === endExclusive`) with no run covering it — a line-break
1628
+ * boundary the caret should leave for the next line.
1629
+ * - `'none'`: no run touches the offset.
1630
+ */
1631
+ offsetMembership(offset: SourceOffset): 'covers' | 'end' | 'none';
1632
+ /**
1633
+ * Min `|offset - r|` over offsets `r` in any of this line's runs. Used
1634
+ * to pick the nearest line when no run actually covers the offset.
1635
+ */
1636
+ sourceDistanceTo(offset: SourceOffset): number;
1637
+ /**
1638
+ * x of the caret position before `offset` on this line. When `offset`
1639
+ * is past all runs (trailing whitespace / blank line), returns the
1640
+ * right edge of the last run; when before all runs, returns the left
1641
+ * edge of the first run.
1642
+ */
1643
+ xAtOffset(offset: SourceOffset): number;
1644
+ /**
1645
+ * Snap `x` to the nearest offset on this line. If `x` falls inside a
1646
+ * run, the offset is interpolated by character fraction; otherwise it
1647
+ * snaps to the closer edge of the nearest run.
1648
+ */
1649
+ offsetAtX(x: number): SourceOffset;
1650
+ }
1651
+
1652
+ /**
1653
+ * Geometry of the rendered document, as a map from source offsets to 2D
1654
+ * positions and back.
1655
+ *
1656
+ * Structure (top to bottom):
1657
+ *
1658
+ * VisualLineMap = ordered list of VisualLines
1659
+ * VisualLine = a horizontal band [rect.top, rect.bottom) split
1660
+ * into one or more VisualRuns
1661
+ * VisualRun = a contiguous source range painted at a rectangle
1662
+ * on the line
1663
+ *
1664
+ * Invariants:
1665
+ * - `lines[i].rect.bottom <= lines[i+1].rect.top + ε`
1666
+ * - For any offset `o` covered by some run on line `L`:
1667
+ * `xAtOffset(o)` is inside that run's horizontal range
1668
+ * `xAtOffset(o)` is inside `L.rect.left..L.rect.right`
1669
+ *
1670
+ * The "map" goes both ways:
1671
+ * - SourceOffset → (line, x) via {@link lineIndexOfOffset} + {@link xAtOffset}
1672
+ * - Point2D → SourceOffset via {@link offsetAtPoint}
1673
+ *
1674
+ * Both directions are total but not bijective: many offsets at a line
1675
+ * boundary map to the same `x`, and large areas of the document
1676
+ * (padding, gaps) map onto the nearest offset on the nearest line.
1677
+ *
1678
+ * Rendering a caret rect from these primitives is a consumer concern:
1679
+ *
1680
+ * const i = map.lineIndexOfOffset(o);
1681
+ * const caretRect = map.lineRect(i).withZeroWidthAt(map.xAtOffset(o));
1682
+ */
1683
+ export declare class VisualLineMap {
1684
+ readonly lines: readonly VisualLine[];
1685
+ static readonly EMPTY: VisualLineMap;
1686
+ static measure(blockViews: readonly {
1687
+ readonly absoluteStart: number;
1688
+ readonly viewNode: ViewNode;
1689
+ }[]): VisualLineMap;
1690
+ constructor(lines: readonly VisualLine[]);
1691
+ get lineCount(): number;
1692
+ get isEmpty(): boolean;
1693
+ lineRect(lineIndex: number): Rect2D;
1694
+ /**
1695
+ * Line whose runs cover the offset, or the nearest line by source
1696
+ * distance if no run covers it.
1697
+ *
1698
+ * An offset that is only a run's *trailing* boundary (`offset ===
1699
+ * endExclusive`) — most notably the source offset just past a
1700
+ * line-breaking `\n`, which a zero-width run reports as its end on the line
1701
+ * it terminates — belongs to the START of the NEXT line instead. Preferring
1702
+ * the line that actually *starts* the offset makes the caret advance past a
1703
+ * newline to the next line rather than collapsing onto the previous line's
1704
+ * end (which would render two distinct offsets at the same caret position).
1705
+ * The first such trailing-boundary line is remembered as a fallback for the
1706
+ * document's very last offset, where no later line starts it.
1707
+ */
1708
+ lineIndexOfOffset(offset: SourceOffset): number;
1709
+ /**
1710
+ * x of the caret position before `offset`, on the line returned by
1711
+ * {@link lineIndexOfOffset}. Returns `0` when the map is empty.
1712
+ */
1713
+ xAtOffset(offset: SourceOffset): number;
1714
+ /**
1715
+ * Line whose vertical band contains `y`, clamped to the first/last
1716
+ * line when `y` is outside the document.
1717
+ */
1718
+ lineIndexAtY(y: number): number;
1719
+ /**
1720
+ * Snap a 2D point to the nearest source offset. Uses `y` to pick a
1721
+ * line, then `x` to pick an offset within it. Up/down navigation
1722
+ * uses {@link offsetInLineAtX} directly to preserve desired column.
1723
+ */
1724
+ offsetAtPoint(point: Point2D): SourceOffset;
1725
+ /** Snap `x` to the nearest offset on a specific line. */
1726
+ offsetInLineAtX(lineIndex: number, x: number): SourceOffset;
1727
+ }
1728
+
1729
+ /**
1730
+ * One contiguous run of text painted on a single visual line.
1731
+ *
1732
+ * When constructed with a {@link VisualRunSource}, `xAtOffset` returns the
1733
+ * pixel-exact x of the caret before character `offset` by measuring the
1734
+ * prefix `[textNodeStart, textNodeStart + (offset - sourceStart))` with a
1735
+ * DOM `Range`. Without a source it falls back to linear interpolation
1736
+ * across `rect.width`.
1737
+ */
1738
+ export declare class VisualRun {
1739
+ readonly sourceRange: OffsetRange;
1740
+ readonly rect: Rect2D;
1741
+ readonly source?: VisualRunSource | undefined;
1742
+ constructor(sourceRange: OffsetRange, rect: Rect2D, source?: VisualRunSource | undefined);
1743
+ get sourceStart(): SourceOffset;
1744
+ get sourceEndExclusive(): SourceOffset;
1745
+ get sourceLength(): number;
1746
+ containsOffset(offset: SourceOffset): boolean;
1747
+ sourceDistanceTo(offset: SourceOffset): number;
1748
+ xAtOffset(offset: SourceOffset): number;
1749
+ offsetAtX(x: number): SourceOffset;
1750
+ }
1751
+
1752
+ /**
1753
+ * The DOM source of a {@link VisualRun}. When set, `xAtOffset` and
1754
+ * `offsetAtX` measure exact glyph positions via `Range.getBoundingClientRect`
1755
+ * instead of linear interpolation across the run's rect. This matters for
1756
+ * proportional fonts where character widths differ a lot (e.g. `m` vs `i`)
1757
+ * and a caret placed by interpolation lands several pixels inside the
1758
+ * wrong character.
1759
+ *
1760
+ * Hand-built runs (tests) omit this; their `xAtOffset` falls back to
1761
+ * linear interpolation.
1762
+ */
1763
+ declare interface VisualRunSource {
1764
+ readonly textNode: Text;
1765
+ /** Offset within `textNode.data` corresponding to `sourceRange.start`. */
1766
+ readonly textNodeStart: number;
1767
+ }
1768
+
1769
+ export { }