@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.
- package/dist/_observables/assert.d.ts +2 -0
- package/dist/_observables/deps.d.ts +28 -0
- package/dist/_observables/disposables.d.ts +19 -0
- package/dist/_observables/equals.d.ts +32 -0
- package/dist/_observables/index.d.ts +2 -0
- package/dist/_observables/observableInternal/base.d.ts +172 -0
- package/dist/_observables/observableInternal/changeTracker.d.ts +44 -0
- package/dist/_observables/observableInternal/commonFacade/cancellation.d.ts +24 -0
- package/dist/_observables/observableInternal/commonFacade/deps.d.ts +24 -0
- package/dist/_observables/observableInternal/debugLocation.d.ts +21 -0
- package/dist/_observables/observableInternal/debugName.d.ts +33 -0
- package/dist/_observables/observableInternal/experimental/deferUnobserve.d.ts +16 -0
- package/dist/_observables/observableInternal/experimental/reducer.d.ts +37 -0
- package/dist/_observables/observableInternal/experimental/utils.d.ts +15 -0
- package/dist/_observables/observableInternal/index.d.ts +25 -0
- package/dist/_observables/observableInternal/logging/consoleObservableLogger.d.ts +40 -0
- package/dist/_observables/observableInternal/logging/debugGetDependencyGraph.d.ts +4 -0
- package/dist/_observables/observableInternal/logging/debugger/debuggerRpc.d.ts +4 -0
- package/dist/_observables/observableInternal/logging/debugger/devToolsLogger.d.ts +43 -0
- package/dist/_observables/observableInternal/logging/debugger/rpc.d.ts +41 -0
- package/dist/_observables/observableInternal/logging/debugger/utils.d.ts +13 -0
- package/dist/_observables/observableInternal/logging/logging.d.ts +30 -0
- package/dist/_observables/observableInternal/map.d.ts +18 -0
- package/dist/_observables/observableInternal/observables/baseObservable.d.ts +58 -0
- package/dist/_observables/observableInternal/observables/constObservable.d.ts +5 -0
- package/dist/_observables/observableInternal/observables/derived.d.ts +46 -0
- package/dist/_observables/observableInternal/observables/derivedImpl.d.ts +83 -0
- package/dist/_observables/observableInternal/observables/lazyObservableValue.d.ts +27 -0
- package/dist/_observables/observableInternal/observables/observableFromEvent.d.ts +37 -0
- package/dist/_observables/observableInternal/observables/observableSignal.d.ts +11 -0
- package/dist/_observables/observableInternal/observables/observableSignalFromEvent.d.ts +5 -0
- package/dist/_observables/observableInternal/observables/observableValue.d.ts +37 -0
- package/dist/_observables/observableInternal/observables/observableValueOpts.d.ts +8 -0
- package/dist/_observables/observableInternal/reactions/autorun.d.ts +56 -0
- package/dist/_observables/observableInternal/reactions/autorunImpl.d.ts +53 -0
- package/dist/_observables/observableInternal/set.d.ts +17 -0
- package/dist/_observables/observableInternal/transaction.d.ts +27 -0
- package/dist/_observables/observableInternal/utils/promise.d.ts +75 -0
- package/dist/_observables/observableInternal/utils/runOnChange.d.ts +7 -0
- package/dist/_observables/observableInternal/utils/utils.d.ts +43 -0
- package/dist/_observables/observableInternal/utils/utilsCancellation.d.ts +10 -0
- package/dist/_observables/observableInternal/utils/valueWithChangeEvent.d.ts +10 -0
- package/dist/_observables/utils.d.ts +15 -0
- package/dist/index.d.ts +1769 -6
- package/dist/observables.d.ts +4 -1
- package/package.json +1 -1
- package/dist/commands/cursorCommands.d.ts +0 -13
- package/dist/commands/editCommands.d.ts +0 -14
- package/dist/commands/index.d.ts +0 -4
- package/dist/commands/selectionCommands.d.ts +0 -6
- package/dist/commands/types.d.ts +0 -26
- package/dist/core/geometry.d.ts +0 -37
- package/dist/core/index.d.ts +0 -8
- package/dist/core/lengthEdit.d.ts +0 -38
- package/dist/core/offsetRange.d.ts +0 -26
- package/dist/core/selection.d.ts +0 -13
- package/dist/core/sourceOffset.d.ts +0 -1
- package/dist/core/stringEdit.d.ts +0 -27
- package/dist/core/stringValue.d.ts +0 -8
- package/dist/core/wordUtils.d.ts +0 -6
- package/dist/highlighter/defaultMonacoSyntaxHighlighter.d.ts +0 -20
- package/dist/highlighter/index.d.ts +0 -3
- package/dist/highlighter/monacoSyntaxHighlighter.d.ts +0 -38
- package/dist/highlighter/syntaxHighlighter.d.ts +0 -67
- package/dist/model/cursorNavigation.d.ts +0 -7
- package/dist/model/editorModel.d.ts +0 -54
- package/dist/model/index.d.ts +0 -4
- package/dist/model/measuredLayoutModel.d.ts +0 -50
- package/dist/parser/_micromarkAdapter.d.ts +0 -7
- package/dist/parser/ast.d.ts +0 -274
- package/dist/parser/index.d.ts +0 -4
- package/dist/parser/parse.d.ts +0 -2
- package/dist/parser/parser.d.ts +0 -14
- package/dist/parser/reconcile.d.ts +0 -33
- package/dist/parser/test/getAnnotatedSource.d.ts +0 -2
- package/dist/parser/test/snapshot.d.ts +0 -9
- package/dist/parser/visualizeAst.d.ts +0 -33
- package/dist/test/random.d.ts +0 -16
- package/dist/view/content/blockView.d.ts +0 -179
- package/dist/view/content/documentView.d.ts +0 -41
- package/dist/view/content/dom.d.ts +0 -16
- package/dist/view/content/katexEditableIdentifiers.d.ts +0 -36
- package/dist/view/content/viewNode.d.ts +0 -93
- package/dist/view/editorController.d.ts +0 -34
- package/dist/view/editorView.d.ts +0 -100
- package/dist/view/fixture/astViewerView.d.ts +0 -27
- package/dist/view/fixture/cyclingTsHighlighter.d.ts +0 -17
- package/dist/view/fixture/debugColors.d.ts +0 -26
- package/dist/view/fixture/monacoDebugPanel.d.ts +0 -7
- package/dist/view/index.d.ts +0 -9
- package/dist/view/measuredLayoutDebugView.d.ts +0 -70
- package/dist/view/parts/cursorView.d.ts +0 -29
- package/dist/view/parts/selectionView.d.ts +0 -57
- package/dist/view/viewData.d.ts +0 -251
- package/dist/view/visualLineMap.d.ts +0 -157
- package/dist/view/visualizeViewTree.d.ts +0 -5
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,1769 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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 `` 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 `` 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 { }
|