@vscode/markdown-editor 0.0.2-13 → 0.0.2-130

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/README.md +644 -0
  2. package/dist/commands.d.ts +67 -0
  3. package/dist/commands.js +185 -0
  4. package/dist/commands.js.map +1 -0
  5. package/dist/config-BGeaJqWk.js +286 -0
  6. package/dist/config-BGeaJqWk.js.map +1 -0
  7. package/dist/config.d.ts +10 -0
  8. package/dist/config.js +6 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/index.d.ts +1611 -270
  11. package/dist/index.js +7839 -3291
  12. package/dist/index.js.map +1 -1
  13. package/dist/markdown-editor.css +1 -1
  14. package/dist/scrolling-C4GW1cCQ.js +391 -0
  15. package/dist/scrolling-C4GW1cCQ.js.map +1 -0
  16. package/dist/web-editors.d.ts +353 -0
  17. package/dist/web-editors.js +7525 -0
  18. package/dist/web-editors.js.map +1 -0
  19. package/package.json +59 -19
  20. package/src/contrib/comments/commentInput.css +38 -80
  21. package/src/contrib/comments/commentWidget.css +60 -0
  22. package/src/contrib/find/find.css +347 -0
  23. package/src/contrib/rename/rename.css +73 -0
  24. package/src/contrib/suggest/suggest.css +109 -0
  25. package/src/view/editor.css +1677 -111
  26. package/src/view/themes/default.css +21 -4
  27. package/src/view/themes/github.css +25 -13
  28. package/src/view/themes/vscode-default.css +98 -23
  29. package/src/view/themes/vscode-github.css +84 -15
  30. package/dist/_observables/assert.d.ts +0 -2
  31. package/dist/_observables/deps.d.ts +0 -28
  32. package/dist/_observables/disposables.d.ts +0 -19
  33. package/dist/_observables/equals.d.ts +0 -32
  34. package/dist/_observables/index.d.ts +0 -2
  35. package/dist/_observables/observableInternal/base.d.ts +0 -172
  36. package/dist/_observables/observableInternal/changeTracker.d.ts +0 -44
  37. package/dist/_observables/observableInternal/commonFacade/cancellation.d.ts +0 -24
  38. package/dist/_observables/observableInternal/commonFacade/deps.d.ts +0 -24
  39. package/dist/_observables/observableInternal/debugLocation.d.ts +0 -21
  40. package/dist/_observables/observableInternal/debugName.d.ts +0 -33
  41. package/dist/_observables/observableInternal/experimental/deferUnobserve.d.ts +0 -16
  42. package/dist/_observables/observableInternal/experimental/reducer.d.ts +0 -37
  43. package/dist/_observables/observableInternal/experimental/utils.d.ts +0 -15
  44. package/dist/_observables/observableInternal/index.d.ts +0 -25
  45. package/dist/_observables/observableInternal/logging/consoleObservableLogger.d.ts +0 -40
  46. package/dist/_observables/observableInternal/logging/debugGetDependencyGraph.d.ts +0 -4
  47. package/dist/_observables/observableInternal/logging/debugger/debuggerRpc.d.ts +0 -4
  48. package/dist/_observables/observableInternal/logging/debugger/devToolsLogger.d.ts +0 -43
  49. package/dist/_observables/observableInternal/logging/debugger/rpc.d.ts +0 -41
  50. package/dist/_observables/observableInternal/logging/debugger/utils.d.ts +0 -13
  51. package/dist/_observables/observableInternal/logging/logging.d.ts +0 -30
  52. package/dist/_observables/observableInternal/map.d.ts +0 -18
  53. package/dist/_observables/observableInternal/observables/baseObservable.d.ts +0 -58
  54. package/dist/_observables/observableInternal/observables/constObservable.d.ts +0 -5
  55. package/dist/_observables/observableInternal/observables/derived.d.ts +0 -46
  56. package/dist/_observables/observableInternal/observables/derivedImpl.d.ts +0 -83
  57. package/dist/_observables/observableInternal/observables/lazyObservableValue.d.ts +0 -27
  58. package/dist/_observables/observableInternal/observables/observableFromEvent.d.ts +0 -37
  59. package/dist/_observables/observableInternal/observables/observableSignal.d.ts +0 -11
  60. package/dist/_observables/observableInternal/observables/observableSignalFromEvent.d.ts +0 -5
  61. package/dist/_observables/observableInternal/observables/observableValue.d.ts +0 -37
  62. package/dist/_observables/observableInternal/observables/observableValueOpts.d.ts +0 -8
  63. package/dist/_observables/observableInternal/reactions/autorun.d.ts +0 -56
  64. package/dist/_observables/observableInternal/reactions/autorunImpl.d.ts +0 -53
  65. package/dist/_observables/observableInternal/set.d.ts +0 -17
  66. package/dist/_observables/observableInternal/transaction.d.ts +0 -27
  67. package/dist/_observables/observableInternal/utils/promise.d.ts +0 -75
  68. package/dist/_observables/observableInternal/utils/runOnChange.d.ts +0 -7
  69. package/dist/_observables/observableInternal/utils/utils.d.ts +0 -43
  70. package/dist/_observables/observableInternal/utils/utilsCancellation.d.ts +0 -10
  71. package/dist/_observables/observableInternal/utils/valueWithChangeEvent.d.ts +0 -10
  72. package/dist/_observables/utils.d.ts +0 -15
  73. package/dist/observables.d.ts +0 -4
  74. package/dist/observables.js +0 -439
  75. package/dist/observables.js.map +0 -1
  76. package/dist/runOnChange-C00UIwqQ.js +0 -1538
  77. package/dist/runOnChange-C00UIwqQ.js.map +0 -1
  78. package/src/contrib/comments/comments.css +0 -129
  79. package/src/contrib/commentsVscode/vscodeCommentWidgetV2.css +0 -166
package/dist/index.d.ts CHANGED
@@ -1,9 +1,10 @@
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';
1
+ import { Disposable } from '@vscode/observables';
2
+ import { IDisposable } from '@vscode/observables';
3
+ import { IObservable } from '@vscode/observables';
4
+ import { IObservableWithChange } from '@vscode/observables';
5
+ import { IReader } from '@vscode/observables';
6
+ import { ISettableObservable } from '@vscode/observables';
7
+ import { ITransaction } from '@vscode/observables';
7
8
  import { MonarchTokenizer } from 'monaco-editor/esm/vs/editor/standalone/common/monarch/monarchLexer.js';
8
9
 
9
10
  declare interface AddedItem {
@@ -24,7 +25,7 @@ declare interface AnnotatedRange {
24
25
  }
25
26
 
26
27
  /** Every concrete node kind, for exhaustive consumer-side dispatch. */
27
- 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;
28
+ export declare type AnyAstNode = TextAstNode | MarkerAstNode | GlueAstNode | ThematicBreakAstNode | StrongAstNode | EmphasisAstNode | StrikethroughAstNode | InlineCodeAstNode | InlineMathAstNode | LinkAstNode | ImageAstNode | HeadingAstNode | ParagraphAstNode | EmptyBlockAstNode | FrontMatterAstNode | CodeBlockAstNode | MathBlockAstNode | VideoAstNode | BlockQuoteAstNode | ListAstNode | ListItemAstNode | TableAstNode | TableRowAstNode | TableCellAstNode | DocumentAstNode | UnhandledBlockAstNode;
28
29
 
29
30
  declare type AnyViewData = DocumentViewData | BlockViewData | InlineViewData | ListItemViewData | TableRowViewData | TableCellViewData | MarkerViewData | GlueViewData | DiffHunkViewData | DiffDecorationViewData;
30
31
 
@@ -72,23 +73,33 @@ declare interface AstVisualizationNode {
72
73
  }
73
74
 
74
75
  /**
75
- * Strategy for hosts that never deliver native clipboard events to the editor
76
- * — most importantly VS Code webviews, whose preload calls `preventDefault()`
77
- * on the Ctrl/Cmd+C/X/V keydowns, so no `copy`/`cut`/`paste` event is ever
78
- * dispatched. Here the keystrokes are the only signal, so this strategy
79
- * listens for them directly and drives the async {@link Clipboard} API
80
- * (`navigator.clipboard`), which webviews are granted.
76
+ * Strategy for hosts that intercept native clipboard shortcuts, notably
77
+ * VS Code webviews. Their preload prevents the default Ctrl/Cmd+C/X/V handling
78
+ * and forwards the keydowns to the host. This strategy handles the keystrokes
79
+ * directly using the async {@link Clipboard} API (`navigator.clipboard`),
80
+ * which webviews are granted.
81
81
  *
82
82
  * Cut deletes synchronously once the text is captured; the clipboard write is
83
83
  * fire-and-forget. Paste must wait for the async read before inserting.
84
+ * Handled keydowns must not reach the host, which may replay native clipboard
85
+ * commands even when the browser's default has been prevented.
86
+ *
87
+ * Hosts can supply a paste callback to read images or other clipboard formats.
88
+ * It receives the original context, whether Shift requested plain text, and
89
+ * native clipboard data when a paste event supplied it. Context menus focus a
90
+ * temporary editable target so native paste works with EditContext roots too.
91
+ * The callback owns asynchronous errors and stale-selection checks. It does
92
+ * not override copy/cut or clipboard handling in nested native inputs.
84
93
  */
85
94
  export declare class AsyncClipboardStrategy implements IClipboardStrategy {
86
95
  private readonly _clipboard;
87
- constructor(_clipboard?: Clipboard);
96
+ private readonly _paste?;
97
+ constructor(_clipboard?: Clipboard, _paste?: ((context: IClipboardContext, plainText: boolean, nativeData?: NativeClipboardData) => Promise<void>) | undefined);
98
+ writeText(text: string): Promise<void>;
88
99
  connect(context: IClipboardContext): IDisposable;
89
100
  }
90
101
 
91
- export declare type BlockAstNode = HeadingAstNode | ParagraphAstNode | CodeBlockAstNode | MathBlockAstNode | ThematicBreakAstNode | BlockQuoteAstNode | ListAstNode | TableAstNode;
102
+ export declare type BlockAstNode = HeadingAstNode | ParagraphAstNode | EmptyBlockAstNode | FrontMatterAstNode | CodeBlockAstNode | MathBlockAstNode | ThematicBreakAstNode | VideoAstNode | BlockQuoteAstNode | ListAstNode | TableAstNode | UnhandledBlockAstNode;
92
103
 
93
104
  /**
94
105
  * A block-level node. Every block may carry a {@link leadingTrivia} glue — the
@@ -109,7 +120,7 @@ declare abstract class BlockAstNodeBase extends AstNode {
109
120
  /**
110
121
  * One block's place in the rendered document.
111
122
  *
112
- * `height` is in CSS pixels. It is either a real DOM measurement
123
+ * Geometry is in editor-local CSS pixels. `height` is either a real DOM measurement
113
124
  * (`isMeasured: true`) or an estimate produced when the block is not
114
125
  * currently mounted (`isMeasured: false`). Estimates exist so virtual
115
126
  * rendering can size the scroll container without mounting every block.
@@ -124,6 +135,13 @@ export declare interface BlockMeasurement {
124
135
  readonly block: BlockAstNode;
125
136
  readonly absoluteStart: number;
126
137
  readonly height: number;
138
+ /** Local border box when mounted and measured. */
139
+ readonly rect: Rect2D | undefined;
140
+ /** Local horizontal padding-box clip when this block scrolls horizontally. */
141
+ readonly viewportClip: {
142
+ readonly left: number;
143
+ readonly right: number;
144
+ } | undefined;
127
145
  readonly isMeasured: boolean;
128
146
  readonly visualLineMap: VisualLineMap | undefined;
129
147
  readonly viewNode: ViewNode | undefined;
@@ -143,11 +161,22 @@ export declare class BlockQuoteAstNode extends BlockAstNodeBase {
143
161
  declare class BlockQuoteViewData {
144
162
  readonly ast: BlockQuoteAstNode;
145
163
  readonly content: readonly AnyViewData[];
164
+ /** False while a pending paragraph replaces the final marker-only line. */
165
+ readonly showFinalMarkerOnlyLine: boolean;
146
166
  readonly kind = "blockQuote";
147
- constructor(ast: BlockQuoteAstNode, content: readonly AnyViewData[]);
167
+ constructor(ast: BlockQuoteAstNode, content: readonly AnyViewData[],
168
+ /** False while a pending paragraph replaces the final marker-only line. */
169
+ showFinalMarkerOnlyLine: boolean);
148
170
  }
149
171
 
150
- declare type BlockViewData = HeadingViewData | ParagraphViewData | CodeBlockViewData | MathBlockViewData | ThematicBreakViewData | BlockQuoteViewData | ListViewData | TableViewData;
172
+ /**
173
+ * All blocks whose source range intersects `[start, endExclusive]`. A
174
+ * collapsed range (start === endExclusive) matches the block containing
175
+ * that offset (with the same boundary rule as {@link findBlockAtOffset}).
176
+ */
177
+ export declare function blocksIntersecting(doc: DocumentAstNode, start: SourceOffset, endExclusive: SourceOffset): BlockAstNode[];
178
+
179
+ declare type BlockViewData = HeadingViewData | ParagraphViewData | EmptyBlockViewData | FrontMatterViewData | CodeBlockViewData | MathBlockViewData | ThematicBreakViewData | VideoViewData | BlockQuoteViewData | ListViewData | TableViewData | UnhandledBlockViewData;
151
180
 
152
181
  /**
153
182
  * Base view node for everything the editor renders, generic over the
@@ -168,6 +197,17 @@ export declare class BlockViewNode<T extends AnyViewData = AnyViewData> extends
168
197
  constructor(data: T, dom: globalThis.Node, children: readonly ViewNode[]);
169
198
  get block(): BlockAstNode;
170
199
  get element(): HTMLElement;
200
+ /**
201
+ * The horizontal scroll viewport for selection/caret clipping
202
+ * ({@link blockViewportClip}). For most blocks the scroller *is*
203
+ * {@link element} — a code / math / unhandled block's `element` is the very
204
+ * `overflow-x: auto` box that scrolls. A table is the exception: its
205
+ * `element` stays the inner `<table>` (so the active/markers classes and
206
+ * `.md-table` theme styling are unaffected), but the box that actually
207
+ * scrolls is the wrapping `.md-table-wrapper`, so {@link TableViewNode}
208
+ * overrides this to return that wrapper.
209
+ */
210
+ get scrollElement(): HTMLElement;
171
211
  /**
172
212
  * Whether this already-built node can stand in for `data` unchanged. The
173
213
  * builder preserves view-data identity for any subtree whose ast and
@@ -175,7 +215,7 @@ export declare class BlockViewNode<T extends AnyViewData = AnyViewData> extends
175
215
  * single identity check captures "nothing in my subtree changed" — and its
176
216
  * whole subtree, and any session it owns, are kept as-is.
177
217
  */
178
- canReuse(data: AnyViewData): boolean;
218
+ canReuse(data: AnyViewData, _options: BlockViewOptions | undefined): boolean;
179
219
  /**
180
220
  * Called by the view after this block is mounted and measured, with the
181
221
  * block's rendered height in px. The default is a no-op; subclasses whose
@@ -186,14 +226,25 @@ export declare class BlockViewNode<T extends AnyViewData = AnyViewData> extends
186
226
  }
187
227
 
188
228
  export declare interface BlockViewOptions {
229
+ /** Writes explicit copy actions through the host clipboard; defaults to the browser API. */
230
+ readonly writeClipboardText?: (text: string) => Promise<void>;
231
+ readonly preserveSourceWhitespace?: boolean;
189
232
  readonly renderCustomCodeBlock?: (language: string, content: string) => HTMLElement | undefined;
190
233
  readonly onToggleCheckbox?: (item: ListItemAstNode, newChecked: boolean) => void;
234
+ /** Temporarily yields the host editor's text input while a nested control owns focus. */
235
+ readonly suspendEditContextWhileFocused?: (element: HTMLElement) => IDisposable;
236
+ /**
237
+ * Supplies live, declarative metadata for recognized links. The editor owns
238
+ * the markup and styling; providers own lookup, caching, and updates.
239
+ */
240
+ readonly linkPresentationProvider?: ILinkPresentationProvider;
191
241
  /**
192
242
  * Opens a link's URL. Called when the user activates a link: a plain click
193
243
  * while the link's block is inactive (rendered), or a Ctrl/Cmd+click while it
194
- * is active (source shown). Defaults to `window.open(url, '_blank')`.
244
+ * is active (source shown). Return `false` to use the anchor's native
245
+ * navigation behavior.
195
246
  */
196
- readonly onOpenLink?: (url: string, event: MouseEvent) => void;
247
+ readonly onOpenLink?: (url: string, event: MouseEvent) => false | void;
197
248
  /**
198
249
  * Colours fenced code blocks. When set, a code block's content is rendered
199
250
  * as a sequence of token spans instead of one plain text node. This is the
@@ -213,16 +264,47 @@ export declare interface BlockViewOptions {
213
264
  * `katexEditableIdentifiers.ts`).
214
265
  */
215
266
  readonly renderMath?: (request: MathRenderRequest) => MathRendering | undefined;
267
+ /**
268
+ * Pluggable factory for an in-place, interactive editor that replaces the
269
+ * *rendered* (inactive) form of a fenced code block — see
270
+ * {@link IEmbeddedCodeEditor}. When it returns an editor for the block's
271
+ * language, that editor's element is mounted instead of the highlighted
272
+ * code, and content flows both ways as string edits. Returning `undefined`
273
+ * falls back to the default rendering. EXPERIMENTAL.
274
+ */
275
+ readonly embeddedCodeEditorFactory?: IEmbeddedCodeEditorFactory;
276
+ /** Current read-only state forwarded to embedded code editors. */
277
+ readonly embeddedCodeEditorReadOnly?: boolean;
278
+ /** Identity used to invalidate previously created embedded editors. */
279
+ readonly embeddedCodeEditorFactoryVersion?: unknown;
280
+ /**
281
+ * Called when an {@link IEmbeddedCodeEditor} edits its content. `contentEdit`
282
+ * is in the block's *content* coordinates; the host translates it to a
283
+ * document edit (via {@link CodeBlockAstNode.codeOffset} and the block's
284
+ * offset) and applies it to the model.
285
+ */
286
+ readonly onEmbeddedCodeEditorEdit?: (block: CodeBlockAstNode, contentEdit: StringEdit) => void;
216
287
  }
217
288
 
218
289
  export declare class CodeBlockAstNode extends BlockAstNodeBase {
290
+ /** First token of the fenced code block info string, used for syntax highlighting. */
219
291
  readonly language: string;
292
+ /** Complete fenced code block info string, including metadata after the language token. */
293
+ readonly infoString: string;
220
294
  readonly content: readonly (MarkerAstNode | GlueAstNode)[];
221
295
  readonly leadingTrivia?: GlueAstNode | undefined;
296
+ /** Logical code tokens, excluding Markdown container prefixes and structural indentation. */
297
+ readonly codeText?: string | undefined;
222
298
  readonly kind = "codeBlock";
223
299
  private _previous?;
224
300
  private _contentEdit?;
225
- constructor(language: string, content: readonly (MarkerAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
301
+ constructor(
302
+ /** First token of the fenced code block info string, used for syntax highlighting. */
303
+ language: string,
304
+ /** Complete fenced code block info string, including metadata after the language token. */
305
+ infoString: string, content: readonly (MarkerAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined,
306
+ /** Logical code tokens, excluding Markdown container prefixes and structural indentation. */
307
+ codeText?: string | undefined);
226
308
  get children(): readonly AstNode[];
227
309
  get openFence(): MarkerAstNode | undefined;
228
310
  get closeFence(): MarkerAstNode | undefined;
@@ -277,6 +359,8 @@ declare class CodeBlockViewData {
277
359
  * only, so a nested block currently builds a fresh session on each rebuild.
278
360
  */
279
361
  export declare class CodeBlockViewNode extends BlockViewNode<CodeBlockViewData> {
362
+ private readonly _contentElement;
363
+ private _copyAction;
280
364
  private _session;
281
365
  /**
282
366
  * Subscription that re-tokenises the rendered `<code>` in place whenever the
@@ -288,10 +372,28 @@ export declare class CodeBlockViewNode extends BlockViewNode<CodeBlockViewData>
288
372
  * its predecessor's subscription explicitly.
289
373
  */
290
374
  private _snapshotSub;
375
+ /**
376
+ * An in-place interactive editor (e.g. an iframe) mounted instead of the
377
+ * rendered code. Like {@link _session} it is adopted from `previous` across
378
+ * rebuilds so the underlying editor keeps its state, and must be disposed
379
+ * manually (a node reused as `previous` is never {@link dispose}d).
380
+ */
381
+ private _embeddedEditor;
382
+ private readonly _embeddedEditorFactoryVersion;
383
+ private readonly _embeddedEditorReadOnly;
384
+ canReuse(data: AnyViewData, options: BlockViewOptions | undefined): boolean;
291
385
  constructor(data: CodeBlockViewData, options: BlockViewOptions | undefined, previous: ViewNode | undefined);
386
+ get element(): HTMLElement;
292
387
  dispose(): void;
293
388
  }
294
389
 
390
+ /**
391
+ * Canonical editor command catalog. Standalone keyboard handling and host
392
+ * integrations derive their command registration and default keybindings from
393
+ * this list.
394
+ */
395
+ export declare const commands: readonly EditorCommandDefinition[];
396
+
295
397
  /** A persistent comment anchored to a source range. */
296
398
  declare interface Comment_2 {
297
399
  readonly id: string;
@@ -307,16 +409,10 @@ declare interface Comment_2 {
307
409
  export { Comment_2 as Comment }
308
410
 
309
411
  /**
310
- * A self-contained comment input box — a rounded panel with an auto-growing
311
- * textarea and a send button, styled after the gdocs/Word "add a comment"
312
- * affordance.
313
- *
314
- * This widget is *positioning-agnostic*: it only owns its own DOM and state.
315
- * A host (the comment-mode controller, or a fixture) mounts {@link element}
316
- * wherever it likes and is responsible for placing it relative to a selection.
412
+ * The compact editing state for a markdown comment.
317
413
  *
318
- * State is observable-driven (no framework): {@link value} reflects the live
319
- * textarea content; submit/cancel are reported through the option callbacks.
414
+ * The widget owns its DOM and draft state but not its position. The comment-mode
415
+ * controller mounts it next to the active selection.
320
416
  */
321
417
  export declare class CommentInputWidget extends Disposable {
322
418
  private readonly _options?;
@@ -327,25 +423,24 @@ export declare class CommentInputWidget extends Disposable {
327
423
  private readonly _value;
328
424
  /** Live, untrimmed textarea content. */
329
425
  get value(): IObservable<string>;
330
- /** The raw textarea, exposed so a host can move focus into it (e.g. on Tab). */
426
+ /** The raw textarea, exposed so a host can move focus into it. */
331
427
  get inputElement(): HTMLTextAreaElement;
332
428
  constructor(_options?: CommentInputWidgetOptions | undefined);
333
- /** Move focus into the textarea (caret at the end). */
334
429
  focus(): void;
335
- /** Replace the textarea content. */
336
430
  setText(text: string): void;
337
- /** Clear the textarea. */
338
431
  clear(): void;
339
432
  private _submit;
340
433
  private _autoSize;
341
434
  }
342
435
 
343
436
  export declare interface CommentInputWidgetOptions {
344
- /** Placeholder shown while the textarea is empty. Defaults to "Add Comment". */
437
+ /** Placeholder shown while the textarea is empty. Defaults to "Add comment". */
345
438
  readonly placeholder?: string;
439
+ /** Called after the textarea changes size. */
440
+ readonly onDidChangeSize?: () => void;
346
441
  /**
347
- * Called when the user submits a non-empty comment (Enter or the send
348
- * button). The text is trimmed; never called with an empty string.
442
+ * Called when the user submits a non-empty comment (Enter or the add button).
443
+ * The text is trimmed; never called with an empty string.
349
444
  */
350
445
  readonly onSubmit?: (text: string) => void;
351
446
  /** Called when the user dismisses the input (Escape). */
@@ -353,7 +448,7 @@ export declare interface CommentInputWidgetOptions {
353
448
  }
354
449
 
355
450
  /**
356
- * Comment mode — a gdocs/Word-style "add a comment" affordance layered on top of
451
+ * Comment mode — a compact "add a comment" affordance layered on top of
357
452
  * the editor *without modifying it*. It reads the editor's public observables
358
453
  * ({@link EditorModel.readonlyMode}, {@link EditorModel.selection}) and the
359
454
  * exposed {@link EditorView.caretRect} geometry, and mounts a
@@ -361,37 +456,38 @@ export declare interface CommentInputWidgetOptions {
361
456
  *
362
457
  * Behaviour:
363
458
  * - Only active in read-only mode (the "review" view).
364
- * - When the selection is non-empty, the input box appears next to the caret
365
- * (the selection's active end) but does NOT take focus, so keyboard selection
366
- * keeps working. Press Tab to move focus into the box, then type.
459
+ * - When a user-created selection is non-empty, the input box appears next to
460
+ * the caret (the selection's active end) but does NOT take focus, so keyboard
461
+ * selection keeps working. Programmatic selections such as find matches do
462
+ * not summon it. Press Tab to move focus into the box, then type.
367
463
  * - The box appears on mouse-up, not mid-drag, so it doesn't flicker/jump
368
464
  * while a selection is being dragged out (keyboard selection shows at once).
369
465
  * - While the box has focus or holds a draft it is frozen in place (selection
370
466
  * changes, drags and clicks no longer move it). It is dismissed by Escape,
371
467
  * by submitting, or by blurring an empty box.
372
- * - The editor's painted caret is hidden only while the box has focus (the
373
- * blinking caret then belongs to the comment input); it stays visible while
374
- * the box is merely shown, so keyboard selection remains visible.
468
+ * - The editor's logical caret geometry remains available for anchoring in
469
+ * read-only mode even though the painted caret is hidden. While the box has
470
+ * focus, `.md-comment-active` also suppresses the painted caret in any mode.
375
471
  */
376
472
  export declare class CommentModeController extends Disposable {
377
473
  private readonly _model;
378
474
  private readonly _view;
379
475
  private readonly _options?;
476
+ private static _isCommentableSelectionSource;
380
477
  private readonly _widget;
381
478
  private readonly _gap;
382
479
  private _visible;
480
+ private _anchorX;
383
481
  private _pinnedRange;
384
482
  /**
385
- * The range a comment was just submitted for. The box stays hidden for it
386
- * until the selection changes, so submitting doesn't immediately re-summon an
387
- * empty box on the still-selected text.
483
+ * Keep a dismissed comment hidden across layout updates until the selection
484
+ * changes, whether the user submitted it or pressed Escape.
388
485
  */
389
- private _submittedRange;
390
- /** True while a mouse button is held over the editor (a selection drag in progress). */
391
- private readonly _mouseDown;
486
+ private _dismissedRange;
392
487
  constructor(_model: EditorModel, _view: EditorView, _options?: CommentModeControllerOptions | undefined);
393
488
  private _update;
394
489
  private _show;
490
+ private _layoutHorizontally;
395
491
  /** Force-hide and clear the box (used by Escape and submit). */
396
492
  private _hide;
397
493
  /**
@@ -419,20 +515,10 @@ export declare interface CommentModeControllerOptions {
419
515
  readonly gap?: number;
420
516
  }
421
517
 
422
- /** Human-readable labels (for pickers / dropdowns). */
423
- export declare const COMMENTS_DESIGN_LABELS: Record<CommentsDesign, string>;
424
-
425
- /** design id → presenter factory over a shared CommentsModel + EditorView. */
426
- export declare const COMMENTS_DESIGNS: Record<CommentsDesign, CommentsPresenterFactory>;
427
-
428
- /** The available comment rendering designs. */
429
- export declare type CommentsDesign = 'connected' | 'vscode' | 'vscode-v2';
430
-
431
518
  /**
432
- * Seedable store of {@link Comment}s for the comment-mode contribution. Owns the
433
- * comment list and the shared hover state; it has no opinion on rendering or
434
- * persistence — a host seeds it via {@link set}/{@link add} and observes
435
- * {@link comments}.
519
+ * Seedable store of {@link Comment}s for the comment-mode contribution. It has
520
+ * no opinion on rendering or persistence — a host seeds it via
521
+ * {@link set}/{@link add} and observes {@link comments}.
436
522
  */
437
523
  export declare class CommentsModel {
438
524
  private readonly _comments;
@@ -440,11 +526,6 @@ export declare class CommentsModel {
440
526
  private _sequence;
441
527
  /** The current comments, in insertion order. */
442
528
  get comments(): IObservable<readonly Comment_2[]>;
443
- /**
444
- * The comment currently hovered (by its card or its highlight), or
445
- * `undefined`. Shared so the card and the highlight can react together.
446
- */
447
- readonly hoveredId: ISettableObservable<string | undefined>;
448
529
  /** Replace the whole comment set. */
449
530
  set(comments: readonly Comment_2[]): void;
450
531
  /**
@@ -463,57 +544,54 @@ export declare class CommentsModel {
463
544
  remove(id: string): void;
464
545
  }
465
546
 
466
- /** Optional, design-specific context a presenter may use (ignored by others). */
467
- export declare interface CommentsPresenterContext {
468
- /** Light/dark hint for the token-wrapped VS Code widget designs. */
469
- readonly theme?: 'light' | 'dark';
470
- /**
471
- * Resolves a source offset to a 1-based line number, for designs that show
472
- * line info (the VS Code V1 card). Optional because the model itself carries
473
- * no text; the host (which owns the source) supplies it.
474
- */
475
- readonly resolveLine?: (offset: number) => number;
476
- }
477
-
478
- /** Builds a presenter for a given model + editor view. */
479
- export declare type CommentsPresenterFactory = (model: CommentsModel, view: EditorView, context?: CommentsPresenterContext) => ICommentsPresenter;
480
-
481
547
  /** A comment the user submitted, with the source range it was anchored to. */
482
548
  export declare interface CommentSubmission {
483
549
  readonly text: string;
484
550
  readonly range: OffsetRange;
485
551
  }
486
552
 
487
- /**
488
- * Renders persistent comments as a gdocs-style side rail: each comment's range
489
- * is highlighted (reusing the editor's selection geometry via
490
- * {@link EditorView.rangeRects}), a leader line curves from the bottom of that
491
- * highlight to a card stacked in the right rail, and cards never overlap.
492
- *
493
- * Everything is mounted into {@link EditorView.overlayContainer} so it shares
494
- * the selection/caret coordinate space and scrolls with the document. When the
495
- * editor's natural right margin is too narrow for the rail, the view reserves
496
- * proportional space by padding the editor on the right — but only while there
497
- * are comments.
498
- */
553
+ /** Displays posted comments beside their source ranges. */
499
554
  export declare class CommentsView extends Disposable {
500
555
  private readonly _model;
501
556
  private readonly _view;
502
557
  private readonly _layer;
503
558
  private readonly _entries;
559
+ private _order;
560
+ private _pendingRevealCommentId;
504
561
  constructor(_model: CommentsModel, _view: EditorView);
505
- private _createLayer;
506
- private _update;
507
- /** Create/update/remove per-comment DOM to match `comments`. */
562
+ revealComment(id: string): void;
508
563
  private _reconcile;
509
- private _createEntry;
510
- private _fillCard;
511
- private _disposeEntry;
512
- /** Position highlights, cards (stacked) and leader lines. */
513
- private _layout;
514
- private _applyHover;
564
+ private _relayout;
565
+ private _revealPendingComment;
566
+ }
567
+
568
+ /** Compact posted state for a markdown comment. */
569
+ export declare class CommentWidget {
570
+ private readonly _domNode;
571
+ private readonly _disposables;
572
+ get element(): HTMLElement;
573
+ constructor(options: CommentWidgetOptions);
574
+ dispose(): void;
575
+ }
576
+
577
+ export declare interface CommentWidgetOptions {
578
+ /** The posted comment body. */
579
+ readonly body: string;
580
+ /** If provided, shows a delete action and invokes it when activated. */
581
+ readonly onDelete?: () => void;
515
582
  }
516
583
 
584
+ /** The lossless source slices of a complete block HTML comment. */
585
+ declare interface CompleteHtmlCommentSource extends HtmlCommentSourceBase {
586
+ readonly kind: 'complete';
587
+ readonly closing: '-->';
588
+ readonly trailingWhitespace: string;
589
+ }
590
+
591
+ export declare const copyLinesDown: EditCommand;
592
+
593
+ export declare const copyLinesUp: EditCommand;
594
+
517
595
  /**
518
596
  * A {@link MonacoSyntaxHighlighter} preloaded with a handful of common Monarch
519
597
  * grammars (plus the usual short aliases). Unknown languages fall back to an
@@ -524,13 +602,17 @@ export declare class CommentsView extends Disposable {
524
602
  */
525
603
  export declare function createDefaultMonacoSyntaxHighlighter(monaco: IMonarchApi, grammars: IDefaultMonarchGrammars): MonacoSyntaxHighlighter;
526
604
 
527
- export declare type CursorCommand = (ctx: CursorCommandContext) => SourceOffset;
605
+ export declare type CursorCommand = (ctx: CursorCommandContext) => CursorPosition;
528
606
 
529
607
  export declare interface CursorCommandContext {
530
608
  readonly text: string;
531
609
  readonly selection: Selection_2;
532
610
  readonly document: DocumentAstNode;
533
611
  readonly activeBlock: BlockAstNode | undefined;
612
+ readonly markerVisibleBlocks: ReadonlySet<BlockAstNode>;
613
+ readonly markupSelectionRange?: OffsetRange;
614
+ readonly wordNavigationConfig: WordNavigationConfig;
615
+ readonly cursorPosition: CursorPosition;
534
616
  }
535
617
 
536
618
  export declare const cursorDocumentEnd: CursorCommand;
@@ -539,6 +621,8 @@ export declare const cursorDocumentStart: CursorCommand;
539
621
 
540
622
  export declare const cursorDown: VisualCursorCommand;
541
623
 
624
+ export declare type CursorKeyboardAction = 'left' | 'right' | 'up' | 'down' | 'wordLeft' | 'wordRight' | 'visualLineStart' | 'visualLineEnd' | 'logicalLineStart' | 'logicalLineEnd' | 'documentStart' | 'documentEnd';
625
+
542
626
  export declare const cursorLeft: CursorCommand;
543
627
 
544
628
  export declare const cursorLineEnd: CursorCommand;
@@ -548,12 +632,23 @@ export declare const cursorLineStart: CursorCommand;
548
632
  export declare const cursorMoveLeft: CursorCommand;
549
633
 
550
634
  export declare interface CursorMoveResult {
551
- readonly offset: SourceOffset;
635
+ readonly position: CursorPosition;
552
636
  readonly desiredColumn: number | undefined;
553
637
  }
554
638
 
555
639
  export declare const cursorMoveRight: CursorCommand;
556
640
 
641
+ /** The cursor's position in either source text or a source-less visual line. */
642
+ export declare type CursorPosition = SourceCursorPosition | {
643
+ readonly kind: 'virtual';
644
+ readonly line: VirtualCursorLine;
645
+ };
646
+
647
+ export declare namespace CursorPosition {
648
+ export function source(offset: SourceOffset, affinity?: SourceCursorPosition['affinity']): SourceCursorPosition;
649
+ export function virtual(line: VirtualCursorLine): CursorPosition;
650
+ }
651
+
557
652
  export declare const cursorRight: CursorCommand;
558
653
 
559
654
  export declare const cursorUp: VisualCursorCommand;
@@ -562,43 +657,57 @@ export declare const cursorUp: VisualCursorCommand;
562
657
  * Owns the blinking cursor DOM element.
563
658
  *
564
659
  * The rendering pipeline is a single `derived` whose compute callback
565
- * asks the {@link VisualLineMap} for the caret rect at the current
566
- * offset, writes it to {@link element}, and returns a
660
+ * asks the {@link VisualLineMap} for the caret rect at the current source or
661
+ * virtual position, writes it to {@link element}, and returns a
567
662
  * {@link CursorViewRendering} value as proof. An autorun keeps the
568
663
  * derived subscribed.
569
664
  */
570
665
  export declare class CursorView extends Disposable {
571
- private readonly _parent;
572
666
  readonly element: HTMLElement;
573
667
  readonly rendering: IObservable<CursorViewRendering>;
574
- constructor(_parent: HTMLElement, options: CursorViewOptions);
668
+ constructor(options: CursorViewOptions);
575
669
  }
576
670
 
577
671
  export declare interface CursorViewOptions {
578
- readonly offset: IObservable<SourceOffset | undefined>;
672
+ readonly position: IObservable<CursorPosition | undefined>;
579
673
  readonly visualLineMap: IObservable<VisualLineMap>;
580
674
  /**
581
- * When set, the caret is drawn over the transient empty paragraph instead
582
- * of at {@link offset} — its rect (in client coordinates) comes straight
583
- * from that synthetic element's geometry, since it has no visual-line-map
584
- * entry. Takes priority over the normal offset-based placement.
675
+ * The mounted blocks, used to hide the caret when it sits at an offset that
676
+ * has been scrolled out of its (horizontally scrolling) block's viewport —
677
+ * matching how the selection is clipped there.
585
678
  */
586
- readonly pendingCaretRect?: IObservable<Rect2D | undefined>;
679
+ readonly blocks?: IObservable<readonly SelectionBlock[]>;
587
680
  }
588
681
 
589
682
  export declare class CursorViewRendering {
590
- readonly offset: SourceOffset;
683
+ readonly position: CursorPosition;
591
684
  readonly visible: boolean;
592
685
  readonly rect: Rect2D;
593
- constructor(offset: SourceOffset, visible: boolean, rect: Rect2D);
686
+ constructor(position: CursorPosition, visible: boolean, rect: Rect2D);
594
687
  }
595
688
 
689
+ export declare const cursorVisualLineEnd: VisualCursorCommand;
690
+
691
+ export declare const cursorVisualLineStart: VisualCursorCommand;
692
+
596
693
  export declare const cursorWordLeft: CursorCommand;
597
694
 
598
695
  export declare const cursorWordRight: CursorCommand;
599
696
 
697
+ export declare const DEFAULT_INDENTATION_CONFIG: IndentationConfig;
698
+
699
+ export declare const DEFAULT_WORD_NAVIGATION_CONFIG: WordNavigationConfig;
700
+
701
+ export declare const DEFAULT_WORD_SEPARATORS = "`~!@#$%^&*()-=+[{]}\\|;:'\",.<>/?";
702
+
600
703
  export declare const deleteLeft: EditCommand;
601
704
 
705
+ export declare const deleteLineLeft: EditCommand;
706
+
707
+ export declare const deleteLineRight: EditCommand;
708
+
709
+ export declare const deleteLines: EditCommand;
710
+
602
711
  export declare const deleteRight: EditCommand;
603
712
 
604
713
  export declare const deleteWordLeft: EditCommand;
@@ -768,7 +877,7 @@ declare class DocumentViewData {
768
877
  export declare class DocumentViewNode extends ViewNode {
769
878
  readonly blocks: readonly DocumentBlock[];
770
879
  /** The transient empty-paragraph element, when one is armed. */
771
- readonly pendingElement?: HTMLElement | undefined;
880
+ readonly pendingParagraph?: PendingParagraphViewNode | undefined;
772
881
  static create(viewData: DocumentViewData, options: BlockViewOptions | undefined, previous: DocumentViewNode | undefined): DocumentViewNode;
773
882
  private constructor();
774
883
  /** The stable content element this document mounts its children into. */
@@ -790,6 +899,26 @@ export declare type EditCommand = (ctx: CursorCommandContext) => {
790
899
  readonly selection: Selection_2;
791
900
  } | undefined;
792
901
 
902
+ export declare type EditKeyboardAction = 'deleteLeft' | 'deleteRight' | 'deleteWordLeft' | 'deleteWordRight' | 'deleteLineLeft' | 'deleteLineRight' | 'copyLinesUp' | 'copyLinesDown' | 'moveLinesUp' | 'moveLinesDown' | 'deleteLines' | 'joinLines';
903
+
904
+ export declare interface EditorCommandDefinition {
905
+ readonly id: `markdown.editor.${string}`;
906
+ readonly title: string;
907
+ readonly action: EditorKeyboardAction;
908
+ readonly keybindings: readonly EditorCommandKeybinding[];
909
+ /**
910
+ * Local commands must execute synchronously in the webview instead of being
911
+ * forwarded through the VS Code keybinding service.
912
+ */
913
+ readonly routing?: 'host' | 'local';
914
+ }
915
+
916
+ export declare interface EditorCommandKeybinding {
917
+ readonly key: string;
918
+ readonly modifiers?: KeyboardModifiers;
919
+ readonly platforms?: readonly KeyboardPlatform[];
920
+ }
921
+
793
922
  /**
794
923
  * Translates raw browser input (mouse, keyboard, EditContext) into model
795
924
  * mutations. Knows about DOM event types but never reads/writes the DOM
@@ -798,19 +927,46 @@ export declare type EditCommand = (ctx: CursorCommandContext) => {
798
927
  *
799
928
  * Owns the only non-derivable controller state:
800
929
  * - `_desiredColumn` — sticky column for up/down navigation
930
+ * - `_clickCount` / `_lastPointerDown` — multi-click detection for pointer
931
+ * input, since `pointerdown` events (unlike `mousedown`) don't populate
932
+ * `detail` with a click count.
801
933
  */
802
934
  export declare class EditorController extends Disposable {
803
935
  private readonly _model;
804
936
  private readonly _view;
937
+ readonly findController: FindController | undefined;
805
938
  private _desiredColumn;
939
+ private readonly _keyboardPlatform;
940
+ private readonly _keyboardProfile;
941
+ private readonly _forwardedKeyboardProfile;
942
+ private readonly _historyStrategy;
943
+ private readonly _indentation;
944
+ private readonly _tabFocusStatus;
945
+ private _tabMovesFocus;
946
+ /** Indentation copied by the most recent fenced-code Enter, while still untouched. */
947
+ private _generatedIndentation;
948
+ /** Running click count for the current multi-click sequence (1, 2, 3, …). */
949
+ private _clickCount;
950
+ /** Timestamp and position of the previous pointer-down, for multi-click detection. */
951
+ private _lastPointerDown;
806
952
  constructor(_model: EditorModel, _view: EditorView, options?: EditorControllerOptions);
807
953
  private readonly _handleTextUpdate;
808
- private readonly _handleMouseDown;
954
+ insertText(text: string, selectionOverride?: Selection_2): void;
955
+ private _insertText;
956
+ private _remainingGeneratedIndentation;
957
+ /** Handle typed, pasted, or command-generated text while a paragraph is pending. */
958
+ private _handlePendingInput;
959
+ private _deletePendingText;
960
+ private readonly _handlePointerDown;
809
961
  private _makeCursorContext;
810
962
  private _makeVisualCursorContext;
811
963
  private _executeCursorCommand;
812
964
  private _executeEditCommand;
965
+ private _runUndoableEdit;
813
966
  private _executeVisualCursorCommand;
967
+ private _cursorDown;
968
+ private _setUserSelection;
969
+ private _applyCursorPosition;
814
970
  /** Move the cursor down one visual line (Arrow Down). */
815
971
  cursorDown(extend?: boolean): void;
816
972
  /** Move the cursor up one visual line (Arrow Up). */
@@ -818,12 +974,34 @@ export declare class EditorController extends Disposable {
818
974
  private _selectedText;
819
975
  private readonly _updateModifierState;
820
976
  private readonly _clearModifierState;
977
+ /**
978
+ * Drop any native DOM selection over the rendered text.
979
+ *
980
+ * The editor paints selection from `model.selection`, so a browser
981
+ * selection there is always spurious: nothing reads it (copy/cut read the
982
+ * model, hit-testing uses the measured layout) and nothing clears it, so it
983
+ * lingers as a second highlight even after the caret moves away.
984
+ * {@link isCaretMotionKey} stops the common source synchronously; this is
985
+ * the backstop for the rest of the browser's editing commands, which are
986
+ * platform- and version-specific and cannot be enumerated (Shift+PageDown
987
+ * and macOS Shift+Ctrl+B both reach one today).
988
+ *
989
+ * Scoped twice so it only ever discards selections the editor owns: the
990
+ * range must touch the rendered text (overlays such as comment widgets sit
991
+ * beside it and stay selectable), and input focus must still be inside this
992
+ * editor (so a host find-in-page, which selects while its own input is
993
+ * focused, is left alone).
994
+ */
995
+ private readonly _discardNativeSelection;
821
996
  private readonly _handleKeyDown;
997
+ executeCommand(command: EditorCommandDefinition): void;
998
+ private _executeKeyboardAction;
822
999
  /**
823
1000
  * Context-aware Enter: splits / line-breaks via {@link insertSmartEnter}, or
824
1001
  * arms a transient empty paragraph when at the end of a paragraph.
825
1002
  */
826
1003
  private _smartEnter;
1004
+ private _registerTabFocusAccessibility;
827
1005
  }
828
1006
 
829
1007
  /** Options for an {@link EditorController}. */
@@ -834,10 +1012,81 @@ export declare interface EditorControllerOptions {
834
1012
  * strategy (e.g. `AsyncClipboardStrategy`) in hosts that swallow them.
835
1013
  */
836
1014
  readonly clipboardStrategy?: IClipboardStrategy;
1015
+ /**
1016
+ * Where undo and redo are executed: `LocalHistoryStrategy` for a
1017
+ * self-contained editor, or a strategy that forwards to the host's own
1018
+ * document history. Left unset, the chords are passed on to the host.
1019
+ */
1020
+ readonly historyStrategy?: IHistoryStrategy;
1021
+ readonly keyboardPlatform?: KeyboardPlatform;
1022
+ readonly keyboardProfile?: KeyboardProfile;
1023
+ /**
1024
+ * Bindings owned by the host. Matching events have their browser default
1025
+ * suppressed but continue propagating so the host keybinding service sees them.
1026
+ */
1027
+ readonly forwardedKeyboardProfile?: KeyboardProfile;
1028
+ /** Tab-stop settings used outside semantic list indentation. */
1029
+ readonly indentation?: IndentationConfig;
1030
+ readonly find?: false;
837
1031
  }
838
1032
 
1033
+ /**
1034
+ * The editor overlay's local CSS-pixel coordinate space.
1035
+ *
1036
+ * Browser geometry and pointer APIs expose viewport client coordinates. This
1037
+ * boundary converts them immediately into the coordinate system shared by the
1038
+ * editor content and its overlays. Range rectangles are axis-aligned, so the
1039
+ * current implementation deliberately supports positive axis-aligned scale and
1040
+ * translation only.
1041
+ */
1042
+ export declare class EditorCoordinateSpace {
1043
+ private readonly _getLocalToClientMatrix;
1044
+ static forSvgOverlay(overlay: SVGSVGElement): EditorCoordinateSpace;
1045
+ private constructor();
1046
+ capture(): EditorCoordinateTransform;
1047
+ }
1048
+
1049
+ /** A stable coordinate conversion captured for one measurement operation. */
1050
+ export declare class EditorCoordinateTransform {
1051
+ private readonly _localToClient;
1052
+ private readonly _clientToLocal;
1053
+ constructor(_localToClient: DOMMatrix);
1054
+ toLocalPoint(point: Pick<Point2D, 'x' | 'y'>): Point2D;
1055
+ toClientPoint(point: Pick<Point2D, 'x' | 'y'>): Point2D;
1056
+ toLocalRect(rect: Pick<DOMRectReadOnly, 'left' | 'top' | 'width' | 'height'>): Rect2D;
1057
+ toClientRect(rect: Pick<Rect2D, 'left' | 'top' | 'width' | 'height'>): Rect2D;
1058
+ private _convertRect;
1059
+ }
1060
+
1061
+ export declare type EditorKeyboardAction = {
1062
+ readonly kind: 'cursor';
1063
+ readonly command: CursorKeyboardAction;
1064
+ readonly extend: boolean;
1065
+ } | {
1066
+ readonly kind: 'edit';
1067
+ readonly command: EditKeyboardAction;
1068
+ } | {
1069
+ readonly kind: 'history';
1070
+ readonly command: HistoryKeyboardAction;
1071
+ } | {
1072
+ readonly kind: 'tab';
1073
+ readonly command: TabKeyboardAction;
1074
+ } | {
1075
+ readonly kind: 'toggleTabFocus';
1076
+ } | {
1077
+ readonly kind: 'toggleReadonly';
1078
+ } | {
1079
+ readonly kind: 'selectAll';
1080
+ } | {
1081
+ readonly kind: 'enter';
1082
+ readonly command: 'smartEnter' | 'insertParagraph' | 'insertHardLineBreak';
1083
+ };
1084
+
839
1085
  export declare class EditorModel {
840
1086
  private readonly _parser;
1087
+ private readonly _sourceEditListeners;
1088
+ private readonly _sourceTextIds;
1089
+ private _lastSourceTextId;
841
1090
  /**
842
1091
  * The most recent edit applied to {@link sourceText}, used by
843
1092
  * {@link document} to let the parser link incrementally edited code
@@ -846,21 +1095,18 @@ export declare class EditorModel {
846
1095
  */
847
1096
  private _pendingEdit;
848
1097
  readonly sourceText: ISettableObservable<StringValue, void>;
849
- /**
850
- * Read-only mode. When `true`, the editor never reveals a block's source
851
- * markers (markdown special characters like `**`, `#`, list bullets, code
852
- * fences, `$…$`) — every block stays in its clean rendered form regardless
853
- * of where the caret/selection is — and source-mutating edits are ignored.
854
- * Plain text selection still works everywhere (so the user can copy). The
855
- * default (`false`) is the normal editing mode where the active block
856
- * reveals its markers.
857
- */
1098
+ readonly wordNavigationConfig: ISettableObservable<WordNavigationConfig, void>;
1099
+ /** Disables text editing, independently of parsing, layout and markup visibility. */
858
1100
  readonly readonlyMode: ISettableObservable<boolean, void>;
1101
+ readonly presentation: ISettableObservable<EditorPresentation, void>;
1102
+ readonly renderMarkupText: ISettableObservable<RenderMarkupText, void>;
1103
+ readonly presentationPolicy: IObservableWithChange<PresentationPolicy, void>;
859
1104
  /**
860
1105
  * The current selection, or `undefined` when the editor has no caret
861
1106
  * (e.g. an inactive/unfocused rendering).
862
1107
  */
863
1108
  readonly selection: ISettableObservable<Selection_2 | undefined, void>;
1109
+ readonly selectionSource: ISettableObservable<SelectionSource, void>;
864
1110
  /**
865
1111
  * Whether a Ctrl/Cmd modifier is currently held. Set by the controller from
866
1112
  * live keyboard state; the view reads it to show the link-open affordance
@@ -868,6 +1114,14 @@ export declare class EditorModel {
868
1114
  * whose block is active.
869
1115
  */
870
1116
  readonly ctrlOrMetaDown: ISettableObservable<boolean, void>;
1117
+ /**
1118
+ * Whether a pointer-driven selection drag is currently in progress. Set by
1119
+ * the controller between the pointer-down that starts the drag and the
1120
+ * pointer-up/cancel that ends it. Contributions read it to defer UI that
1121
+ * would otherwise flicker mid-drag (e.g. the comment input box appears only
1122
+ * once the drag ends).
1123
+ */
1124
+ readonly isSelecting: ISettableObservable<boolean, void>;
871
1125
  /**
872
1126
  * Gutter markers (source-control style change indicators) painted in the
873
1127
  * left gutter. Each entry maps a source {@link OffsetRange} to a change kind
@@ -887,16 +1141,19 @@ export declare class EditorModel {
887
1141
  * The transient empty-paragraph editing state, or `undefined` when none is
888
1142
  * armed. See {@link PendingParagraph}. This is *not* document data — it is
889
1143
  * cleared by any source edit and lives only between the Enter that armed it
890
- * and the next keystroke.
1144
+ * and the next content-producing edit.
891
1145
  */
892
1146
  readonly pendingParagraph: ISettableObservable<PendingParagraph | undefined, void>;
1147
+ /** Switches between editing and locked mode and clears transient edit intent. */
1148
+ toggleReadonlyMode(): void;
893
1149
  readonly cursorOffset: IObservableWithChange<number | undefined, void>;
1150
+ readonly cursorPosition: IObservableWithChange<CursorPosition | undefined, void>;
894
1151
  /**
895
1152
  * The parsed document. Threads the previous document into the parser so
896
1153
  * unchanged blocks keep their object identity across reparses (see
897
1154
  * {@link MarkdownParser.parse}). Writing `previous` inside the compute is
898
- * a safe optimization: `derived` only recomputes when `sourceText`
899
- * changes, and the result is structurally identical to a full reparse.
1155
+ * safe: unchanged source reuses it directly, while changed source produces
1156
+ * a result structurally identical to a full reparse.
900
1157
  */
901
1158
  readonly document: IObservableWithChange<DocumentAstNode, void>;
902
1159
  /**
@@ -932,26 +1189,56 @@ export declare class EditorModel {
932
1189
  insertedRanges: OffsetRange[];
933
1190
  changedBlocks: Set<BlockAstNode>;
934
1191
  } | undefined, void>;
1192
+ readonly markerVisibleBlocks: IObservableWithChange<Set<BlockAstNode>, void>;
1193
+ getMarkupSelectionRange(selectionRange: OffsetRange | undefined, reader?: IReader): OffsetRange | undefined;
1194
+ onWillApplySourceEdit(listener: (event: SourceEditEvent) => void): IDisposable;
1195
+ /** Returns a stable per-object identity without retaining the source text. */
1196
+ getSourceTextId(sourceText: StringValue): number;
935
1197
  /**
936
1198
  * Arm a {@link PendingParagraph} at the given gap, minting a fresh synthetic
937
1199
  * AST node for it, and park the caret at the gap start. No source edit is
938
1200
  * applied — the blank line exists only in the view until it is materialized.
939
1201
  */
940
- armPendingParagraph(req: {
941
- anchorBlock: BlockAstNode;
942
- replaceRange: OffsetRange;
943
- atEof: boolean;
944
- }): void;
1202
+ armPendingParagraph(req: Omit<PendingParagraph, 'syntheticAst' | 'cursorLine' | 'text'>): void;
945
1203
  /** Discard the pending paragraph (if any) without touching the source. */
946
1204
  cancelPendingParagraph(): void;
1205
+ /**
1206
+ * Replace the source with an authoritative value from the host, mapping the
1207
+ * selection through the changed span and atomically discarding transient
1208
+ * state anchored to the previous parse.
1209
+ */
1210
+ replaceSourceText(text: StringValue): void;
1211
+ /** Replace the transient horizontal whitespace on the pending line. */
1212
+ setPendingParagraphText(text: string): void;
947
1213
  /**
948
1214
  * Turn the pending paragraph into real source: rewrite its gap so the typed
949
- * `text` becomes its own paragraph, separated from its neighbours by blank
950
- * lines, and place the caret after the inserted text.
1215
+ * text, including any transient indentation, is separated from its neighbours
1216
+ * by blank lines, and place the caret after it.
951
1217
  */
952
1218
  materializePendingParagraph(text: string): void;
953
- applyEdit(edit: StringEdit): void;
1219
+ /** Sets a rendered task checkbox state in either editing or read-only mode. */
1220
+ setTaskCheckboxChecked(item: ListItemAstNode, checked: boolean): void;
1221
+ applyEdit(edit: StringEdit, selection?: Selection_2): void;
954
1222
  applyEditForSelection(edit: StringEdit): void;
1223
+ private _applySourceEdit;
1224
+ private _identifySourceEdit;
1225
+ private _emitWillApplySourceEdit;
1226
+ }
1227
+
1228
+ export declare type EditorOverlayPosition = 'top-chrome' | 'below-selection' | 'above-decorations';
1229
+
1230
+ export declare type EditorPresentation = 'reading' | 'editing';
1231
+
1232
+ /** Text updates and browser attachment are separate so hosts can supply a local transport. */
1233
+ declare interface EditorTextInput {
1234
+ readonly context: EditorTextInputContext;
1235
+ readonly nativeContext: IObservable<EditContext | null>;
1236
+ }
1237
+
1238
+ declare interface EditorTextInputContext extends EventTarget {
1239
+ readonly text: string;
1240
+ updateText(start: number, end: number, text: string): void;
1241
+ updateSelection(start: number, end: number): void;
955
1242
  }
956
1243
 
957
1244
  /**
@@ -981,8 +1268,13 @@ export declare class EditorView extends Disposable {
981
1268
  private readonly _model;
982
1269
  private readonly _options?;
983
1270
  readonly element: HTMLElement;
984
- readonly editContext: EditContext;
1271
+ readonly editContext: EditorTextInputContext;
1272
+ private readonly _nativeEditContext;
985
1273
  readonly measuredLayout: MeasuredLayoutModel;
1274
+ readonly coordinateSpace: EditorCoordinateSpace;
1275
+ readonly forcedMarkerVisibleBlocks: ISettableObservable<ReadonlySet<BlockAstNode>, void>;
1276
+ readonly showReadonlyToggle: ISettableObservable<boolean, void>;
1277
+ readonly highlightActiveBlock: ISettableObservable<boolean, void>;
986
1278
  /**
987
1279
  * Inner container that holds the rendered document and the cursor/selection
988
1280
  * overlays. The outer {@link element} spans the full width; this container
@@ -990,10 +1282,18 @@ export declare class EditorView extends Disposable {
990
1282
  * to their parent's box) stay aligned with the content.
991
1283
  */
992
1284
  private readonly _contentContainer;
1285
+ private readonly _resizeObserver;
993
1286
  private readonly _cursorView;
994
1287
  private readonly _selectionView;
995
1288
  private readonly _gutterMarkersView;
996
1289
  private readonly _diffHighlightsView;
1290
+ private _readonlyToggleButton;
1291
+ private readonly _editContextSuspensions;
1292
+ private readonly _revealOcclusions;
1293
+ private _pendingTopReveal;
1294
+ private _caretRevealRaf;
1295
+ private _followedCaretBlock;
1296
+ private _followCaretAfterEdit;
997
1297
  /**
998
1298
  * The mounted block sequence, in source order. Rebuilt (not mutated) each
999
1299
  * frame by {@link DocumentViewNode.create}; the view just swaps one
@@ -1001,8 +1301,17 @@ export declare class EditorView extends Disposable {
1001
1301
  * (those go through the measured-layout model).
1002
1302
  */
1003
1303
  private readonly _document;
1304
+ private readonly _embeddedCodeEditorFactoryVersion;
1305
+ private readonly _suspendEditContextForBlockControl;
1306
+ private _clipboardWriter;
1307
+ private readonly _writeClipboardText;
1308
+ /** Connects explicit copy actions to the controller's host clipboard strategy. */
1309
+ setClipboardWriter(writeText: (text: string) => Promise<void>): IDisposable;
1310
+ private _renderedSourceEditing;
1004
1311
  /** The current view-node tree (AST overlaid with rendered DOM), for debugging. */
1005
1312
  get documentViewNode(): IObservable<DocumentViewNode | undefined>;
1313
+ /** Re-resolves embedded code editors while preserving the surrounding editor view. */
1314
+ refreshEmbeddedCodeEditors(): void;
1006
1315
  /**
1007
1316
  * Last frame's view-data overlay, threaded back into
1008
1317
  * {@link buildDocumentViewData} so any subtree whose ast and selection flags
@@ -1014,12 +1323,15 @@ export declare class EditorView extends Disposable {
1014
1323
  private readonly _viewData;
1015
1324
  get viewData(): IObservable<DocumentViewData | undefined>;
1016
1325
  /**
1017
- * Caret rect (client coords) for the transient empty paragraph, or
1018
- * `undefined` when none is armed. Set each frame from the synthetic
1019
- * paragraph element's geometry and fed to the {@link CursorView}, which has
1020
- * no visual-line-map entry to place the caret from otherwise.
1326
+ * Whether the editor is genuinely focused: focus rests somewhere inside the
1327
+ * editor subtree *and* its window is focused. Mirrored onto the root as
1328
+ * `.md-focused`, which gates the painted caret — the blinking cursor is only
1329
+ * shown while this is `true`, so it never blinks in an unfocused editor or
1330
+ * after the window loses focus. Only the caret's visibility is affected; the
1331
+ * logical selection and caret geometry ({@link caretRect}) are unchanged.
1021
1332
  */
1022
- private readonly _pendingCaretRect;
1333
+ private readonly _focused;
1334
+ get focused(): IObservable<boolean>;
1023
1335
  /**
1024
1336
  * The block cache projected for views (selection painting) that need to
1025
1337
  * react to mount/unmount. Derived from {@link _document}, so it stays in
@@ -1050,6 +1362,7 @@ export declare class EditorView extends Disposable {
1050
1362
  */
1051
1363
  rangeRects(range: OffsetRange): IObservable<readonly SelectionRect[]>;
1052
1364
  constructor(_model: EditorModel, _options?: EditorViewOptions | undefined);
1365
+ private _setupEmptyDocumentSelection;
1053
1366
  /**
1054
1367
  * Mirrors the model's live Ctrl/Cmd state onto the editor root as
1055
1368
  * `.md-mod-down` so CSS can show the link-open underline and pointer cursor
@@ -1058,34 +1371,109 @@ export declare class EditorView extends Disposable {
1058
1371
  */
1059
1372
  private _setupModifierTracking;
1060
1373
  /**
1061
- * Renders the edit/read-only lock toggle. It flips the model's
1062
- * {@link EditorModel.readonlyMode}: when locked (read-only) every block stays
1374
+ * Tracks whether the editor is genuinely focused and mirrors it onto the
1375
+ * root as `.md-focused` so CSS can gate the painted caret. "Focused" means
1376
+ * focus rests somewhere inside the editor subtree *and* the window itself is
1377
+ * focused; either condition failing (focus moving elsewhere, or the window
1378
+ * losing focus) hides the blinking caret while leaving the logical selection
1379
+ * and caret geometry intact.
1380
+ */
1381
+ private _setupFocusTracking;
1382
+ private _setupCaretScrollPadding;
1383
+ /**
1384
+ * Renders the locked/rich/source editing mode toggle. When locked every block stays
1063
1385
  * in its clean rendered form (no markdown markers revealed) and edits are
1064
1386
  * ignored, while text selection still works. The control lives in a
1065
- * zero-height *sticky* host so the lock stays pinned to the top-right corner
1066
- * of the scroll container as the document scrolls. The current mode is also
1067
- * mirrored onto the root as `.md-readonly` for any CSS hooks.
1387
+ * zero-height sticky host, using the right margin when it fits and
1388
+ * overlapping content when narrow, without changing the document's geometry.
1389
+ * The current mode is also mirrored onto the root as `.md-readonly`
1390
+ * for any CSS hooks.
1068
1391
  */
1069
1392
  private _setupReadonlyToggle;
1393
+ /** Draws attention to the mode toggle after text input is attempted while locked. */
1394
+ showReadonlyEditingAttempt(): void;
1070
1395
  focus(): void;
1071
- /**
1072
- * Opt-in "own" point→offset resolution (a debug/experimental flag). When
1073
- * `false` (default), {@link resolveOffsetFromPoint} uses the platform DOM
1074
- * hit-test (`caretPositionFromPoint`). When `true`, it ignores the DOM
1075
- * hit-test and snaps the point to the nearest offset purely from the
1076
- * rendered {@link VisualLineMap} geometry — picking the nearest visual line
1077
- * by `y`, then the nearest offset on it by `x`. Because a table row's cells
1078
- * share one horizontal line band, this makes the whole width of a row
1079
- * resolve into that row (rather than only the cell boxes), with no visible
1080
- * layout change.
1081
- */
1082
- readonly geometricHitTest: ISettableObservable<boolean, void>;
1396
+ mountOverlay(element: HTMLElement | SVGSVGElement, position: EditorOverlayPosition): IDisposable;
1397
+ /** Registers floating editor chrome that should count as covering a range during reveal. */
1398
+ registerRevealOcclusion(element: Element): IDisposable;
1399
+ /**
1400
+ * Temporarily detaches the root {@link EditContext} while focus is inside
1401
+ * nested editor chrome. Chromium otherwise reclaims focus from non-text
1402
+ * controls inside the EditContext host, breaking keyboard access to controls
1403
+ * such as the find actions and read-only toggle.
1404
+ */
1405
+ suspendEditContextWhileFocused(element: HTMLElement): IDisposable;
1406
+ revealRangeInCenterIfOutsideViewport(range: OffsetRange, behavior?: ScrollBehavior): IDisposable;
1407
+ /**
1408
+ * Aligns an explicitly navigated range with the top of its nearest vertical
1409
+ * scroll viewport, even when the range is already partially or fully visible.
1410
+ * The alignment leaves {@link TOP_REVEAL_CONTEXT_INSET}px of navigation
1411
+ * context above the range, grown so the range also clears any chrome
1412
+ * registered through {@link registerRevealOcclusion} that covers the top of
1413
+ * that viewport. Outer vertical scrollers and the window keep nearest-edge
1414
+ * behavior so they do not jump, and horizontal scrolling stays nearest-edge.
1415
+ *
1416
+ * Explicit navigation also stops edit-driven caret following, so a later
1417
+ * block resize does not scroll back to where the caret was left behind.
1418
+ * Sticky chrome is remeasured once scrolling completes. User input, a newer
1419
+ * reveal, or disposal cancels that deferred correction.
1420
+ */
1421
+ revealRangeAtTop(range: OffsetRange, behavior?: ScrollBehavior): IDisposable;
1422
+ private _scheduleRangeReveal;
1423
+ private _scheduleTopRangeReveal;
1424
+ /**
1425
+ * Keeps the caret visible after an editor-driven text edit. The reveal is
1426
+ * deferred until the rebuilt document has been laid out and uses nearest-edge
1427
+ * scrolling so ordinary typing only moves the containing viewport as far as
1428
+ * needed. While this mode is active, a later resize of the same active block
1429
+ * also re-reveals the caret (for asynchronous code, math, or diagram layout).
1430
+ */
1431
+ revealCaretAfterEdit(): void;
1432
+ /** Keeps a keyboard-moved caret visible without enabling edit-resize following. */
1433
+ revealCaretAfterKeyboardNavigation(): void;
1434
+ /** Stops edit-driven caret following before pointer-based selection begins. */
1435
+ stopFollowingCaret(): void;
1436
+ /**
1437
+ * Samples the ambient focus state that decides whether taking focus on open
1438
+ * would steal it from an explicit user target: whether the window is focused
1439
+ * and whether focus is still unclaimed (no active element, or the `<body>`
1440
+ * fallback).
1441
+ */
1442
+ private _sampleAutoFocusEnvironment;
1443
+ /**
1444
+ * One-shot guarded focus attempt: focuses the editor only if doing so will
1445
+ * not steal focus from an explicit user target — the window must already be
1446
+ * focused and no other element may have claimed focus yet. Returns whether
1447
+ * focus was taken. A no-op for a background window or when the user has
1448
+ * already focused something else. {@link autoFocusOnOpen} builds the
1449
+ * open-time behavior on top of this primitive.
1450
+ */
1451
+ tryAutoFocus(): boolean;
1452
+ /**
1453
+ * Focuses the editor when it opens without ever stealing focus from an
1454
+ * explicit user target. Tries once immediately; if the window is not focused
1455
+ * yet — a common open-time race where the editor is mounted before the host
1456
+ * routes focus to its window — the guarded attempt is deferred to the next
1457
+ * time the window gains focus and re-evaluated then. The deferral is
1458
+ * one-shot, so a later, unrelated window refocus never grabs focus, and the
1459
+ * re-check still respects any target the user has claimed in the meantime.
1460
+ */
1461
+ autoFocusOnOpen(): void;
1083
1462
  /**
1084
1463
  * Client coordinates → absolute source offset (any block). Used during
1085
1464
  * drag to keep extending the selection even when the pointer leaves the
1086
- * original block. Honours {@link geometricHitTest}.
1465
+ * original block. Snaps to the nearest visual line and source offset.
1087
1466
  */
1088
1467
  resolveOffsetFromPoint(point: Point2D): SourceOffset | undefined;
1468
+ resolveCursorPositionFromPoint(point: Point2D): SourceCursorPosition | undefined;
1469
+ private _resolveControlFreeVideoOffset;
1470
+ /**
1471
+ * Resolve table-cell hits that have no measurable text run. Empty cells map
1472
+ * from their own box instead of snapping to a neighboring cell; element-only
1473
+ * content (for example an inactive image) maps through the hit element's view
1474
+ * node. Text-bearing cells keep the normal pixel-precise line-map path.
1475
+ */
1476
+ private _resolveTableCellOffset;
1089
1477
  /**
1090
1478
  * Whether a client point falls on the rendered document content, as
1091
1479
  * opposed to the surrounding editor padding (the green area). Uses DOM
@@ -1095,6 +1483,14 @@ export declare class EditorView extends Disposable {
1095
1483
  * have `pointer-events: none`, so the hit-test sees through them.
1096
1484
  */
1097
1485
  isPointInContent(point: Point2D): boolean;
1486
+ /**
1487
+ * Whether `range` intersects the rendered source text — the region whose
1488
+ * selection this editor paints itself from `model.selection`. This also
1489
+ * catches select-all ranges whose endpoints surround the rendered content.
1490
+ * Overlays anchored beside the text (comment widgets and the like) are *not*
1491
+ * part of it and keep their own native selection behaviour.
1492
+ */
1493
+ intersectsRenderedContent(range: Range): boolean;
1098
1494
  private readonly _renderAutorun;
1099
1495
  /** Current mounted blocks, or empty before the first render. */
1100
1496
  private get _blocks();
@@ -1113,9 +1509,46 @@ export declare class EditorView extends Disposable {
1113
1509
  */
1114
1510
  private _paintDiff;
1115
1511
  private _clearDiff;
1512
+ private _syncEditContextAttachment;
1513
+ private _revealRange;
1514
+ private _revealTarget;
1515
+ private _scheduleCaretReveal;
1516
+ private _revealCaretNearest;
1517
+ private _revealCaretAfterActiveBlockResize;
1518
+ private _caretBlockAt;
1519
+ private _measurementAt;
1520
+ private _stopFollowingCaret;
1521
+ private _isRevealOccluded;
1522
+ /** Client rects of registered occlusions that are currently rendered and visible. */
1523
+ private _activeRevealOcclusions;
1524
+ /**
1525
+ * How far registered chrome covers the top of `viewport`, measured down from
1526
+ * `viewport.top`, across the columns `target` occupies. Clearing one occluder
1527
+ * can slide the target behind the next one, so the tested band is re-evaluated
1528
+ * until it settles; stacked chrome therefore reports the lowest connected
1529
+ * bottom edge. Returns 0 when nothing covers the top.
1530
+ */
1531
+ private _occludedTopHeight;
1532
+ /**
1533
+ * Vertical inset used to top-align `target` inside `viewport`. Defaults to
1534
+ * {@link TOP_REVEAL_CONTEXT_INSET}, and grows past registered chrome covering
1535
+ * the viewport top so the same breathing room is kept below that chrome.
1536
+ */
1537
+ private _topRevealInset;
1538
+ /**
1539
+ * `viewport` reduced to the area an explicitly navigated target may occupy:
1540
+ * registered top chrome is excluded, along with the breathing room below it.
1541
+ * Nearest-edge movement parks the target just inside the rect it is given, so
1542
+ * the inset has to be part of that rect; otherwise an outer scroller, or the
1543
+ * window, would leave the target grazing the chrome's bottom edge after the
1544
+ * nearest vertical viewport had already aligned it.
1545
+ */
1546
+ private _unoccludedViewport;
1116
1547
  }
1117
1548
 
1118
1549
  export declare interface EditorViewOptions extends BlockViewOptions {
1550
+ readonly presentation?: EditorPresentation;
1551
+ readonly textInput?: EditorTextInput;
1119
1552
  /**
1120
1553
  * Extra class names added to the editor root element, e.g. a theme class
1121
1554
  * such as `'md-theme-default'` or `'github-markdown-theme'`. Theme styles
@@ -1123,6 +1556,14 @@ export declare interface EditorViewOptions extends BlockViewOptions {
1123
1556
  * only) unless a theme class is supplied.
1124
1557
  */
1125
1558
  readonly classNames?: readonly string[];
1559
+ /**
1560
+ * Whether to render the edit/read-only toggle at the top-right edge
1561
+ * of the content. Defaults to `true`; set to `false` to omit it (e.g. in
1562
+ * fixtures that focus on selection rendering).
1563
+ */
1564
+ readonly showReadonlyToggle?: boolean;
1565
+ /** Whether to paint the active block's background and glow. Defaults to `true`. */
1566
+ readonly highlightActiveBlock?: boolean;
1126
1567
  /**
1127
1568
  * Controls "limited width mode". The observable yields the maximum content
1128
1569
  * width in pixels, or `undefined` to let the content fill the available
@@ -1145,10 +1586,10 @@ export declare interface EditorViewOptions extends BlockViewOptions {
1145
1586
 
1146
1587
  export declare class EmphasisAstNode extends AstNode {
1147
1588
  readonly openMarker: MarkerAstNode;
1148
- readonly content: readonly (InlineAstNode | GlueAstNode)[];
1589
+ readonly content: readonly InlineContentAstNode[];
1149
1590
  readonly closeMarker: MarkerAstNode;
1150
1591
  readonly kind = "emphasis";
1151
- constructor(openMarker: MarkerAstNode, content: readonly (InlineAstNode | GlueAstNode)[], closeMarker: MarkerAstNode);
1592
+ constructor(openMarker: MarkerAstNode, content: readonly InlineContentAstNode[], closeMarker: MarkerAstNode);
1152
1593
  get children(): readonly AstNode[];
1153
1594
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1154
1595
  }
@@ -1160,6 +1601,129 @@ declare class EmphasisViewData {
1160
1601
  constructor(ast: EmphasisAstNode, content: readonly AnyViewData[]);
1161
1602
  }
1162
1603
 
1604
+ /** One blank source line, or the empty final line after a terminating newline. */
1605
+ export declare class EmptyBlockAstNode extends BlockAstNodeBase {
1606
+ readonly content: readonly GlueAstNode[];
1607
+ readonly leadingTrivia?: GlueAstNode | undefined;
1608
+ readonly kind = "emptyBlock";
1609
+ constructor(content: readonly GlueAstNode[], leadingTrivia?: GlueAstNode | undefined);
1610
+ get children(): readonly AstNode[];
1611
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1612
+ withLeadingTrivia(trivia: GlueAstNode | undefined): EmptyBlockAstNode;
1613
+ }
1614
+
1615
+ declare class EmptyBlockViewData {
1616
+ readonly ast: EmptyBlockAstNode;
1617
+ readonly content: readonly AnyViewData[];
1618
+ readonly kind = "emptyBlock";
1619
+ constructor(ast: EmptyBlockAstNode, content: readonly AnyViewData[]);
1620
+ }
1621
+
1622
+ export declare function escapeFindRegex(value: string): string;
1623
+
1624
+ export declare const FIND_MATCH_LIMIT = 19999;
1625
+
1626
+ export declare function findBlockAtOffset(doc: DocumentAstNode, offset: SourceOffset): BlockAstNode | undefined;
1627
+
1628
+ export declare class FindController extends Disposable {
1629
+ private readonly _editorModel;
1630
+ private readonly _view;
1631
+ private readonly _options;
1632
+ readonly model: FindModel;
1633
+ readonly widget: FindWidget;
1634
+ private readonly _selectionForScope;
1635
+ private _forcedMatch;
1636
+ private _selectedMatch;
1637
+ private _observedSourceTextId;
1638
+ private readonly _sourceEditTracker;
1639
+ private _revealRequest;
1640
+ constructor(_editorModel: EditorModel, _view: EditorView, _options: FindControllerOptions);
1641
+ private _setForcedMarkerVisibleBlocks;
1642
+ openAndFocus(): void;
1643
+ close(): void;
1644
+ private _handleKeyDown;
1645
+ private _cancelRevealRequest;
1646
+ private _findByKeyboard;
1647
+ private _querySeed;
1648
+ private _prepareSeed;
1649
+ private _selectedSingleLineText;
1650
+ private _toggleFindInSelection;
1651
+ }
1652
+
1653
+ export declare interface FindControllerOptions {
1654
+ readonly keyboardPlatform: KeyboardPlatform;
1655
+ }
1656
+
1657
+ export declare type FindDirection = 'next' | 'previous';
1658
+
1659
+ export declare class FindHighlightsView extends Disposable {
1660
+ private readonly _view;
1661
+ private readonly _matchesLayer;
1662
+ private readonly _currentLayer;
1663
+ private readonly _highlightRegistration;
1664
+ private readonly _resizeObserver;
1665
+ private readonly _resizeObservedElements;
1666
+ private _snapshot;
1667
+ private _paintRaf;
1668
+ constructor(_view: EditorView, findModel: FindModel);
1669
+ private _schedulePaint;
1670
+ private _paint;
1671
+ private _observeResizeAncestors;
1672
+ private _paintRanges;
1673
+ }
1674
+
1675
+ export declare interface FindMatchesResult {
1676
+ readonly matches: readonly OffsetRange[];
1677
+ readonly isCapped: boolean;
1678
+ }
1679
+
1680
+ export declare class FindModel extends Disposable {
1681
+ private readonly _editorModel;
1682
+ readonly isRevealed: ISettableObservable<boolean, void>;
1683
+ readonly searchString: ISettableObservable<string, void>;
1684
+ readonly isRegex: ISettableObservable<boolean, void>;
1685
+ readonly matchCase: ISettableObservable<boolean, void>;
1686
+ readonly wholeWord: ISettableObservable<boolean, void>;
1687
+ readonly searchScope: ISettableObservable<OffsetRange | undefined, void>;
1688
+ readonly currentMatch: ISettableObservable<OffsetRange | undefined, void>;
1689
+ readonly loop: ISettableObservable<boolean, void>;
1690
+ readonly searchResult: IObservableWithChange< {
1691
+ kind: "invalid";
1692
+ error: Error;
1693
+ pattern?: undefined;
1694
+ matches?: undefined;
1695
+ isCapped?: undefined;
1696
+ } | {
1697
+ kind: "valid";
1698
+ pattern: FindPattern;
1699
+ matches: readonly OffsetRange[];
1700
+ isCapped: boolean;
1701
+ error?: undefined;
1702
+ }, void>;
1703
+ readonly matchesCount: IObservableWithChange<number, void>;
1704
+ readonly isCapped: IObservableWithChange<boolean, void>;
1705
+ readonly currentMatchPosition: IObservableWithChange<number, void>;
1706
+ private _searchOrigin;
1707
+ private readonly _sourceEditTracker;
1708
+ private _pendingInitialDirection;
1709
+ constructor(_editorModel: EditorModel);
1710
+ reveal(options: {
1711
+ readonly origin: number;
1712
+ readonly searchString?: string;
1713
+ readonly direction?: FindDirection;
1714
+ }): void;
1715
+ hide(): void;
1716
+ setSearchOrigin(offset: number): void;
1717
+ setSearchScope(scope: OffsetRange | undefined): void;
1718
+ moveToNextMatch(): OffsetRange | undefined;
1719
+ moveToPreviousMatch(): OffsetRange | undefined;
1720
+ private _move;
1721
+ private _selectFromOrigin;
1722
+ private _mapStateThroughEdit;
1723
+ private _inputSnapshot;
1724
+ private _readInputSnapshot;
1725
+ }
1726
+
1163
1727
  /**
1164
1728
  * Source offset (relative to `root`) of the node with `target`'s id, or
1165
1729
  * `undefined` when it is not in the tree. Ids are stable across edits, so this
@@ -1167,14 +1731,117 @@ declare class EmphasisViewData {
1167
1731
  */
1168
1732
  export declare function findNodeOffsetById(root: AstNode, target: AstNode): number | undefined;
1169
1733
 
1170
- export declare function findWordAt(text: string, offset: number): {
1734
+ export declare class FindPattern {
1735
+ private readonly _source;
1736
+ private readonly _flags;
1737
+ private readonly _wholeWord;
1738
+ private readonly _wordSeparators;
1739
+ readonly isEmpty: boolean;
1740
+ private constructor();
1741
+ static create(query: FindQuery): FindQueryResult;
1742
+ findMatches(text: string, scope?: OffsetRange, limit?: number): FindMatchesResult;
1743
+ findNextMatch(text: string, after: number, scope?: OffsetRange, loop?: boolean, skip?: OffsetRange): OffsetRange | undefined;
1744
+ findPreviousMatch(text: string, before: number, scope?: OffsetRange, loop?: boolean, skip?: OffsetRange): OffsetRange | undefined;
1745
+ private _forEachMatch;
1746
+ }
1747
+
1748
+ export declare interface FindQuery {
1749
+ readonly searchString: string;
1750
+ readonly isRegex: boolean;
1751
+ readonly matchCase: boolean;
1752
+ readonly wholeWord: boolean;
1753
+ readonly wordSeparators: string;
1754
+ }
1755
+
1756
+ export declare type FindQueryResult = {
1757
+ readonly kind: 'valid';
1758
+ readonly pattern: FindPattern;
1759
+ } | {
1760
+ readonly kind: 'invalid';
1761
+ readonly error: Error;
1762
+ };
1763
+
1764
+ export declare type FindSearchResult = {
1765
+ readonly kind: 'valid';
1766
+ readonly pattern: FindPattern;
1767
+ readonly matches: readonly OffsetRange[];
1768
+ readonly isCapped: boolean;
1769
+ } | {
1770
+ readonly kind: 'invalid';
1771
+ readonly error: Error;
1772
+ };
1773
+
1774
+ export declare class FindWidget extends Disposable {
1775
+ private readonly _view;
1776
+ private readonly _options;
1777
+ readonly element: HTMLElement;
1778
+ readonly panelElement: HTMLElement;
1779
+ readonly focused: ISettableObservable<boolean, void>;
1780
+ private readonly _inputShell;
1781
+ private readonly _input;
1782
+ private readonly _matchesCount;
1783
+ private readonly _previousButton;
1784
+ private readonly _nextButton;
1785
+ private readonly _selectionButton;
1786
+ private readonly _caseButton;
1787
+ private readonly _wholeWordButton;
1788
+ private readonly _regexButton;
1789
+ private readonly _error;
1790
+ constructor(_view: EditorView, _options: FindWidgetOptions);
1791
+ focusAndSelect(): void;
1792
+ private _registerButton;
1793
+ private _render;
1794
+ }
1795
+
1796
+ export declare interface FindWidgetOptions {
1797
+ readonly findModel: FindModel;
1798
+ readonly canFindInSelection: IObservable<boolean>;
1799
+ readonly onNext: () => void;
1800
+ readonly onPrevious: () => void;
1801
+ readonly onToggleFindInSelection: () => void;
1802
+ readonly onClose: () => void;
1803
+ }
1804
+
1805
+ export declare function findWordAt(text: string, offset: number, config?: WordNavigationConfig): {
1171
1806
  start: number;
1172
1807
  end: number;
1173
1808
  };
1174
1809
 
1175
- export declare function findWordBoundaryLeft(text: string, offset: number): number;
1810
+ export declare function findWordBoundaryLeft(text: string, offset: number, config?: WordNavigationConfig): number;
1811
+
1812
+ export declare function findWordBoundaryRight(text: string, offset: number, config?: WordNavigationConfig): number;
1813
+
1814
+ export declare function findWordDeleteBoundaryLeft(text: string, offset: number, config?: WordNavigationConfig): number;
1815
+
1816
+ export declare function findWordDeleteBoundaryRight(text: string, offset: number, config?: WordNavigationConfig): number;
1817
+
1818
+ /**
1819
+ * A leading YAML front matter block. The YAML value is intentionally opaque:
1820
+ * only the two fences and the exact source between them are modeled.
1821
+ */
1822
+ export declare class FrontMatterAstNode extends BlockAstNodeBase {
1823
+ readonly content: readonly (MarkerAstNode | GlueAstNode)[];
1824
+ readonly leadingTrivia?: GlueAstNode | undefined;
1825
+ readonly kind = "frontMatter";
1826
+ constructor(content: readonly (MarkerAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
1827
+ get children(): readonly AstNode[];
1828
+ get openFence(): MarkerAstNode | undefined;
1829
+ get closeFence(): MarkerAstNode | undefined;
1830
+ get value(): MarkerAstNode | undefined;
1831
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1832
+ withLeadingTrivia(trivia: GlueAstNode | undefined): FrontMatterAstNode;
1833
+ }
1176
1834
 
1177
- export declare function findWordBoundaryRight(text: string, offset: number): number;
1835
+ declare class FrontMatterViewData {
1836
+ readonly ast: FrontMatterAstNode;
1837
+ /** Active: render both fences; inactive: render only the opaque YAML value. */
1838
+ readonly showMarkup: boolean;
1839
+ readonly content: readonly AnyViewData[];
1840
+ readonly kind = "frontMatter";
1841
+ constructor(ast: FrontMatterAstNode,
1842
+ /** Active: render both fences; inactive: render only the opaque YAML value. */
1843
+ showMarkup: boolean, content: readonly AnyViewData[]);
1844
+ }
1178
1845
 
1179
1846
  export declare function getAnnotatedSource(node: AstNode, source: string, offset?: number): string;
1180
1847
 
@@ -1197,6 +1864,8 @@ declare class GlueViewData {
1197
1864
  * block children) the break is already visible, so no `↵` is drawn.
1198
1865
  */
1199
1866
  readonly decorateNewline: boolean;
1867
+ readonly showWhitespace: boolean;
1868
+ readonly listContinuation?: ListContinuation | undefined;
1200
1869
  readonly kind = "glue";
1201
1870
  constructor(ast: GlueAstNode, visible: boolean,
1202
1871
  /**
@@ -1205,7 +1874,7 @@ declare class GlueViewData {
1205
1874
  * the line ending hiding there; between block-level siblings (list items,
1206
1875
  * block children) the break is already visible, so no `↵` is drawn.
1207
1876
  */
1208
- decorateNewline: boolean);
1877
+ decorateNewline: boolean, showWhitespace?: boolean, listContinuation?: ListContinuation | undefined);
1209
1878
  }
1210
1879
 
1211
1880
  /**
@@ -1234,10 +1903,10 @@ export declare type GutterMarkerType = 'added' | 'modified' | 'deleted';
1234
1903
  export declare class HeadingAstNode extends BlockAstNodeBase {
1235
1904
  readonly level: 1 | 2 | 3 | 4 | 5 | 6;
1236
1905
  readonly marker: MarkerAstNode;
1237
- readonly content: readonly (InlineAstNode | GlueAstNode)[];
1906
+ readonly content: readonly InlineContentAstNode[];
1238
1907
  readonly leadingTrivia?: GlueAstNode | undefined;
1239
1908
  readonly kind = "heading";
1240
- constructor(level: 1 | 2 | 3 | 4 | 5 | 6, marker: MarkerAstNode, content: readonly (InlineAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
1909
+ constructor(level: 1 | 2 | 3 | 4 | 5 | 6, marker: MarkerAstNode, content: readonly InlineContentAstNode[], leadingTrivia?: GlueAstNode | undefined);
1241
1910
  get children(): readonly AstNode[];
1242
1911
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1243
1912
  withLeadingTrivia(trivia: GlueAstNode | undefined): HeadingAstNode;
@@ -1251,6 +1920,19 @@ declare class HeadingViewData {
1251
1920
  constructor(ast: HeadingAstNode, content: readonly AnyViewData[]);
1252
1921
  }
1253
1922
 
1923
+ export declare function hiddenCursorRanges(doc: DocumentAstNode, markerVisibleBlocks: ReadonlySet<BlockAstNode>, selectionRange: OffsetRange): readonly OffsetRange[];
1924
+
1925
+ export declare type HistoryKeyboardAction = 'undo' | 'redo';
1926
+
1927
+ /** A block HTML comment, discriminated by whether its closing delimiter is present. */
1928
+ declare type HtmlCommentSource = OpenHtmlCommentSource | CompleteHtmlCommentSource;
1929
+
1930
+ declare interface HtmlCommentSourceBase {
1931
+ readonly leadingWhitespace: string;
1932
+ readonly opening: '<!--';
1933
+ readonly body: string;
1934
+ }
1935
+
1254
1936
  /**
1255
1937
  * The editor operations a clipboard strategy drives. The strategy never
1256
1938
  * touches the model or the DOM directly — it asks through this seam, so the
@@ -1263,8 +1945,8 @@ export declare interface IClipboardContext {
1263
1945
  getSelectedText(): string | undefined;
1264
1946
  /** Delete the current selection (the cut half of cut). */
1265
1947
  deleteSelection(): void;
1266
- /** Insert text at the caret, replacing any selection (the paste action). */
1267
- insertText(text: string): void;
1948
+ /** Paste text, linking a suitable selection when the payload is a URL unless plain text was requested. */
1949
+ insertText(text: string, plainText?: boolean): void;
1268
1950
  }
1269
1951
 
1270
1952
  /**
@@ -1280,6 +1962,8 @@ export declare interface IClipboardContext {
1280
1962
  * swallow the native clipboard events before they reach the editor.
1281
1963
  */
1282
1964
  export declare interface IClipboardStrategy {
1965
+ /** Copy an explicit payload without changing the editor selection. Falls back to the browser API when omitted. */
1966
+ writeText?(text: string): Promise<void>;
1283
1967
  /**
1284
1968
  * Wire up clipboard handling against `context`. The returned disposable
1285
1969
  * tears down every listener the strategy installed.
@@ -1287,9 +1971,6 @@ export declare interface IClipboardStrategy {
1287
1971
  connect(context: IClipboardContext): IDisposable;
1288
1972
  }
1289
1973
 
1290
- /** A live rendering of a {@link CommentsModel}. Dispose to unmount it. */
1291
- export declare type ICommentsPresenter = IDisposable;
1292
-
1293
1974
  /** The Monarch language definitions the default highlighter wires up. */
1294
1975
  export declare interface IDefaultMonarchGrammars {
1295
1976
  typescript: unknown;
@@ -1299,6 +1980,89 @@ export declare interface IDefaultMonarchGrammars {
1299
1980
  python: unknown;
1300
1981
  rust: unknown;
1301
1982
  shell: unknown;
1983
+ yaml: unknown;
1984
+ }
1985
+
1986
+ /**
1987
+ * A live editor embedded in place of a fenced code block's *rendered* form.
1988
+ *
1989
+ * This is the internal seam between the block view and a concrete embedded
1990
+ * editor (e.g. an `<iframe>` speaking the web-editor protocol). The block view
1991
+ * only speaks string edits: it pushes the block's content down via
1992
+ * {@link setContent} and receives the editor's own changes back through
1993
+ * {@link onEdit} (set by the block view on each (re)construction, so it always
1994
+ * routes to the current AST node). The concrete implementation owns its DOM,
1995
+ * transport, and lifecycle.
1996
+ *
1997
+ * A single instance is adopted across re-renders (like the highlighter session)
1998
+ * so the underlying editor keeps its state across edits — see
1999
+ * {@link CodeBlockViewNode}.
2000
+ */
2001
+ declare interface IEmbeddedCodeEditor {
2002
+ /** The element mounted as the block's rendered form. */
2003
+ readonly element: HTMLElement;
2004
+ /**
2005
+ * Document → editor. The block's content changed (from any source). Must be
2006
+ * idempotent: pushing the content the editor already holds is a no-op, which
2007
+ * is how edits the editor itself originated are prevented from echoing back.
2008
+ */
2009
+ setContent(content: string): void;
2010
+ /** Update whether the embedded editor may change its content. */
2011
+ setReadOnly?(readOnly: boolean): void;
2012
+ /** Mount host actions alongside the embedded editor's own presentation controls. */
2013
+ setActions?(actions: HTMLElement): void;
2014
+ /**
2015
+ * Optional synchronous height (px) to reserve for `content` *before* the
2016
+ * editor has laid out. Return `undefined` to let the editor size itself
2017
+ * (the implementation may report its real height later). Lets a registration
2018
+ * avoid a layout jump when it can cheaply estimate the size from content.
2019
+ */
2020
+ estimateHeight?(content: string): number | undefined;
2021
+ /**
2022
+ * Editor → document. Set by the block view on every (re)construction to
2023
+ * route the editor's own edits, expressed in the block's *content*
2024
+ * coordinates, to the current AST node.
2025
+ */
2026
+ onEdit?: (edit: StringEdit) => void;
2027
+ dispose(): void;
2028
+ }
2029
+
2030
+ /** Creates an {@link IEmbeddedCodeEditor} for a fenced block, or opts out. */
2031
+ declare interface IEmbeddedCodeEditorFactory {
2032
+ /**
2033
+ * Return an editor for a fenced block, or `undefined` to fall
2034
+ * back to the default (highlighting / {@link BlockViewOptions.renderCustomCodeBlock}).
2035
+ */
2036
+ create(language: string, infoString: string, initialContent: string): IEmbeddedCodeEditor | undefined;
2037
+ }
2038
+
2039
+ /**
2040
+ * Routes undo and redo to whatever owns the document's history: the editor
2041
+ * itself on a standalone page, or the enclosing document in a host like
2042
+ * VS Code.
2043
+ */
2044
+ export declare interface IHistoryStrategy {
2045
+ undo(): void;
2046
+ redo(): void;
2047
+ /**
2048
+ * Invoked around each source mutation so the strategy can record it.
2049
+ * Implemented only by strategies that build their own history; a host that
2050
+ * forwards edits to a VS Code `TextDocument` lets it record them instead.
2051
+ */
2052
+ record?(operation: () => void, edit?: StringEdit): void;
2053
+ }
2054
+
2055
+ export declare interface ILinkPresentation extends IDisposable {
2056
+ /** Current presentation, updated without rebuilding the editor. */
2057
+ readonly presentation: IObservable<LinkPresentation | undefined>;
2058
+ }
2059
+
2060
+ export declare interface ILinkPresentationProvider {
2061
+ /**
2062
+ * Returns `undefined` for unsupported links. The caller disposes the returned
2063
+ * reference when the rendered link disappears.
2064
+ */
2065
+ createLinkPresentation(url: string): ILinkPresentation | undefined;
1302
2066
  }
1303
2067
 
1304
2068
  export declare class ImageAstNode extends AstNode {
@@ -1335,6 +2099,14 @@ export declare interface IMonarchApi {
1335
2099
  MonarchTokenizer: new (languageService: unknown, standaloneThemeService: unknown, languageId: string, lexer: unknown, configurationService: unknown) => MonarchTokenizer;
1336
2100
  }
1337
2101
 
2102
+ /** Controls tab-stop insertion and non-list line indentation. */
2103
+ export declare interface IndentationConfig {
2104
+ /** Number of visual columns between tab stops. */
2105
+ readonly tabSize: number;
2106
+ /** Whether indentation uses spaces instead of tab characters. */
2107
+ readonly insertSpaces: boolean;
2108
+ }
2109
+
1338
2110
  export declare type InlineAstNode = TextAstNode | StrongAstNode | EmphasisAstNode | StrikethroughAstNode | InlineCodeAstNode | InlineMathAstNode | LinkAstNode | ImageAstNode;
1339
2111
 
1340
2112
  export declare class InlineCodeAstNode extends AstNode {
@@ -1352,6 +2124,8 @@ declare class InlineCodeViewData {
1352
2124
  constructor(ast: InlineCodeAstNode, content: readonly AnyViewData[]);
1353
2125
  }
1354
2126
 
2127
+ declare type InlineContentAstNode = InlineAstNode | MarkerAstNode | GlueAstNode;
2128
+
1355
2129
  export declare class InlineMathAstNode extends AstNode {
1356
2130
  readonly content: readonly (MarkerAstNode | GlueAstNode)[];
1357
2131
  readonly kind = "inlineMath";
@@ -1389,17 +2163,29 @@ export declare const insertParagraph: EditCommand;
1389
2163
  * - paragraph / heading / thematic break — the "rich text" thing: at the
1390
2164
  * block's end arm a transient empty paragraph (see {@link SmartEnterResult});
1391
2165
  * elsewhere split into two paragraphs (`\n\n`).
1392
- * - code block — insert a newline that preserves the current line's indentation,
1393
- * staying inside the fence.
2166
+ * - fenced code / front matter — insert a newline that preserves the current
2167
+ * line's indentation, staying inside the fences.
2168
+ * - video — leave the completed HTML block at its end; otherwise insert a
2169
+ * normal source line break.
1394
2170
  * - block quote — continue the quote (`\n> `); an empty quote line exits it.
1395
2171
  * - list — continue the list with the next marker (incrementing ordered
1396
- * numbers, re-emitting task checkboxes); an empty item exits the list.
2172
+ * numbers, re-emitting task checkboxes); an empty item outdents one level
2173
+ * before exiting the list.
2174
+ * - complete HTML comment — at the comment's end, leave it by arming a
2175
+ * transient paragraph; inside it (or while the comment is open), insert a
2176
+ * normal source line break.
1397
2177
  * A non-collapsed selection, or any other block, falls back to a plain soft line
1398
2178
  * break, preserving today's behaviour.
1399
2179
  */
1400
- export declare const insertSmartEnter: (ctx: CursorCommandContext) => SmartEnterResult;
2180
+ export declare const insertSmartEnter: (ctx: CursorCommandContext, useSourceLineBreaks?: boolean) => SmartEnterResult;
1401
2181
 
1402
- export declare function insertText(text: string): EditCommand;
2182
+ /**
2183
+ * VS Code-style Tab: insert to the next tab stop for a caret or partial
2184
+ * single-line selection, and indent every selected line for a line selection.
2185
+ */
2186
+ export declare function insertTab(config?: IndentationConfig): EditCommand;
2187
+
2188
+ export declare function insertText(text: string, generatedIndentation?: OffsetRange, completeFences?: boolean): EditCommand;
1403
2189
 
1404
2190
  /**
1405
2191
  * An immutable view of one document's tokens at a point in time. It may be a
@@ -1440,6 +2226,31 @@ export declare interface ISyntaxHighlighterDocument extends IDisposable {
1440
2226
  readonly snapshot: IObservableWithChange<ISyntaxHighlightedSnapshot, LengthEdit>;
1441
2227
  }
1442
2228
 
2229
+ export declare const joinLines: EditCommand;
2230
+
2231
+ export declare interface KeyboardBinding {
2232
+ readonly key: string;
2233
+ readonly modifiers?: KeyboardModifiers;
2234
+ readonly platforms?: readonly KeyboardPlatform[];
2235
+ readonly action: EditorKeyboardAction;
2236
+ }
2237
+
2238
+ export declare interface KeyboardModifiers {
2239
+ readonly shift?: boolean;
2240
+ readonly alt?: boolean;
2241
+ readonly ctrl?: boolean;
2242
+ readonly meta?: boolean;
2243
+ }
2244
+
2245
+ export declare type KeyboardPlatform = 'macos' | 'windows' | 'linux';
2246
+
2247
+ export declare interface KeyboardProfile {
2248
+ /**
2249
+ * Bindings in priority order. The first exact key/modifier/platform match wins.
2250
+ */
2251
+ readonly bindings: readonly KeyboardBinding[];
2252
+ }
2253
+
1443
2254
  declare abstract class LeafAstNode extends AstNode {
1444
2255
  abstract readonly content: string;
1445
2256
  get children(): readonly AstNode[];
@@ -1488,27 +2299,64 @@ export declare class LengthReplacement {
1488
2299
 
1489
2300
  export declare class LinkAstNode extends AstNode {
1490
2301
  readonly url: string;
1491
- readonly content: readonly (MarkerAstNode | InlineAstNode | GlueAstNode)[];
2302
+ readonly content: readonly InlineContentAstNode[];
2303
+ readonly title?: string | undefined;
1492
2304
  readonly kind = "link";
1493
- constructor(url: string, content: readonly (MarkerAstNode | InlineAstNode | GlueAstNode)[]);
2305
+ constructor(url: string, content: readonly InlineContentAstNode[], title?: string | undefined);
1494
2306
  get children(): readonly AstNode[];
1495
2307
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1496
2308
  protected _localEquals(o: this): boolean;
1497
2309
  }
1498
2310
 
2311
+ /**
2312
+ * Declarative rendering data for one link. `kind` selects the package-owned
2313
+ * visual treatment; providers never supply DOM or CSS.
2314
+ */
2315
+ export declare interface LinkPresentation {
2316
+ readonly kind: LinkPresentationKind;
2317
+ readonly title?: string;
2318
+ readonly detail?: string;
2319
+ readonly reference?: string;
2320
+ /** Primary resource state, such as pull-request lifecycle or session state. */
2321
+ readonly status?: LinkPresentationStatus;
2322
+ /** Secondary state, such as pull-request CI status. */
2323
+ readonly secondaryStatus?: LinkPresentationStatus;
2324
+ readonly changes?: LinkPresentationChanges;
2325
+ readonly tooltip?: string;
2326
+ readonly ariaLabel?: string;
2327
+ }
2328
+
2329
+ declare interface LinkPresentationChanges {
2330
+ readonly insertions: number;
2331
+ readonly deletions: number;
2332
+ }
2333
+
2334
+ export declare type LinkPresentationKind = 'resource' | 'issue' | 'pullRequest' | 'commit' | 'file' | 'folder' | 'session' | 'repository' | 'branch';
2335
+
2336
+ export declare interface LinkPresentationStatus {
2337
+ readonly kind: LinkPresentationStatusKind;
2338
+ readonly label: string;
2339
+ }
2340
+
2341
+ export declare type LinkPresentationStatusKind = 'neutral' | 'pending' | 'success' | 'warning' | 'error' | 'open' | 'closed' | 'merged' | 'draft' | 'notPlanned';
2342
+
1499
2343
  declare class LinkViewData {
1500
2344
  readonly ast: LinkAstNode;
2345
+ /** Active: render the Markdown source; inactive: allow a rich presentation. */
2346
+ readonly showMarkup: boolean;
1501
2347
  readonly content: readonly AnyViewData[];
1502
2348
  readonly kind = "link";
1503
- constructor(ast: LinkAstNode, content: readonly AnyViewData[]);
2349
+ constructor(ast: LinkAstNode,
2350
+ /** Active: render the Markdown source; inactive: allow a rich presentation. */
2351
+ showMarkup: boolean, content: readonly AnyViewData[]);
1504
2352
  }
1505
2353
 
1506
2354
  export declare class ListAstNode extends BlockAstNodeBase {
1507
2355
  readonly ordered: boolean;
1508
- readonly content: readonly (ListItemAstNode | GlueAstNode)[];
2356
+ readonly content: readonly (ListItemAstNode | EmptyBlockAstNode | GlueAstNode)[];
1509
2357
  readonly leadingTrivia?: GlueAstNode | undefined;
1510
2358
  readonly kind = "list";
1511
- constructor(ordered: boolean, content: readonly (ListItemAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
2359
+ constructor(ordered: boolean, content: readonly (ListItemAstNode | EmptyBlockAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
1512
2360
  get children(): readonly AstNode[];
1513
2361
  get items(): readonly ListItemAstNode[];
1514
2362
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
@@ -1516,6 +2364,14 @@ export declare class ListAstNode extends BlockAstNodeBase {
1516
2364
  protected _localEquals(o: this): boolean;
1517
2365
  }
1518
2366
 
2367
+ declare interface ListContinuation {
2368
+ readonly item: ListItemAstNode;
2369
+ readonly level: number;
2370
+ readonly indentation: number;
2371
+ readonly mixedTasks: boolean;
2372
+ readonly outsideList: boolean;
2373
+ }
2374
+
1519
2375
  export declare class ListItemAstNode extends AstNode {
1520
2376
  readonly marker: MarkerAstNode;
1521
2377
  readonly content: readonly (BlockAstNode | GlueAstNode)[];
@@ -1525,6 +2381,7 @@ export declare class ListItemAstNode extends AstNode {
1525
2381
  constructor(marker: MarkerAstNode, content: readonly (BlockAstNode | GlueAstNode)[], checked?: boolean | undefined, leadingTrivia?: GlueAstNode | undefined);
1526
2382
  get children(): readonly AstNode[];
1527
2383
  get blocks(): readonly BlockAstNode[];
2384
+ get isIncomplete(): boolean;
1528
2385
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1529
2386
  withLeadingTrivia(trivia: GlueAstNode | undefined): ListItemAstNode;
1530
2387
  protected _localEquals(o: this): boolean;
@@ -1537,12 +2394,27 @@ declare class ListItemViewData {
1537
2394
  readonly content: readonly AnyViewData[];
1538
2395
  /** 1-based list nesting depth, used to size the indentation gutter. */
1539
2396
  readonly level: number;
2397
+ /**
2398
+ * Whether this is an inactive task item whose first paragraph begins
2399
+ * with the `:running:` marker (see {@link TextViewData.hiddenPrefixLength}).
2400
+ * Always `false` while the item is active — an active/editing task
2401
+ * reveals the literal marker instead of the progress affordance.
2402
+ */
2403
+ readonly isRunning: boolean;
2404
+ readonly sourceIndentation: number;
1540
2405
  readonly kind = "listItem";
1541
2406
  constructor(ast: ListItemAstNode,
1542
2407
  /** Whether the selection reaches this item (reveals its markers). */
1543
2408
  isActive: boolean, content: readonly AnyViewData[],
1544
2409
  /** 1-based list nesting depth, used to size the indentation gutter. */
1545
- level: number);
2410
+ level: number,
2411
+ /**
2412
+ * Whether this is an inactive task item whose first paragraph begins
2413
+ * with the `:running:` marker (see {@link TextViewData.hiddenPrefixLength}).
2414
+ * Always `false` while the item is active — an active/editing task
2415
+ * reveals the literal marker instead of the progress affordance.
2416
+ */
2417
+ isRunning?: boolean, sourceIndentation?: number);
1546
2418
  }
1547
2419
 
1548
2420
  declare class ListViewData {
@@ -1552,6 +2424,41 @@ declare class ListViewData {
1552
2424
  constructor(ast: ListAstNode, content: readonly AnyViewData[]);
1553
2425
  }
1554
2426
 
2427
+ /**
2428
+ * Compact in-memory history for editors that hold the only copy of the
2429
+ * document, such as a standalone browser page. Where the surrounding host
2430
+ * already records history — a VS Code `TextDocument` — forward to that
2431
+ * instead.
2432
+ */
2433
+ export declare class LocalHistoryStrategy implements IHistoryStrategy {
2434
+ private readonly _model;
2435
+ private readonly _past;
2436
+ private readonly _future;
2437
+ /**
2438
+ * The source text as of the last change this strategy recorded or applied.
2439
+ * Any other value means the document was replaced behind its back, so the
2440
+ * stored edits no longer line up and must be discarded rather than applied.
2441
+ */
2442
+ private _lastKnownText;
2443
+ constructor(_model: EditorModel);
2444
+ record(operation: () => void, edit?: StringEdit): void;
2445
+ undo(): void;
2446
+ redo(): void;
2447
+ /** The entry on top of `stack`, or `undefined` when it cannot be applied. */
2448
+ private _peekApplicable;
2449
+ private _apply;
2450
+ private _clear;
2451
+ }
2452
+
2453
+ export declare interface MarkdownParseOptions {
2454
+ readonly explicitBlankLineBlocks?: boolean;
2455
+ readonly explicitFinalEmptyLine?: boolean;
2456
+ readonly preserveTrailingListContinuation?: boolean;
2457
+ readonly allowEmptyListItemInterrupts?: boolean;
2458
+ readonly requireListMarkerWhitespace?: boolean;
2459
+ readonly allowEmptyTaskItems?: boolean;
2460
+ }
2461
+
1555
2462
  /**
1556
2463
  * Parses markdown into a {@link DocumentAstNode}.
1557
2464
  *
@@ -1561,7 +2468,7 @@ declare class ListViewData {
1561
2468
  * blocks keep their incremental highlighting sessions.
1562
2469
  */
1563
2470
  export declare class MarkdownParser {
1564
- parse(text: StringValue, previous?: DocumentAstNode, edit?: StringEdit): DocumentAstNode;
2471
+ parse(text: StringValue, previous?: DocumentAstNode, edit?: StringEdit, options?: MarkdownParseOptions): DocumentAstNode;
1565
2472
  }
1566
2473
 
1567
2474
  /** A semantic syntax marker (heading `#`, fences, brackets, list bullet, …). */
@@ -1658,8 +2565,8 @@ export declare class MeasuredLayoutDebugRendering {
1658
2565
  * Exposes two DOM nodes the caller can place independently:
1659
2566
  *
1660
2567
  * - {@link overlayElement} — absolutely positioned; the caller mounts it
1661
- * inside the editor element so dashed line-bands and run-boxes line up
1662
- * with the editor's client coordinates.
2568
+ * inside the editor overlay container so dashed line-bands and run-boxes
2569
+ * share the measured editor-local coordinates.
1663
2570
  * - {@link infoElement} — block-flow; the caller mounts it as a sibling
1664
2571
  * *below* the editor. Contains the per-block summary table that used
1665
2572
  * to live on the overlay.
@@ -1670,7 +2577,6 @@ export declare class MeasuredLayoutDebugRendering {
1670
2577
  * the derived subscribed.
1671
2578
  */
1672
2579
  export declare class MeasuredLayoutDebugView extends Disposable {
1673
- private readonly _overlayParent;
1674
2580
  readonly overlayElement: HTMLElement;
1675
2581
  readonly infoElement: HTMLElement;
1676
2582
  readonly rendering: IObservable<MeasuredLayoutDebugRendering>;
@@ -1683,6 +2589,7 @@ export declare class MeasuredLayoutDebugView extends Disposable {
1683
2589
 
1684
2590
  export declare interface MeasuredLayoutDebugViewOptions {
1685
2591
  readonly model: MeasuredLayoutModel;
2592
+ readonly coordinateSpace: EditorCoordinateSpace;
1686
2593
  /**
1687
2594
  * DEBUG ONLY. Maps an absolute source offset to a fill color for that
1688
2595
  * character's glyph rect. The fixture passes the same function to the
@@ -1715,14 +2622,16 @@ export declare interface MeasuredLayoutDebugViewOptions {
1715
2622
  * through this model and never touches view fields directly.
1716
2623
  */
1717
2624
  export declare class MeasuredLayoutModel {
1718
- readonly measurements: ISettableObservable<readonly BlockMeasurement[], void>;
2625
+ private readonly _measurements;
2626
+ readonly measurements: IObservable<readonly BlockMeasurement[]>;
2627
+ private readonly _virtualLines;
1719
2628
  /**
1720
- * Concatenated visual line map across all mounted blocks. Lines are
1721
- * left in DOM (client-coordinate) y order — each per-block map already
1722
- * uses absolute client coordinates from `getClientRects()`, so the
1723
- * concatenation is well-formed without re-sorting.
2629
+ * Concatenated visual line map across all mounted blocks. Every per-block
2630
+ * map uses the same editor-local coordinate space, so concatenation is
2631
+ * well-formed without translation or re-sorting.
1724
2632
  */
1725
2633
  readonly visualLineMap: IObservableWithChange<VisualLineMap, void>;
2634
+ setMeasurements(measurements: readonly BlockMeasurement[], virtualLines: readonly VirtualLineMeasurement[]): void;
1726
2635
  }
1727
2636
 
1728
2637
  /**
@@ -1751,6 +2660,15 @@ export declare class MonacoSyntaxHighlighter implements ISyntaxHighlighter {
1751
2660
  private _tokenizerFor;
1752
2661
  }
1753
2662
 
2663
+ export declare const moveLinesDown: EditCommand;
2664
+
2665
+ export declare const moveLinesUp: EditCommand;
2666
+
2667
+ export declare interface NativeClipboardData {
2668
+ readonly text: string;
2669
+ readonly files: readonly File[];
2670
+ }
2671
+
1754
2672
  /**
1755
2673
  * Default strategy: handle the browser's native `copy`/`cut`/`paste` events,
1756
2674
  * reading and writing the synchronous {@link ClipboardEvent.clipboardData}.
@@ -1772,13 +2690,15 @@ declare interface NestedItem {
1772
2690
  }
1773
2691
 
1774
2692
  /**
1775
- * Move the cursor one position left or right, skipping over hidden marker
2693
+ * Move the cursor one position left or right, skipping over hidden source
1776
2694
  * ranges in inactive blocks (and inactive items of an active list).
1777
2695
  */
1778
- export declare function nextCursorPosition(doc: DocumentAstNode, activeBlock: BlockAstNode | undefined, cursor: number, direction: 'left' | 'right'): number;
2696
+ export declare function nextCursorPosition(doc: DocumentAstNode, markerVisibleBlocks: ReadonlySet<BlockAstNode>, cursor: number, direction: 'left' | 'right', selectionRange?: OffsetRange): number;
1779
2697
 
1780
2698
  declare const NO_ACTIVE_BLOCKS: unique symbol;
1781
2699
 
2700
+ export declare function normalizeCursorPosition(doc: DocumentAstNode, markerVisibleBlocks: ReadonlySet<BlockAstNode>, cursor: number, target: number, direction: 'left' | 'right', includeHiddenRangeBoundary?: boolean, selectionRange?: OffsetRange): number;
2701
+
1782
2702
  export declare class OffsetRange {
1783
2703
  readonly start: number;
1784
2704
  readonly endExclusive: number;
@@ -1806,11 +2726,19 @@ export declare class OffsetRange {
1806
2726
  toString(): string;
1807
2727
  }
1808
2728
 
2729
+ /** The lossless source slices of a block HTML comment whose closer has not been typed. */
2730
+ declare interface OpenHtmlCommentSource extends HtmlCommentSourceBase {
2731
+ readonly kind: 'open';
2732
+ }
2733
+
2734
+ /** Outdent the current line, or every line touched by the selection. */
2735
+ export declare function outdent(config?: IndentationConfig): EditCommand;
2736
+
1809
2737
  export declare class ParagraphAstNode extends BlockAstNodeBase {
1810
- readonly content: readonly (InlineAstNode | GlueAstNode)[];
2738
+ readonly content: readonly InlineContentAstNode[];
1811
2739
  readonly leadingTrivia?: GlueAstNode | undefined;
1812
2740
  readonly kind = "paragraph";
1813
- constructor(content: readonly (InlineAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
2741
+ constructor(content: readonly InlineContentAstNode[], leadingTrivia?: GlueAstNode | undefined);
1814
2742
  get children(): readonly AstNode[];
1815
2743
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1816
2744
  withLeadingTrivia(trivia: GlueAstNode | undefined): ParagraphAstNode;
@@ -1824,23 +2752,32 @@ declare class ParagraphViewData {
1824
2752
  }
1825
2753
 
1826
2754
  /**
1827
- * A *transient* editing state: the empty paragraph the user conjured by
1828
- * pressing Enter at the end of a paragraph. Markdown has no empty-paragraph
1829
- * node, so this never lives in {@link EditorModel.sourceText} or the parsed
1830
- * {@link EditorModel.document} — it is pure edit intent that the view renders
1831
- * as a synthetic blank line and that the controller either *materializes* (the
1832
- * user types) or *cancels* (the user navigates away / backspaces).
2755
+ * A *transient* editing state: an empty paragraph adjacent to a real block.
2756
+ * Markdown has no empty-paragraph node, so this never lives in
2757
+ * {@link EditorModel['sourceText']} or the parsed {@link EditorModel.document}
2758
+ * — it is pure edit intent that the view renders as a synthetic blank line and
2759
+ * that the controller either *materializes* (the user types) or *cancels* (the
2760
+ * user navigates away / backspaces).
1833
2761
  */
1834
2762
  declare interface PendingParagraph {
1835
- /** The paragraph the blank line is rendered directly after. */
2763
+ /** The block the blank line is rendered directly after. */
1836
2764
  readonly anchorBlock: BlockAstNode;
1837
2765
  /**
1838
2766
  * Source region rewritten when the pending paragraph is materialized — the
1839
2767
  * gap between {@link anchorBlock}'s text and whatever follows it.
1840
2768
  */
1841
2769
  readonly replaceRange: OffsetRange;
2770
+ /** Whether materialized text needs a blank-line separator before it. */
2771
+ readonly separateFromPreviousBlock: boolean;
1842
2772
  /** Whether {@link replaceRange} ends at the end of the document. */
1843
2773
  readonly atEof: boolean;
2774
+ /**
2775
+ * Horizontal whitespace typed on the source-less line. It remains transient
2776
+ * until other input materializes the paragraph. Contains only spaces and tabs.
2777
+ */
2778
+ readonly text: string;
2779
+ /** The source-less visual line occupied by the pending caret. */
2780
+ readonly cursorLine: VirtualCursorLine;
1844
2781
  /**
1845
2782
  * A throwaway AST node that exists only to give the synthetic view child a
1846
2783
  * stable identity across render frames (the view pairs nodes by `ast.id`).
@@ -1849,21 +2786,51 @@ declare interface PendingParagraph {
1849
2786
  readonly syntheticAst: ParagraphAstNode;
1850
2787
  }
1851
2788
 
2789
+ declare interface PendingParagraphResult {
2790
+ readonly kind: 'pending';
2791
+ readonly anchorBlock: BlockAstNode;
2792
+ readonly replaceRange: OffsetRange;
2793
+ /** Whether materialized text needs a blank-line separator before it. */
2794
+ readonly separateFromPreviousBlock: boolean;
2795
+ readonly atEof: boolean;
2796
+ }
2797
+
1852
2798
  /**
1853
2799
  * View-data for the transient empty paragraph (see `PendingParagraph` in the
1854
- * model). It carries only the throwaway {@link ParagraphAstNode} that gives the
1855
- * rendered blank line a stable identity across frames; it has no content and is
1856
- * never measured or part of the selection geometry — the caret is positioned
1857
- * over it via a dedicated rect, not via the visual-line map.
2800
+ * model). It carries the throwaway {@link ParagraphAstNode} that gives the
2801
+ * rendered line a stable identity across frames, its anchor block, source-less
2802
+ * cursor line, and transient horizontal whitespace. It has no source content or
2803
+ * selection range.
1858
2804
  */
1859
2805
  declare class PendingParagraphViewData {
1860
2806
  readonly ast: ParagraphAstNode;
2807
+ readonly anchorBlock: BlockAstNode;
2808
+ readonly cursorLine: VirtualCursorLine;
2809
+ readonly text: string;
1861
2810
  readonly kind = "pendingParagraph";
1862
- constructor(ast: ParagraphAstNode);
2811
+ constructor(ast: ParagraphAstNode, anchorBlock: BlockAstNode, cursorLine: VirtualCursorLine, text: string);
2812
+ }
2813
+
2814
+ /**
2815
+ * The mounted transient empty paragraph: a `<p class="md-pending-paragraph">`
2816
+ * holding either a `<br>` or decorated transient horizontal whitespace. It is a
2817
+ * leaf view node with no inline source content; the document view publishes its
2818
+ * element geometry as a virtual visual line.
2819
+ */
2820
+ declare class PendingParagraphViewNode extends ViewNode {
2821
+ readonly element: HTMLElement;
2822
+ readonly anchorBlock: BlockAstNode;
2823
+ readonly cursorLine: VirtualCursorLine;
2824
+ private _text;
2825
+ constructor(view: PendingParagraphViewData);
2826
+ update(text: string): void;
2827
+ getCaretClientRect(): DOMRect;
1863
2828
  }
1864
2829
 
1865
2830
  /**
1866
- * Immutable point in 2D space, in CSS-pixel client coordinates.
2831
+ * Immutable point in a caller-defined 2D CSS-pixel coordinate space.
2832
+ * Coordinate-owning APIs must document whether values are viewport-client or
2833
+ * editor-local; values from different spaces must not be mixed.
1867
2834
  */
1868
2835
  export declare class Point2D {
1869
2836
  readonly x: number;
@@ -1873,9 +2840,25 @@ export declare class Point2D {
1873
2840
  translate(dx: number, dy: number): Point2D;
1874
2841
  }
1875
2842
 
2843
+ export declare const presentationPolicies: Readonly<Record<EditorPresentation, PresentationPolicy>>;
2844
+
2845
+ declare interface PresentationPolicy {
2846
+ readonly parseOptions: MarkdownParseOptions;
2847
+ readonly preserveSourceWhitespace: boolean;
2848
+ readonly useSourceLineBreaks: boolean;
2849
+ }
2850
+
2851
+ /**
2852
+ * Read native clipboard formats through an editable target. Electron can expose
2853
+ * file clipboard entries here that navigator.clipboard.read() omits. EditContext
2854
+ * roots themselves do not receive execCommand('paste') events.
2855
+ * Returns undefined when the host does not support native programmatic paste.
2856
+ */
2857
+ export declare function readNativeClipboard(focusTarget: HTMLElement, executePaste?: () => void): NativeClipboardData | undefined;
2858
+
1876
2859
  /**
1877
- * Immutable axis-aligned rectangle in 2D space, in CSS-pixel client
1878
- * coordinates. `x`/`y` is the top-left corner, growing right/down.
2860
+ * Immutable axis-aligned rectangle in a caller-defined 2D CSS-pixel coordinate
2861
+ * space. `x`/`y` is the top-left corner, growing right/down.
1879
2862
  *
1880
2863
  * Half-open in both dimensions: `right` and `bottom` are excluded.
1881
2864
  */
@@ -1908,6 +2891,89 @@ declare interface RemovedItem {
1908
2891
  readonly deletedLocal: readonly AnnotatedRange[];
1909
2892
  }
1910
2893
 
2894
+ export declare interface RenameAnchor {
2895
+ readonly left: number;
2896
+ readonly top: number;
2897
+ readonly height: number;
2898
+ }
2899
+
2900
+ export declare class RenameModel<TContext = undefined> {
2901
+ private readonly _options;
2902
+ readonly name: ISettableObservable<string, void>;
2903
+ private readonly _session;
2904
+ private readonly _pending;
2905
+ private readonly _failure;
2906
+ private _submission;
2907
+ private _disposed;
2908
+ readonly session: IObservable<RenameSession<TContext> | undefined>;
2909
+ readonly pending: IObservable<boolean>;
2910
+ readonly isOpen: IObservableWithChange<boolean, void>;
2911
+ readonly error: IObservableWithChange<Error | undefined, void>;
2912
+ readonly validationMessage: IObservableWithChange<string | undefined, void>;
2913
+ readonly canSubmit: IObservableWithChange<boolean, void>;
2914
+ private readonly _nameObserver;
2915
+ constructor(_options: RenameModelOptions<TContext>);
2916
+ open(session: RenameSession<TContext>): void;
2917
+ submit(): Promise<RenameSubmitResult>;
2918
+ cancel(): void;
2919
+ dispose(): void;
2920
+ private _close;
2921
+ private _abortSubmission;
2922
+ private _isCurrent;
2923
+ }
2924
+
2925
+ export declare interface RenameModelOptions<TContext = undefined> {
2926
+ readonly onSubmit: (request: RenameRequest<TContext>) => void | Promise<void>;
2927
+ readonly onCancel?: (session: RenameSession<TContext>) => void;
2928
+ readonly validate?: (name: string, session: RenameSession<TContext>) => string | undefined;
2929
+ }
2930
+
2931
+ export declare interface RenameRequest<TContext = undefined> extends RenameSession<TContext> {
2932
+ readonly name: string;
2933
+ readonly signal: AbortSignal;
2934
+ }
2935
+
2936
+ export declare interface RenameSession<TContext = undefined> {
2937
+ readonly initialName: string;
2938
+ readonly context: TContext;
2939
+ }
2940
+
2941
+ export declare type RenameSubmitResult = {
2942
+ readonly kind: 'submitted';
2943
+ readonly name: string;
2944
+ } | {
2945
+ readonly kind: 'invalid';
2946
+ readonly message: string;
2947
+ } | {
2948
+ readonly kind: 'error';
2949
+ readonly error: Error;
2950
+ } | {
2951
+ readonly kind: 'closed' | 'pending' | 'cancelled' | 'superseded';
2952
+ };
2953
+
2954
+ export declare class RenameWidget<TContext = undefined> extends Disposable {
2955
+ private readonly _container;
2956
+ private readonly _model;
2957
+ private readonly _options;
2958
+ readonly element: HTMLDivElement;
2959
+ readonly inputElement: HTMLInputElement;
2960
+ private readonly _message;
2961
+ private _anchor;
2962
+ private _focusedSession;
2963
+ constructor(_container: HTMLElement, _model: RenameModel<TContext>, _options?: RenameWidgetOptions);
2964
+ focusAndSelect(): void;
2965
+ /** Anchor coordinates are relative to the positioned container's padding box. */
2966
+ layout(anchor?: RenameAnchor): void;
2967
+ }
2968
+
2969
+ export declare interface RenameWidgetOptions {
2970
+ readonly autoFocus?: boolean;
2971
+ /** Called when a focused widget closes; the host can restore editor focus. */
2972
+ readonly onDidHide?: () => void;
2973
+ }
2974
+
2975
+ export declare type RenderMarkupText = 'none' | 'selection' | 'all';
2976
+
1911
2977
  declare interface ReplacedItem {
1912
2978
  readonly kind: 'replaced';
1913
2979
  readonly original: AstNode;
@@ -1918,6 +2984,39 @@ declare interface ReplacedItem {
1918
2984
  readonly deletedLocal: readonly AnnotatedRange[];
1919
2985
  }
1920
2986
 
2987
+ export declare class RichLink {
2988
+ private readonly _displayHints?;
2989
+ static create(options: RichLinkOptions): RichLink;
2990
+ static mount(element: HTMLElement, authoredLabel: HTMLSpanElement, displayHints?: RichLinkDisplayHints): RichLink;
2991
+ static clear(element: HTMLElement): void;
2992
+ readonly element: HTMLElement;
2993
+ readonly authoredLabel: HTMLSpanElement;
2994
+ private readonly _icon;
2995
+ private readonly _title;
2996
+ private readonly _detail;
2997
+ private readonly _reference;
2998
+ private readonly _changes;
2999
+ private readonly _status;
3000
+ private readonly _secondaryStatus;
3001
+ private constructor();
3002
+ update(presentation: LinkPresentation | undefined): void;
3003
+ private _renderUnavailable;
3004
+ private _layout;
3005
+ private _setDefaultOrder;
3006
+ }
3007
+
3008
+ declare interface RichLinkDisplayHints {
3009
+ readonly iconOnly?: boolean;
3010
+ readonly maxWidthChars?: number;
3011
+ }
3012
+
3013
+ export declare interface RichLinkOptions {
3014
+ readonly href: string;
3015
+ readonly authoredLabel: string;
3016
+ readonly presentation?: LinkPresentation;
3017
+ readonly displayHints?: RichLinkDisplayHints;
3018
+ }
3019
+
1921
3020
  export declare const selectAll: SelectionCommand;
1922
3021
 
1923
3022
  export declare function selectBlock(ctx: CursorCommandContext, blockRange: OffsetRange): Selection_2;
@@ -1925,13 +3024,14 @@ export declare function selectBlock(ctx: CursorCommandContext, blockRange: Offse
1925
3024
  declare class Selection_2 {
1926
3025
  readonly anchor: SourceOffset;
1927
3026
  readonly active: SourceOffset;
1928
- static collapsed(offset: SourceOffset): Selection_2;
1929
- constructor(anchor: SourceOffset, active: SourceOffset);
3027
+ static collapsed(offset: SourceOffset, affinity?: SourceCursorPosition['affinity']): Selection_2;
3028
+ readonly activeAffinity?: SourceCursorPosition['affinity'];
3029
+ constructor(anchor: SourceOffset, active: SourceOffset, activeAffinity?: SourceCursorPosition['affinity']);
1930
3030
  get isCollapsed(): boolean;
1931
3031
  get isForward(): boolean;
1932
3032
  get range(): OffsetRange;
1933
3033
  collapseToActive(): Selection_2;
1934
- withActive(active: SourceOffset): Selection_2;
3034
+ withActive(active: SourceOffset, affinity?: SourceCursorPosition['affinity']): Selection_2;
1935
3035
  }
1936
3036
  export { Selection_2 as Selection }
1937
3037
 
@@ -1943,8 +3043,13 @@ export { Selection_2 as Selection }
1943
3043
  export declare interface SelectionBlock {
1944
3044
  readonly block: BlockAstNode;
1945
3045
  readonly absoluteStart: number;
1946
- readonly viewNode: ViewNode;
1947
- readonly element: HTMLElement;
3046
+ /** Block border box in editor-local coordinates. */
3047
+ readonly rect: Rect2D;
3048
+ /** Visible horizontal padding-box bounds for a scrolling block. */
3049
+ readonly viewportClip: {
3050
+ readonly left: number;
3051
+ readonly right: number;
3052
+ } | undefined;
1948
3053
  }
1949
3054
 
1950
3055
  export declare type SelectionCommand = (ctx: CursorCommandContext, offset: SourceOffset) => Selection_2;
@@ -1956,6 +3061,9 @@ export declare interface SelectionRect {
1956
3061
  readonly height: number;
1957
3062
  }
1958
3063
 
3064
+ /** The interaction that produced the current editor selection. */
3065
+ export declare type SelectionSource = 'user' | 'find';
3066
+
1959
3067
  /**
1960
3068
  * Owns the SVG overlay that paints the selection.
1961
3069
  *
@@ -1976,11 +3084,10 @@ export declare interface SelectionRect {
1976
3084
  * envelope shape used by IDE selection rendering.
1977
3085
  */
1978
3086
  export declare class SelectionView extends Disposable {
1979
- private readonly _parent;
1980
3087
  readonly element: SVGSVGElement;
1981
3088
  readonly rendering: IObservable<SelectionViewRendering>;
1982
3089
  private readonly _path;
1983
- constructor(_parent: HTMLElement, options: SelectionViewOptions);
3090
+ constructor(options: SelectionViewOptions);
1984
3091
  }
1985
3092
 
1986
3093
  export declare interface SelectionViewOptions {
@@ -2008,12 +3115,9 @@ export declare type SmartEnterResult = {
2008
3115
  readonly kind: 'edit';
2009
3116
  readonly edit: StringEdit;
2010
3117
  readonly selection: Selection_2;
2011
- } | {
2012
- readonly kind: 'pending';
2013
- readonly anchorBlock: BlockAstNode;
2014
- readonly replaceRange: OffsetRange;
2015
- readonly atEof: boolean;
2016
- };
3118
+ /** Post-edit range of indentation copied onto a new fenced-code line. */
3119
+ readonly generatedIndentation?: OffsetRange;
3120
+ } | PendingParagraphResult;
2017
3121
 
2018
3122
  /**
2019
3123
  * A run of {@link Token}s together with the exact {@link OffsetRange} they
@@ -2028,34 +3132,29 @@ export declare interface SnapshotTokens {
2028
3132
  readonly tokens: readonly Token[];
2029
3133
  }
2030
3134
 
2031
- export declare type SourceOffset = number;
2032
-
2033
- export declare abstract class StackedCommentsPresenter extends Disposable implements ICommentsPresenter {
2034
- protected readonly model: CommentsModel;
2035
- protected readonly view: EditorView;
2036
- protected readonly context?: CommentsPresenterContext | undefined;
2037
- private readonly _layer;
2038
- private readonly _entries;
2039
- private _order;
2040
- constructor(model: CommentsModel, view: EditorView, context?: CommentsPresenterContext | undefined);
2041
- /** Build the card DOM for a comment. Called once per new comment. */
2042
- protected abstract createWidget(comment: Comment_2): StackWidget;
2043
- private _reconcile;
2044
- private _relayout;
3135
+ declare interface SourceCursorPosition {
3136
+ readonly kind: 'source';
3137
+ readonly offset: SourceOffset;
3138
+ /** Prefer the preceding visual line at a shared soft-wrap boundary. */
3139
+ readonly affinity?: 'upstream';
2045
3140
  }
2046
3141
 
2047
- /** The minimal widget contract a subclass must produce. */
2048
- export declare interface StackWidget {
2049
- readonly element: HTMLElement;
2050
- dispose(): void;
3142
+ /** Metadata delivered synchronously immediately before a model-owned source edit is applied. */
3143
+ export declare interface SourceEditEvent {
3144
+ readonly baseSourceTextId: number;
3145
+ readonly resultSourceTextId: number;
3146
+ readonly edit: StringEdit;
3147
+ readonly transaction: ITransaction;
2051
3148
  }
2052
3149
 
3150
+ export declare type SourceOffset = number;
3151
+
2053
3152
  export declare class StrikethroughAstNode extends AstNode {
2054
3153
  readonly openMarker: MarkerAstNode;
2055
- readonly content: readonly (InlineAstNode | GlueAstNode)[];
3154
+ readonly content: readonly InlineContentAstNode[];
2056
3155
  readonly closeMarker: MarkerAstNode;
2057
3156
  readonly kind = "strikethrough";
2058
- constructor(openMarker: MarkerAstNode, content: readonly (InlineAstNode | GlueAstNode)[], closeMarker: MarkerAstNode);
3157
+ constructor(openMarker: MarkerAstNode, content: readonly InlineContentAstNode[], closeMarker: MarkerAstNode);
2059
3158
  get children(): readonly AstNode[];
2060
3159
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
2061
3160
  }
@@ -2092,6 +3191,11 @@ export declare class StringReplacement {
2092
3191
  constructor(replaceRange: OffsetRange, newText: string);
2093
3192
  get isEmpty(): boolean;
2094
3193
  equals(other: StringReplacement): boolean;
3194
+ /**
3195
+ * Narrows this replacement to the span that actually changes, by trimming
3196
+ * the prefix and suffix it shares with the text it replaces in `source`.
3197
+ */
3198
+ removeCommonSuffixPrefix(source: string): StringReplacement;
2095
3199
  toString(): string;
2096
3200
  }
2097
3201
 
@@ -2105,10 +3209,10 @@ export declare class StringValue {
2105
3209
 
2106
3210
  export declare class StrongAstNode extends AstNode {
2107
3211
  readonly openMarker: MarkerAstNode;
2108
- readonly content: readonly (InlineAstNode | GlueAstNode)[];
3212
+ readonly content: readonly InlineContentAstNode[];
2109
3213
  readonly closeMarker: MarkerAstNode;
2110
3214
  readonly kind = "strong";
2111
- constructor(openMarker: MarkerAstNode, content: readonly (InlineAstNode | GlueAstNode)[], closeMarker: MarkerAstNode);
3215
+ constructor(openMarker: MarkerAstNode, content: readonly InlineContentAstNode[], closeMarker: MarkerAstNode);
2112
3216
  get children(): readonly AstNode[];
2113
3217
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
2114
3218
  }
@@ -2120,6 +3224,85 @@ declare class StrongViewData {
2120
3224
  constructor(ast: StrongAstNode, content: readonly AnyViewData[]);
2121
3225
  }
2122
3226
 
3227
+ export declare type SuggestAcceptance = 'enter' | 'tab' | 'pointer';
3228
+
3229
+ export declare interface SuggestCallbacks<T extends SuggestItem> {
3230
+ readonly onAccept: (item: T, source: SuggestAcceptance) => void;
3231
+ readonly onCancel?: () => void;
3232
+ readonly onSelect?: (item: T | undefined) => void;
3233
+ }
3234
+
3235
+ export declare interface SuggestItem {
3236
+ readonly id: string;
3237
+ readonly label: string;
3238
+ readonly detail?: string;
3239
+ readonly type?: string;
3240
+ readonly highlightLength?: number;
3241
+ }
3242
+
3243
+ export declare class SuggestModel<T extends SuggestItem = SuggestItem> {
3244
+ private readonly _callbacks;
3245
+ private readonly _state;
3246
+ readonly state: IObservable<SuggestState<T>>;
3247
+ readonly selectedItem: IObservableWithChange<T | undefined, void>;
3248
+ constructor(_callbacks: SuggestCallbacks<T>);
3249
+ show(items: readonly T[], selectedId?: string | undefined): void;
3250
+ showLoading(): void;
3251
+ showError(message: string): void;
3252
+ close(): void;
3253
+ select(id: string): boolean;
3254
+ navigate(direction: SuggestNavigation, pageSize?: number): boolean;
3255
+ accept(source?: SuggestAcceptance): boolean;
3256
+ cancel(): boolean;
3257
+ private _update;
3258
+ }
3259
+
3260
+ export declare type SuggestNavigation = 'next' | 'previous' | 'first' | 'last' | 'nextPage' | 'previousPage';
3261
+
3262
+ export declare type SuggestState<T extends SuggestItem = SuggestItem> = {
3263
+ readonly kind: 'closed';
3264
+ } | {
3265
+ readonly kind: 'loading';
3266
+ } | {
3267
+ readonly kind: 'empty';
3268
+ } | {
3269
+ readonly kind: 'error';
3270
+ readonly message: string;
3271
+ } | {
3272
+ readonly kind: 'ready';
3273
+ readonly items: readonly T[];
3274
+ readonly selectedIndex: number;
3275
+ };
3276
+
3277
+ export declare class SuggestWidget<T extends SuggestItem = SuggestItem> extends Disposable {
3278
+ private readonly _options;
3279
+ readonly element: HTMLDivElement;
3280
+ readonly listElement: HTMLDivElement;
3281
+ private readonly _message;
3282
+ private readonly _savedAttributes;
3283
+ private _items;
3284
+ private _disposed;
3285
+ private _pendingReveal;
3286
+ constructor(_options: SuggestWidgetOptions<T>);
3287
+ handleKeyDown(event: KeyboardEvent): boolean;
3288
+ dispose(): void;
3289
+ private _rowFromEvent;
3290
+ private _render;
3291
+ private _revealSelection;
3292
+ private _createRow;
3293
+ private _restoreAttributes;
3294
+ }
3295
+
3296
+ export declare interface SuggestWidgetOptions<T extends SuggestItem> {
3297
+ readonly model: SuggestModel<T>;
3298
+ readonly focusTarget: HTMLElement;
3299
+ readonly id: string;
3300
+ readonly label?: string;
3301
+ readonly listenForKeyboard?: boolean;
3302
+ }
3303
+
3304
+ export declare type TabKeyboardAction = 'insert' | 'outdent';
3305
+
2123
3306
  export declare class TableAstNode extends BlockAstNodeBase {
2124
3307
  readonly content: readonly (TableRowAstNode | GlueAstNode)[];
2125
3308
  readonly leadingTrivia?: GlueAstNode | undefined;
@@ -2182,10 +3365,10 @@ declare class TableViewData {
2182
3365
  }
2183
3366
 
2184
3367
  /**
2185
- * Source range (relative to `item`) of a task list item's `[x]`/`[ ]`
3368
+ * Source range (relative to `item`) of a task list item's `[x]`/`[ ]`/`[]`
2186
3369
  * checkbox, or `undefined` when the item is not a task item. The checkbox is
2187
3370
  * plain glue in the AST, so a host that wants to toggle it locates the literal
2188
- * `[x]`/`[ ]` token here.
3371
+ * checkbox token here.
2189
3372
  */
2190
3373
  export declare function taskCheckboxRange(item: ListItemAstNode): OffsetRange | undefined;
2191
3374
 
@@ -2202,6 +3385,14 @@ declare class TextViewData {
2202
3385
  readonly showWhitespace: boolean;
2203
3386
  readonly leftWordBoundary: boolean;
2204
3387
  readonly rightWordBoundary: boolean;
3388
+ /**
3389
+ * Number of leading source characters to keep out of the rendered
3390
+ * text (but not out of the source): the `:running:` marker plus its
3391
+ * mandatory leading separator, once
3392
+ * {@link isRunnerMarkerText} has matched this node. Zero otherwise.
3393
+ */
3394
+ readonly hiddenPrefixLength: number;
3395
+ readonly taskLabel: boolean;
2205
3396
  readonly kind = "text";
2206
3397
  /**
2207
3398
  * Whether non-obvious whitespace in this text is revealed (block is active).
@@ -2210,7 +3401,14 @@ declare class TextViewData {
2210
3401
  * emphasis); a single space touching such a sibling is obvious and stays
2211
3402
  * undecorated, just like a space between two words within this leaf.
2212
3403
  */
2213
- constructor(ast: TextAstNode, showWhitespace: boolean, leftWordBoundary?: boolean, rightWordBoundary?: boolean);
3404
+ constructor(ast: TextAstNode, showWhitespace: boolean, leftWordBoundary?: boolean, rightWordBoundary?: boolean,
3405
+ /**
3406
+ * Number of leading source characters to keep out of the rendered
3407
+ * text (but not out of the source): the `:running:` marker plus its
3408
+ * mandatory leading separator, once
3409
+ * {@link isRunnerMarkerText} has matched this node. Zero otherwise.
3410
+ */
3411
+ hiddenPrefixLength?: number, taskLabel?: boolean);
2214
3412
  }
2215
3413
 
2216
3414
  export declare class ThematicBreakAstNode extends BlockAstNodeBase {
@@ -2261,6 +3459,91 @@ declare interface UnchangedItem {
2261
3459
  readonly modifiedStart: number;
2262
3460
  }
2263
3461
 
3462
+ /**
3463
+ * A block whose token type the parser does not understand (a setext heading or
3464
+ * any future/extension construct). Rather than dropping the
3465
+ * span — which would demote its text to invisible glue — the parser captures the
3466
+ * whole source range verbatim as a single {@link MarkerAstNode} of kind
3467
+ * `content` and records the originating micromark {@link tokenType}, so the view
3468
+ * can render it as raw, editable text with an "unhandled" affordance. Offsets
3469
+ * stay sound: `content` tiles the block's full source span exactly.
3470
+ */
3471
+ declare class UnhandledBlockAstNode extends BlockAstNodeBase {
3472
+ readonly tokenType: string;
3473
+ readonly content: readonly (MarkerAstNode | GlueAstNode)[];
3474
+ readonly leadingTrivia?: GlueAstNode | undefined;
3475
+ readonly kind = "unhandledBlock";
3476
+ constructor(tokenType: string, content: readonly (MarkerAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
3477
+ get children(): readonly AstNode[];
3478
+ get code(): MarkerAstNode | undefined;
3479
+ /**
3480
+ * Lossless slices when this raw HTML block starts one comment after optional
3481
+ * whitespace. An open comment consumes the remaining source as its body. A
3482
+ * complete comment permits only trailing whitespace after its closer.
3483
+ */
3484
+ get htmlComment(): HtmlCommentSource | undefined;
3485
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
3486
+ withLeadingTrivia(trivia: GlueAstNode | undefined): UnhandledBlockAstNode;
3487
+ protected _localEquals(o: this): boolean;
3488
+ }
3489
+
3490
+ /**
3491
+ * View-data for an {@link UnhandledBlockAstNode}. The source remains verbatim
3492
+ * in both states. Complete HTML comments use {@link showMarkup} to switch
3493
+ * between their quiet reading treatment and editable source presentation;
3494
+ * other unhandled blocks ignore the flag and keep their warning treatment.
3495
+ */
3496
+ declare class UnhandledBlockViewData {
3497
+ readonly ast: UnhandledBlockAstNode;
3498
+ readonly showMarkup: boolean;
3499
+ readonly content: readonly AnyViewData[];
3500
+ readonly kind = "unhandledBlock";
3501
+ constructor(ast: UnhandledBlockAstNode, showMarkup: boolean, content: readonly AnyViewData[]);
3502
+ }
3503
+
3504
+ /**
3505
+ * A standalone HTML `<video>` whose source can be rendered without executing
3506
+ * arbitrary raw HTML. Its exact HTML remains in `content`, so activating the
3507
+ * block restores the original source for editing.
3508
+ */
3509
+ export declare class VideoAstNode extends BlockAstNodeBase {
3510
+ readonly attributes: VideoAttributes;
3511
+ readonly content: readonly (MarkerAstNode | GlueAstNode)[];
3512
+ readonly leadingTrivia?: GlueAstNode | undefined;
3513
+ readonly kind = "video";
3514
+ constructor(attributes: VideoAttributes, content: readonly (MarkerAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
3515
+ get children(): readonly AstNode[];
3516
+ get source(): MarkerAstNode | undefined;
3517
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
3518
+ withLeadingTrivia(trivia: GlueAstNode | undefined): VideoAstNode;
3519
+ protected _localEquals(o: this): boolean;
3520
+ }
3521
+
3522
+ /** The supported semantic attributes of a standalone HTML `<video>` block. */
3523
+ export declare interface VideoAttributes {
3524
+ readonly src: string;
3525
+ readonly title?: string;
3526
+ readonly autoplay: boolean;
3527
+ readonly controls: boolean;
3528
+ readonly loop: boolean;
3529
+ readonly muted: boolean;
3530
+ }
3531
+
3532
+ declare class VideoViewData {
3533
+ readonly ast: VideoAstNode;
3534
+ /** Active: reveal the exact HTML source; inactive: render the native video. */
3535
+ readonly showMarkup: boolean;
3536
+ readonly content: readonly AnyViewData[];
3537
+ /** Nested diff state; top-level video diff state lives on the document child. */
3538
+ readonly diffKind?: "added" | "modified" | undefined;
3539
+ readonly kind = "video";
3540
+ constructor(ast: VideoAstNode,
3541
+ /** Active: reveal the exact HTML source; inactive: render the native video. */
3542
+ showMarkup: boolean, content: readonly AnyViewData[],
3543
+ /** Nested diff state; top-level video diff state lives on the document child. */
3544
+ diffKind?: "added" | "modified" | undefined);
3545
+ }
3546
+
2264
3547
  /**
2265
3548
  * Immutable view of an AST node. Pairs `ast` with its rendered `dom` and a
2266
3549
  * mirror of `ast.children` as ViewNode children. Source offsets are NEVER
@@ -2352,6 +3635,24 @@ export declare class ViewNode extends Disposable {
2352
3635
  forEachTextLeaf(nodeOffset: number, visitor: (leaf: ViewNode, leafOffset: number) => void): void;
2353
3636
  }
2354
3637
 
3638
+ /**
3639
+ * A visual cursor line that has no representation in the source text.
3640
+ *
3641
+ * The two source offsets are the positions immediately before and after the
3642
+ * virtual line. The object itself is the stable identity of the line.
3643
+ */
3644
+ export declare class VirtualCursorLine {
3645
+ readonly sourceOffsetBefore: SourceOffset;
3646
+ readonly sourceOffsetAfter: SourceOffset;
3647
+ constructor(sourceOffsetBefore: SourceOffset, sourceOffsetAfter: SourceOffset);
3648
+ }
3649
+
3650
+ /** A measured source-less line inserted directly after a source block. */
3651
+ declare interface VirtualLineMeasurement {
3652
+ readonly afterBlock: BlockAstNode;
3653
+ readonly line: VisualLine;
3654
+ }
3655
+
2355
3656
  export declare type VisualCursorCommand = (ctx: VisualCursorCommandContext) => CursorMoveResult;
2356
3657
 
2357
3658
  export declare interface VisualCursorCommandContext extends CursorCommandContext {
@@ -2369,12 +3670,15 @@ export declare function visualizeAst(root: AstNode, source: string): AstVisualiz
2369
3670
  export declare class VisualLine {
2370
3671
  readonly rect: Rect2D;
2371
3672
  readonly runs: readonly VisualRun[];
2372
- constructor(rect: Rect2D, runs: readonly VisualRun[]);
3673
+ readonly virtualCursorLine?: VirtualCursorLine | undefined;
3674
+ static virtual(cursorLine: VirtualCursorLine, rect: Rect2D): VisualLine;
3675
+ constructor(rect: Rect2D, runs: readonly VisualRun[], virtualCursorLine?: VirtualCursorLine | undefined);
2373
3676
  containsOffset(offset: SourceOffset): boolean;
2374
3677
  /**
2375
3678
  * How `offset` relates to this line's runs:
2376
3679
  * - `'covers'`: a run starts at or strictly contains the offset
2377
- * (`start <= offset < endExclusive`) — the caret belongs on this line.
3680
+ * (`start <= offset < endExclusive`), or a zero-length visual-line
3681
+ * anchor sits at the offset — the caret belongs on this line.
2378
3682
  * - `'end'`: the offset is only some run's trailing boundary
2379
3683
  * (`offset === endExclusive`) with no run covering it — a line-break
2380
3684
  * boundary the caret should leave for the next line.
@@ -2387,10 +3691,27 @@ export declare class VisualLine {
2387
3691
  */
2388
3692
  sourceDistanceTo(offset: SourceOffset): number;
2389
3693
  /**
2390
- * x of the caret position before `offset` on this line. When `offset`
2391
- * is past all runs (trailing whitespace / blank line), returns the
2392
- * right edge of the last run; when before all runs, returns the left
2393
- * edge of the first run.
3694
+ * x of the caret position before `offset` on this line.
3695
+ *
3696
+ * The runs tile the source but are stored in paint order, not sorted by
3697
+ * source offset (hidden-marker runs are appended last). So this scans all
3698
+ * runs rather than assuming any ordering:
3699
+ *
3700
+ * - A zero-source visual anchor owns its exact offset, so a marker-only line
3701
+ * wins over the preceding line's inclusive end boundary.
3702
+ * - Otherwise a run starting at `offset` owns that seam. This keeps an
3703
+ * out-of-flow prefix from placing the caret at its trailing edge when the
3704
+ * following body starts at a visually separate x.
3705
+ * - Otherwise, if some run *covers* `offset`, its own geometry places the
3706
+ * caret (exact glyph boundary for text runs). In the active,
3707
+ * markers-visible form every interior offset is covered, so this branch
3708
+ * keeps distinct offsets distinct.
3709
+ * - Otherwise `offset` sits in a gap — a hidden inline marker such as the
3710
+ * `**` of `**bold**`, or before/after the painted text. It snaps to the
3711
+ * seam between the source-nearest runs on either side: the right edge of
3712
+ * the closest run ending at/before `offset`, else the left edge of the
3713
+ * closest run starting at/after it. A hidden marker collapses to zero
3714
+ * width, so both edges coincide at the seam.
2394
3715
  */
2395
3716
  xAtOffset(offset: SourceOffset): number;
2396
3717
  /**
@@ -2404,7 +3725,8 @@ export declare class VisualLine {
2404
3725
 
2405
3726
  /**
2406
3727
  * Geometry of the rendered document, as a map from source offsets to 2D
2407
- * positions and back.
3728
+ * positions and back. All geometry is expressed in the editor overlay's local
3729
+ * CSS-pixel coordinate space.
2408
3730
  *
2409
3731
  * Structure (top to bottom):
2410
3732
  *
@@ -2439,7 +3761,9 @@ export declare class VisualLineMap {
2439
3761
  static measure(blockViews: readonly {
2440
3762
  readonly absoluteStart: number;
2441
3763
  readonly viewNode: ViewNode;
2442
- }[]): VisualLineMap;
3764
+ }[], coordinateSpace: EditorCoordinateSpace, transform?: EditorCoordinateTransform): VisualLineMap;
3765
+ /** Lines backed by source ranges, excluding source-less cursor lines. */
3766
+ readonly sourceLines: readonly VisualLine[];
2443
3767
  constructor(lines: readonly VisualLine[]);
2444
3768
  get lineCount(): number;
2445
3769
  get isEmpty(): boolean;
@@ -2458,12 +3782,18 @@ export declare class VisualLineMap {
2458
3782
  * The first such trailing-boundary line is remembered as a fallback for the
2459
3783
  * document's very last offset, where no later line starts it.
2460
3784
  */
2461
- lineIndexOfOffset(offset: SourceOffset): number;
3785
+ lineIndexOfOffset(offset: SourceOffset, affinity?: SourceCursorPosition['affinity']): number;
2462
3786
  /**
2463
3787
  * x of the caret position before `offset`, on the line returned by
2464
3788
  * {@link lineIndexOfOffset}. Returns `0` when the map is empty.
2465
3789
  */
2466
3790
  xAtOffset(offset: SourceOffset): number;
3791
+ /**
3792
+ * Line occupied by a source or virtual cursor position. A virtual position
3793
+ * returns `undefined` until its corresponding DOM line has been measured.
3794
+ */
3795
+ lineIndexOfPosition(position: CursorPosition): number | undefined;
3796
+ xAtPosition(position: CursorPosition): number;
2467
3797
  /**
2468
3798
  * Line whose vertical band contains `y`, clamped to the first/last
2469
3799
  * line when `y` is outside the document.
@@ -2475,8 +3805,13 @@ export declare class VisualLineMap {
2475
3805
  * uses {@link offsetInLineAtX} directly to preserve desired column.
2476
3806
  */
2477
3807
  offsetAtPoint(point: Point2D): SourceOffset;
3808
+ positionAtPoint(point: Point2D): SourceCursorPosition;
3809
+ positionAtOffsetInLine(lineIndex: number, offset: SourceOffset): SourceCursorPosition;
2478
3810
  /** Snap `x` to the nearest offset on a specific line. */
2479
3811
  offsetInLineAtX(lineIndex: number, x: number): SourceOffset;
3812
+ positionInLineAtX(lineIndex: number, x: number): CursorPosition;
3813
+ lineStartOffset(lineIndex: number): SourceOffset | undefined;
3814
+ lineEndOffset(lineIndex: number): SourceOffset | undefined;
2480
3815
  }
2481
3816
 
2482
3817
  /**
@@ -2498,7 +3833,9 @@ export declare class VisualRun {
2498
3833
  readonly sourceRange: OffsetRange;
2499
3834
  readonly rect: Rect2D;
2500
3835
  readonly source?: VisualRunSource | undefined;
2501
- constructor(sourceRange: OffsetRange, rect: Rect2D, source?: VisualRunSource | undefined);
3836
+ readonly isVisualLineAnchor: boolean;
3837
+ static visualLineAnchor(sourceOffset: SourceOffset, rect: Rect2D): VisualRun;
3838
+ constructor(sourceRange: OffsetRange, rect: Rect2D, source?: VisualRunSource | undefined, isVisualLineAnchor?: boolean);
2502
3839
  get sourceStart(): SourceOffset;
2503
3840
  get sourceEndExclusive(): SourceOffset;
2504
3841
  get sourceLength(): number;
@@ -2524,14 +3861,18 @@ declare interface VisualRunSource {
2524
3861
  readonly textNode: Text;
2525
3862
  /** Offset within `textNode.data` corresponding to `sourceRange.start`. */
2526
3863
  readonly textNodeStart: number;
3864
+ readonly coordinateSpace: EditorCoordinateSpace;
2527
3865
  }
2528
3866
 
2529
- export declare class VscodeStackedCommentsView extends StackedCommentsPresenter {
2530
- protected createWidget(comment: Comment_2): StackWidget;
2531
- }
3867
+ export declare const vscodeHostKeyboardProfile: KeyboardProfile;
3868
+
3869
+ export declare const vscodeKeyboardProfile: KeyboardProfile;
3870
+
3871
+ export declare const vscodeLocalKeyboardProfile: KeyboardProfile;
2532
3872
 
2533
- export declare class VsCodeV2CommentsView extends StackedCommentsPresenter {
2534
- protected createWidget(comment: Comment_2): StackWidget;
3873
+ export declare interface WordNavigationConfig {
3874
+ readonly wordSeparators: string;
3875
+ readonly wordSegmenterLocales: readonly string[];
2535
3876
  }
2536
3877
 
2537
3878
  export { }