@vscode/markdown-editor 0.0.2-14 → 0.0.2-141

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 +663 -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 +1615 -270
  11. package/dist/index.js +7845 -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 +357 -0
  17. package/dist/web-editors.js +7597 -0
  18. package/dist/web-editors.js.map +1 -0
  19. package/package.json +60 -20
  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 +1702 -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,48 @@ 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;
952
+ /** Timestamp of the last locked-mode reveal caused by a pointer click. */
953
+ private _lastReadonlyClickRevealTime;
806
954
  constructor(_model: EditorModel, _view: EditorView, options?: EditorControllerOptions);
807
955
  private readonly _handleTextUpdate;
808
- private readonly _handleMouseDown;
956
+ insertText(text: string, selectionOverride?: Selection_2): void;
957
+ private _insertText;
958
+ private _remainingGeneratedIndentation;
959
+ /** Handle typed, pasted, or command-generated text while a paragraph is pending. */
960
+ private _handlePendingInput;
961
+ private _deletePendingText;
962
+ private readonly _handlePointerDown;
809
963
  private _makeCursorContext;
810
964
  private _makeVisualCursorContext;
811
965
  private _executeCursorCommand;
812
966
  private _executeEditCommand;
967
+ private _runUndoableEdit;
813
968
  private _executeVisualCursorCommand;
969
+ private _cursorDown;
970
+ private _setUserSelection;
971
+ private _applyCursorPosition;
814
972
  /** Move the cursor down one visual line (Arrow Down). */
815
973
  cursorDown(extend?: boolean): void;
816
974
  /** Move the cursor up one visual line (Arrow Up). */
@@ -818,12 +976,34 @@ export declare class EditorController extends Disposable {
818
976
  private _selectedText;
819
977
  private readonly _updateModifierState;
820
978
  private readonly _clearModifierState;
979
+ /**
980
+ * Drop any native DOM selection over the rendered text.
981
+ *
982
+ * The editor paints selection from `model.selection`, so a browser
983
+ * selection there is always spurious: nothing reads it (copy/cut read the
984
+ * model, hit-testing uses the measured layout) and nothing clears it, so it
985
+ * lingers as a second highlight even after the caret moves away.
986
+ * {@link isCaretMotionKey} stops the common source synchronously; this is
987
+ * the backstop for the rest of the browser's editing commands, which are
988
+ * platform- and version-specific and cannot be enumerated (Shift+PageDown
989
+ * and macOS Shift+Ctrl+B both reach one today).
990
+ *
991
+ * Scoped twice so it only ever discards selections the editor owns: the
992
+ * range must touch the rendered text (overlays such as comment widgets sit
993
+ * beside it and stay selectable), and input focus must still be inside this
994
+ * editor (so a host find-in-page, which selects while its own input is
995
+ * focused, is left alone).
996
+ */
997
+ private readonly _discardNativeSelection;
821
998
  private readonly _handleKeyDown;
999
+ executeCommand(command: EditorCommandDefinition): void;
1000
+ private _executeKeyboardAction;
822
1001
  /**
823
1002
  * Context-aware Enter: splits / line-breaks via {@link insertSmartEnter}, or
824
1003
  * arms a transient empty paragraph when at the end of a paragraph.
825
1004
  */
826
1005
  private _smartEnter;
1006
+ private _registerTabFocusAccessibility;
827
1007
  }
828
1008
 
829
1009
  /** Options for an {@link EditorController}. */
@@ -834,10 +1014,81 @@ export declare interface EditorControllerOptions {
834
1014
  * strategy (e.g. `AsyncClipboardStrategy`) in hosts that swallow them.
835
1015
  */
836
1016
  readonly clipboardStrategy?: IClipboardStrategy;
1017
+ /**
1018
+ * Where undo and redo are executed: `LocalHistoryStrategy` for a
1019
+ * self-contained editor, or a strategy that forwards to the host's own
1020
+ * document history. Left unset, the chords are passed on to the host.
1021
+ */
1022
+ readonly historyStrategy?: IHistoryStrategy;
1023
+ readonly keyboardPlatform?: KeyboardPlatform;
1024
+ readonly keyboardProfile?: KeyboardProfile;
1025
+ /**
1026
+ * Bindings owned by the host. Matching events have their browser default
1027
+ * suppressed but continue propagating so the host keybinding service sees them.
1028
+ */
1029
+ readonly forwardedKeyboardProfile?: KeyboardProfile;
1030
+ /** Tab-stop settings used outside semantic list indentation. */
1031
+ readonly indentation?: IndentationConfig;
1032
+ readonly find?: false;
837
1033
  }
838
1034
 
1035
+ /**
1036
+ * The editor overlay's local CSS-pixel coordinate space.
1037
+ *
1038
+ * Browser geometry and pointer APIs expose viewport client coordinates. This
1039
+ * boundary converts them immediately into the coordinate system shared by the
1040
+ * editor content and its overlays. Range rectangles are axis-aligned, so the
1041
+ * current implementation deliberately supports positive axis-aligned scale and
1042
+ * translation only.
1043
+ */
1044
+ export declare class EditorCoordinateSpace {
1045
+ private readonly _getLocalToClientMatrix;
1046
+ static forSvgOverlay(overlay: SVGSVGElement): EditorCoordinateSpace;
1047
+ private constructor();
1048
+ capture(): EditorCoordinateTransform;
1049
+ }
1050
+
1051
+ /** A stable coordinate conversion captured for one measurement operation. */
1052
+ export declare class EditorCoordinateTransform {
1053
+ private readonly _localToClient;
1054
+ private readonly _clientToLocal;
1055
+ constructor(_localToClient: DOMMatrix);
1056
+ toLocalPoint(point: Pick<Point2D, 'x' | 'y'>): Point2D;
1057
+ toClientPoint(point: Pick<Point2D, 'x' | 'y'>): Point2D;
1058
+ toLocalRect(rect: Pick<DOMRectReadOnly, 'left' | 'top' | 'width' | 'height'>): Rect2D;
1059
+ toClientRect(rect: Pick<Rect2D, 'left' | 'top' | 'width' | 'height'>): Rect2D;
1060
+ private _convertRect;
1061
+ }
1062
+
1063
+ export declare type EditorKeyboardAction = {
1064
+ readonly kind: 'cursor';
1065
+ readonly command: CursorKeyboardAction;
1066
+ readonly extend: boolean;
1067
+ } | {
1068
+ readonly kind: 'edit';
1069
+ readonly command: EditKeyboardAction;
1070
+ } | {
1071
+ readonly kind: 'history';
1072
+ readonly command: HistoryKeyboardAction;
1073
+ } | {
1074
+ readonly kind: 'tab';
1075
+ readonly command: TabKeyboardAction;
1076
+ } | {
1077
+ readonly kind: 'toggleTabFocus';
1078
+ } | {
1079
+ readonly kind: 'toggleReadonly';
1080
+ } | {
1081
+ readonly kind: 'selectAll';
1082
+ } | {
1083
+ readonly kind: 'enter';
1084
+ readonly command: 'smartEnter' | 'insertParagraph' | 'insertHardLineBreak';
1085
+ };
1086
+
839
1087
  export declare class EditorModel {
840
1088
  private readonly _parser;
1089
+ private readonly _sourceEditListeners;
1090
+ private readonly _sourceTextIds;
1091
+ private _lastSourceTextId;
841
1092
  /**
842
1093
  * The most recent edit applied to {@link sourceText}, used by
843
1094
  * {@link document} to let the parser link incrementally edited code
@@ -846,21 +1097,18 @@ export declare class EditorModel {
846
1097
  */
847
1098
  private _pendingEdit;
848
1099
  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
- */
1100
+ readonly wordNavigationConfig: ISettableObservable<WordNavigationConfig, void>;
1101
+ /** Disables text editing, independently of parsing, layout and markup visibility. */
858
1102
  readonly readonlyMode: ISettableObservable<boolean, void>;
1103
+ readonly presentation: ISettableObservable<EditorPresentation, void>;
1104
+ readonly renderMarkupText: ISettableObservable<RenderMarkupText, void>;
1105
+ readonly presentationPolicy: IObservableWithChange<PresentationPolicy, void>;
859
1106
  /**
860
1107
  * The current selection, or `undefined` when the editor has no caret
861
1108
  * (e.g. an inactive/unfocused rendering).
862
1109
  */
863
1110
  readonly selection: ISettableObservable<Selection_2 | undefined, void>;
1111
+ readonly selectionSource: ISettableObservable<SelectionSource, void>;
864
1112
  /**
865
1113
  * Whether a Ctrl/Cmd modifier is currently held. Set by the controller from
866
1114
  * live keyboard state; the view reads it to show the link-open affordance
@@ -868,6 +1116,14 @@ export declare class EditorModel {
868
1116
  * whose block is active.
869
1117
  */
870
1118
  readonly ctrlOrMetaDown: ISettableObservable<boolean, void>;
1119
+ /**
1120
+ * Whether a pointer-driven selection drag is currently in progress. Set by
1121
+ * the controller between the pointer-down that starts the drag and the
1122
+ * pointer-up/cancel that ends it. Contributions read it to defer UI that
1123
+ * would otherwise flicker mid-drag (e.g. the comment input box appears only
1124
+ * once the drag ends).
1125
+ */
1126
+ readonly isSelecting: ISettableObservable<boolean, void>;
871
1127
  /**
872
1128
  * Gutter markers (source-control style change indicators) painted in the
873
1129
  * left gutter. Each entry maps a source {@link OffsetRange} to a change kind
@@ -887,16 +1143,19 @@ export declare class EditorModel {
887
1143
  * The transient empty-paragraph editing state, or `undefined` when none is
888
1144
  * armed. See {@link PendingParagraph}. This is *not* document data — it is
889
1145
  * cleared by any source edit and lives only between the Enter that armed it
890
- * and the next keystroke.
1146
+ * and the next content-producing edit.
891
1147
  */
892
1148
  readonly pendingParagraph: ISettableObservable<PendingParagraph | undefined, void>;
1149
+ /** Switches between editing and locked mode and clears transient edit intent. */
1150
+ toggleReadonlyMode(): void;
893
1151
  readonly cursorOffset: IObservableWithChange<number | undefined, void>;
1152
+ readonly cursorPosition: IObservableWithChange<CursorPosition | undefined, void>;
894
1153
  /**
895
1154
  * The parsed document. Threads the previous document into the parser so
896
1155
  * unchanged blocks keep their object identity across reparses (see
897
1156
  * {@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.
1157
+ * safe: unchanged source reuses it directly, while changed source produces
1158
+ * a result structurally identical to a full reparse.
900
1159
  */
901
1160
  readonly document: IObservableWithChange<DocumentAstNode, void>;
902
1161
  /**
@@ -932,26 +1191,56 @@ export declare class EditorModel {
932
1191
  insertedRanges: OffsetRange[];
933
1192
  changedBlocks: Set<BlockAstNode>;
934
1193
  } | undefined, void>;
1194
+ readonly markerVisibleBlocks: IObservableWithChange<Set<BlockAstNode>, void>;
1195
+ getMarkupSelectionRange(selectionRange: OffsetRange | undefined, reader?: IReader): OffsetRange | undefined;
1196
+ onWillApplySourceEdit(listener: (event: SourceEditEvent) => void): IDisposable;
1197
+ /** Returns a stable per-object identity without retaining the source text. */
1198
+ getSourceTextId(sourceText: StringValue): number;
935
1199
  /**
936
1200
  * Arm a {@link PendingParagraph} at the given gap, minting a fresh synthetic
937
1201
  * AST node for it, and park the caret at the gap start. No source edit is
938
1202
  * applied — the blank line exists only in the view until it is materialized.
939
1203
  */
940
- armPendingParagraph(req: {
941
- anchorBlock: BlockAstNode;
942
- replaceRange: OffsetRange;
943
- atEof: boolean;
944
- }): void;
1204
+ armPendingParagraph(req: Omit<PendingParagraph, 'syntheticAst' | 'cursorLine' | 'text'>): void;
945
1205
  /** Discard the pending paragraph (if any) without touching the source. */
946
1206
  cancelPendingParagraph(): void;
1207
+ /**
1208
+ * Replace the source with an authoritative value from the host, mapping the
1209
+ * selection through the changed span and atomically discarding transient
1210
+ * state anchored to the previous parse.
1211
+ */
1212
+ replaceSourceText(text: StringValue): void;
1213
+ /** Replace the transient horizontal whitespace on the pending line. */
1214
+ setPendingParagraphText(text: string): void;
947
1215
  /**
948
1216
  * 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.
1217
+ * text, including any transient indentation, is separated from its neighbours
1218
+ * by blank lines, and place the caret after it.
951
1219
  */
952
1220
  materializePendingParagraph(text: string): void;
953
- applyEdit(edit: StringEdit): void;
1221
+ /** Sets a rendered task checkbox state in either editing or read-only mode. */
1222
+ setTaskCheckboxChecked(item: ListItemAstNode, checked: boolean): void;
1223
+ applyEdit(edit: StringEdit, selection?: Selection_2): void;
954
1224
  applyEditForSelection(edit: StringEdit): void;
1225
+ private _applySourceEdit;
1226
+ private _identifySourceEdit;
1227
+ private _emitWillApplySourceEdit;
1228
+ }
1229
+
1230
+ export declare type EditorOverlayPosition = 'top-chrome' | 'below-selection' | 'above-decorations';
1231
+
1232
+ export declare type EditorPresentation = 'reading' | 'editing';
1233
+
1234
+ /** Text updates and browser attachment are separate so hosts can supply a local transport. */
1235
+ declare interface EditorTextInput {
1236
+ readonly context: EditorTextInputContext;
1237
+ readonly nativeContext: IObservable<EditContext | null>;
1238
+ }
1239
+
1240
+ declare interface EditorTextInputContext extends EventTarget {
1241
+ readonly text: string;
1242
+ updateText(start: number, end: number, text: string): void;
1243
+ updateSelection(start: number, end: number): void;
955
1244
  }
956
1245
 
957
1246
  /**
@@ -981,8 +1270,13 @@ export declare class EditorView extends Disposable {
981
1270
  private readonly _model;
982
1271
  private readonly _options?;
983
1272
  readonly element: HTMLElement;
984
- readonly editContext: EditContext;
1273
+ readonly editContext: EditorTextInputContext;
1274
+ private readonly _nativeEditContext;
985
1275
  readonly measuredLayout: MeasuredLayoutModel;
1276
+ readonly coordinateSpace: EditorCoordinateSpace;
1277
+ readonly forcedMarkerVisibleBlocks: ISettableObservable<ReadonlySet<BlockAstNode>, void>;
1278
+ readonly showReadonlyToggle: ISettableObservable<boolean, void>;
1279
+ readonly highlightActiveBlock: ISettableObservable<boolean, void>;
986
1280
  /**
987
1281
  * Inner container that holds the rendered document and the cursor/selection
988
1282
  * overlays. The outer {@link element} spans the full width; this container
@@ -990,10 +1284,18 @@ export declare class EditorView extends Disposable {
990
1284
  * to their parent's box) stay aligned with the content.
991
1285
  */
992
1286
  private readonly _contentContainer;
1287
+ private readonly _resizeObserver;
993
1288
  private readonly _cursorView;
994
1289
  private readonly _selectionView;
995
1290
  private readonly _gutterMarkersView;
996
1291
  private readonly _diffHighlightsView;
1292
+ private _readonlyToggleButton;
1293
+ private readonly _editContextSuspensions;
1294
+ private readonly _revealOcclusions;
1295
+ private _pendingTopReveal;
1296
+ private _caretRevealRaf;
1297
+ private _followedCaretBlock;
1298
+ private _followCaretAfterEdit;
997
1299
  /**
998
1300
  * The mounted block sequence, in source order. Rebuilt (not mutated) each
999
1301
  * frame by {@link DocumentViewNode.create}; the view just swaps one
@@ -1001,8 +1303,17 @@ export declare class EditorView extends Disposable {
1001
1303
  * (those go through the measured-layout model).
1002
1304
  */
1003
1305
  private readonly _document;
1306
+ private readonly _embeddedCodeEditorFactoryVersion;
1307
+ private readonly _suspendEditContextForBlockControl;
1308
+ private _clipboardWriter;
1309
+ private readonly _writeClipboardText;
1310
+ /** Connects explicit copy actions to the controller's host clipboard strategy. */
1311
+ setClipboardWriter(writeText: (text: string) => Promise<void>): IDisposable;
1312
+ private _renderedSourceEditing;
1004
1313
  /** The current view-node tree (AST overlaid with rendered DOM), for debugging. */
1005
1314
  get documentViewNode(): IObservable<DocumentViewNode | undefined>;
1315
+ /** Re-resolves embedded code editors while preserving the surrounding editor view. */
1316
+ refreshEmbeddedCodeEditors(): void;
1006
1317
  /**
1007
1318
  * Last frame's view-data overlay, threaded back into
1008
1319
  * {@link buildDocumentViewData} so any subtree whose ast and selection flags
@@ -1014,12 +1325,15 @@ export declare class EditorView extends Disposable {
1014
1325
  private readonly _viewData;
1015
1326
  get viewData(): IObservable<DocumentViewData | undefined>;
1016
1327
  /**
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.
1328
+ * Whether the editor is genuinely focused: focus rests somewhere inside the
1329
+ * editor subtree *and* its window is focused. Mirrored onto the root as
1330
+ * `.md-focused`, which gates the painted caret — the blinking cursor is only
1331
+ * shown while this is `true`, so it never blinks in an unfocused editor or
1332
+ * after the window loses focus. Only the caret's visibility is affected; the
1333
+ * logical selection and caret geometry ({@link caretRect}) are unchanged.
1021
1334
  */
1022
- private readonly _pendingCaretRect;
1335
+ private readonly _focused;
1336
+ get focused(): IObservable<boolean>;
1023
1337
  /**
1024
1338
  * The block cache projected for views (selection painting) that need to
1025
1339
  * react to mount/unmount. Derived from {@link _document}, so it stays in
@@ -1050,6 +1364,7 @@ export declare class EditorView extends Disposable {
1050
1364
  */
1051
1365
  rangeRects(range: OffsetRange): IObservable<readonly SelectionRect[]>;
1052
1366
  constructor(_model: EditorModel, _options?: EditorViewOptions | undefined);
1367
+ private _setupEmptyDocumentSelection;
1053
1368
  /**
1054
1369
  * Mirrors the model's live Ctrl/Cmd state onto the editor root as
1055
1370
  * `.md-mod-down` so CSS can show the link-open underline and pointer cursor
@@ -1058,34 +1373,109 @@ export declare class EditorView extends Disposable {
1058
1373
  */
1059
1374
  private _setupModifierTracking;
1060
1375
  /**
1061
- * Renders the edit/read-only lock toggle. It flips the model's
1062
- * {@link EditorModel.readonlyMode}: when locked (read-only) every block stays
1376
+ * Tracks whether the editor is genuinely focused and mirrors it onto the
1377
+ * root as `.md-focused` so CSS can gate the painted caret. "Focused" means
1378
+ * focus rests somewhere inside the editor subtree *and* the window itself is
1379
+ * focused; either condition failing (focus moving elsewhere, or the window
1380
+ * losing focus) hides the blinking caret while leaving the logical selection
1381
+ * and caret geometry intact.
1382
+ */
1383
+ private _setupFocusTracking;
1384
+ private _setupCaretScrollPadding;
1385
+ /**
1386
+ * Renders the locked/rich/source editing mode toggle. When locked every block stays
1063
1387
  * in its clean rendered form (no markdown markers revealed) and edits are
1064
1388
  * 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.
1389
+ * zero-height sticky host, using the right margin when it fits and
1390
+ * overlapping content when narrow, without changing the document's geometry.
1391
+ * The current mode is also mirrored onto the root as `.md-readonly`
1392
+ * for any CSS hooks.
1068
1393
  */
1069
1394
  private _setupReadonlyToggle;
1395
+ /** Draws attention to the mode toggle after text input is attempted while locked. */
1396
+ showReadonlyEditingAttempt(): void;
1070
1397
  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>;
1398
+ mountOverlay(element: HTMLElement | SVGSVGElement, position: EditorOverlayPosition): IDisposable;
1399
+ /** Registers floating editor chrome that should count as covering a range during reveal. */
1400
+ registerRevealOcclusion(element: Element): IDisposable;
1401
+ /**
1402
+ * Temporarily detaches the root {@link EditContext} while focus is inside
1403
+ * nested editor chrome. Chromium otherwise reclaims focus from non-text
1404
+ * controls inside the EditContext host, breaking keyboard access to controls
1405
+ * such as the find actions and read-only toggle.
1406
+ */
1407
+ suspendEditContextWhileFocused(element: HTMLElement): IDisposable;
1408
+ revealRangeInCenterIfOutsideViewport(range: OffsetRange, behavior?: ScrollBehavior): IDisposable;
1409
+ /**
1410
+ * Aligns an explicitly navigated range with the top of its nearest vertical
1411
+ * scroll viewport, even when the range is already partially or fully visible.
1412
+ * The alignment leaves {@link TOP_REVEAL_CONTEXT_INSET}px of navigation
1413
+ * context above the range, grown so the range also clears any chrome
1414
+ * registered through {@link registerRevealOcclusion} that covers the top of
1415
+ * that viewport. Outer vertical scrollers and the window keep nearest-edge
1416
+ * behavior so they do not jump, and horizontal scrolling stays nearest-edge.
1417
+ *
1418
+ * Explicit navigation also stops edit-driven caret following, so a later
1419
+ * block resize does not scroll back to where the caret was left behind.
1420
+ * Sticky chrome is remeasured once scrolling completes. User input, a newer
1421
+ * reveal, or disposal cancels that deferred correction.
1422
+ */
1423
+ revealRangeAtTop(range: OffsetRange, behavior?: ScrollBehavior): IDisposable;
1424
+ private _scheduleRangeReveal;
1425
+ private _scheduleTopRangeReveal;
1426
+ /**
1427
+ * Keeps the caret visible after an editor-driven text edit. The reveal is
1428
+ * deferred until the rebuilt document has been laid out and uses nearest-edge
1429
+ * scrolling so ordinary typing only moves the containing viewport as far as
1430
+ * needed. While this mode is active, a later resize of the same active block
1431
+ * also re-reveals the caret (for asynchronous code, math, or diagram layout).
1432
+ */
1433
+ revealCaretAfterEdit(): void;
1434
+ /** Keeps a keyboard-moved caret visible without enabling edit-resize following. */
1435
+ revealCaretAfterKeyboardNavigation(): void;
1436
+ /** Stops edit-driven caret following before pointer-based selection begins. */
1437
+ stopFollowingCaret(): void;
1438
+ /**
1439
+ * Samples the ambient focus state that decides whether taking focus on open
1440
+ * would steal it from an explicit user target: whether the window is focused
1441
+ * and whether focus is still unclaimed (no active element, or the `<body>`
1442
+ * fallback).
1443
+ */
1444
+ private _sampleAutoFocusEnvironment;
1445
+ /**
1446
+ * One-shot guarded focus attempt: focuses the editor only if doing so will
1447
+ * not steal focus from an explicit user target — the window must already be
1448
+ * focused and no other element may have claimed focus yet. Returns whether
1449
+ * focus was taken. A no-op for a background window or when the user has
1450
+ * already focused something else. {@link autoFocusOnOpen} builds the
1451
+ * open-time behavior on top of this primitive.
1452
+ */
1453
+ tryAutoFocus(): boolean;
1454
+ /**
1455
+ * Focuses the editor when it opens without ever stealing focus from an
1456
+ * explicit user target. Tries once immediately; if the window is not focused
1457
+ * yet — a common open-time race where the editor is mounted before the host
1458
+ * routes focus to its window — the guarded attempt is deferred to the next
1459
+ * time the window gains focus and re-evaluated then. The deferral is
1460
+ * one-shot, so a later, unrelated window refocus never grabs focus, and the
1461
+ * re-check still respects any target the user has claimed in the meantime.
1462
+ */
1463
+ autoFocusOnOpen(): void;
1083
1464
  /**
1084
1465
  * Client coordinates → absolute source offset (any block). Used during
1085
1466
  * drag to keep extending the selection even when the pointer leaves the
1086
- * original block. Honours {@link geometricHitTest}.
1467
+ * original block. Snaps to the nearest visual line and source offset.
1087
1468
  */
1088
1469
  resolveOffsetFromPoint(point: Point2D): SourceOffset | undefined;
1470
+ resolveCursorPositionFromPoint(point: Point2D): SourceCursorPosition | undefined;
1471
+ private _resolveControlFreeVideoOffset;
1472
+ /**
1473
+ * Resolve table-cell hits that have no measurable text run. Empty cells map
1474
+ * from their own box instead of snapping to a neighboring cell; element-only
1475
+ * content (for example an inactive image) maps through the hit element's view
1476
+ * node. Text-bearing cells keep the normal pixel-precise line-map path.
1477
+ */
1478
+ private _resolveTableCellOffset;
1089
1479
  /**
1090
1480
  * Whether a client point falls on the rendered document content, as
1091
1481
  * opposed to the surrounding editor padding (the green area). Uses DOM
@@ -1095,6 +1485,14 @@ export declare class EditorView extends Disposable {
1095
1485
  * have `pointer-events: none`, so the hit-test sees through them.
1096
1486
  */
1097
1487
  isPointInContent(point: Point2D): boolean;
1488
+ /**
1489
+ * Whether `range` intersects the rendered source text — the region whose
1490
+ * selection this editor paints itself from `model.selection`. This also
1491
+ * catches select-all ranges whose endpoints surround the rendered content.
1492
+ * Overlays anchored beside the text (comment widgets and the like) are *not*
1493
+ * part of it and keep their own native selection behaviour.
1494
+ */
1495
+ intersectsRenderedContent(range: Range): boolean;
1098
1496
  private readonly _renderAutorun;
1099
1497
  /** Current mounted blocks, or empty before the first render. */
1100
1498
  private get _blocks();
@@ -1113,9 +1511,46 @@ export declare class EditorView extends Disposable {
1113
1511
  */
1114
1512
  private _paintDiff;
1115
1513
  private _clearDiff;
1514
+ private _syncEditContextAttachment;
1515
+ private _revealRange;
1516
+ private _revealTarget;
1517
+ private _scheduleCaretReveal;
1518
+ private _revealCaretNearest;
1519
+ private _revealCaretAfterActiveBlockResize;
1520
+ private _caretBlockAt;
1521
+ private _measurementAt;
1522
+ private _stopFollowingCaret;
1523
+ private _isRevealOccluded;
1524
+ /** Client rects of registered occlusions that are currently rendered and visible. */
1525
+ private _activeRevealOcclusions;
1526
+ /**
1527
+ * How far registered chrome covers the top of `viewport`, measured down from
1528
+ * `viewport.top`, across the columns `target` occupies. Clearing one occluder
1529
+ * can slide the target behind the next one, so the tested band is re-evaluated
1530
+ * until it settles; stacked chrome therefore reports the lowest connected
1531
+ * bottom edge. Returns 0 when nothing covers the top.
1532
+ */
1533
+ private _occludedTopHeight;
1534
+ /**
1535
+ * Vertical inset used to top-align `target` inside `viewport`. Defaults to
1536
+ * {@link TOP_REVEAL_CONTEXT_INSET}, and grows past registered chrome covering
1537
+ * the viewport top so the same breathing room is kept below that chrome.
1538
+ */
1539
+ private _topRevealInset;
1540
+ /**
1541
+ * `viewport` reduced to the area an explicitly navigated target may occupy:
1542
+ * registered top chrome is excluded, along with the breathing room below it.
1543
+ * Nearest-edge movement parks the target just inside the rect it is given, so
1544
+ * the inset has to be part of that rect; otherwise an outer scroller, or the
1545
+ * window, would leave the target grazing the chrome's bottom edge after the
1546
+ * nearest vertical viewport had already aligned it.
1547
+ */
1548
+ private _unoccludedViewport;
1116
1549
  }
1117
1550
 
1118
1551
  export declare interface EditorViewOptions extends BlockViewOptions {
1552
+ readonly presentation?: EditorPresentation;
1553
+ readonly textInput?: EditorTextInput;
1119
1554
  /**
1120
1555
  * Extra class names added to the editor root element, e.g. a theme class
1121
1556
  * such as `'md-theme-default'` or `'github-markdown-theme'`. Theme styles
@@ -1123,6 +1558,14 @@ export declare interface EditorViewOptions extends BlockViewOptions {
1123
1558
  * only) unless a theme class is supplied.
1124
1559
  */
1125
1560
  readonly classNames?: readonly string[];
1561
+ /**
1562
+ * Whether to render the edit/read-only toggle at the top-right edge
1563
+ * of the content. Defaults to `true`; set to `false` to omit it (e.g. in
1564
+ * fixtures that focus on selection rendering).
1565
+ */
1566
+ readonly showReadonlyToggle?: boolean;
1567
+ /** Whether to paint the active block's background and glow. Defaults to `true`. */
1568
+ readonly highlightActiveBlock?: boolean;
1126
1569
  /**
1127
1570
  * Controls "limited width mode". The observable yields the maximum content
1128
1571
  * width in pixels, or `undefined` to let the content fill the available
@@ -1145,10 +1588,10 @@ export declare interface EditorViewOptions extends BlockViewOptions {
1145
1588
 
1146
1589
  export declare class EmphasisAstNode extends AstNode {
1147
1590
  readonly openMarker: MarkerAstNode;
1148
- readonly content: readonly (InlineAstNode | GlueAstNode)[];
1591
+ readonly content: readonly InlineContentAstNode[];
1149
1592
  readonly closeMarker: MarkerAstNode;
1150
1593
  readonly kind = "emphasis";
1151
- constructor(openMarker: MarkerAstNode, content: readonly (InlineAstNode | GlueAstNode)[], closeMarker: MarkerAstNode);
1594
+ constructor(openMarker: MarkerAstNode, content: readonly InlineContentAstNode[], closeMarker: MarkerAstNode);
1152
1595
  get children(): readonly AstNode[];
1153
1596
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1154
1597
  }
@@ -1160,6 +1603,129 @@ declare class EmphasisViewData {
1160
1603
  constructor(ast: EmphasisAstNode, content: readonly AnyViewData[]);
1161
1604
  }
1162
1605
 
1606
+ /** One blank source line, or the empty final line after a terminating newline. */
1607
+ export declare class EmptyBlockAstNode extends BlockAstNodeBase {
1608
+ readonly content: readonly GlueAstNode[];
1609
+ readonly leadingTrivia?: GlueAstNode | undefined;
1610
+ readonly kind = "emptyBlock";
1611
+ constructor(content: readonly GlueAstNode[], leadingTrivia?: GlueAstNode | undefined);
1612
+ get children(): readonly AstNode[];
1613
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1614
+ withLeadingTrivia(trivia: GlueAstNode | undefined): EmptyBlockAstNode;
1615
+ }
1616
+
1617
+ declare class EmptyBlockViewData {
1618
+ readonly ast: EmptyBlockAstNode;
1619
+ readonly content: readonly AnyViewData[];
1620
+ readonly kind = "emptyBlock";
1621
+ constructor(ast: EmptyBlockAstNode, content: readonly AnyViewData[]);
1622
+ }
1623
+
1624
+ export declare function escapeFindRegex(value: string): string;
1625
+
1626
+ export declare const FIND_MATCH_LIMIT = 19999;
1627
+
1628
+ export declare function findBlockAtOffset(doc: DocumentAstNode, offset: SourceOffset): BlockAstNode | undefined;
1629
+
1630
+ export declare class FindController extends Disposable {
1631
+ private readonly _editorModel;
1632
+ private readonly _view;
1633
+ private readonly _options;
1634
+ readonly model: FindModel;
1635
+ readonly widget: FindWidget;
1636
+ private readonly _selectionForScope;
1637
+ private _forcedMatch;
1638
+ private _selectedMatch;
1639
+ private _observedSourceTextId;
1640
+ private readonly _sourceEditTracker;
1641
+ private _revealRequest;
1642
+ constructor(_editorModel: EditorModel, _view: EditorView, _options: FindControllerOptions);
1643
+ private _setForcedMarkerVisibleBlocks;
1644
+ openAndFocus(): void;
1645
+ close(): void;
1646
+ private _handleKeyDown;
1647
+ private _cancelRevealRequest;
1648
+ private _findByKeyboard;
1649
+ private _querySeed;
1650
+ private _prepareSeed;
1651
+ private _selectedSingleLineText;
1652
+ private _toggleFindInSelection;
1653
+ }
1654
+
1655
+ export declare interface FindControllerOptions {
1656
+ readonly keyboardPlatform: KeyboardPlatform;
1657
+ }
1658
+
1659
+ export declare type FindDirection = 'next' | 'previous';
1660
+
1661
+ export declare class FindHighlightsView extends Disposable {
1662
+ private readonly _view;
1663
+ private readonly _matchesLayer;
1664
+ private readonly _currentLayer;
1665
+ private readonly _highlightRegistration;
1666
+ private readonly _resizeObserver;
1667
+ private readonly _resizeObservedElements;
1668
+ private _snapshot;
1669
+ private _paintRaf;
1670
+ constructor(_view: EditorView, findModel: FindModel);
1671
+ private _schedulePaint;
1672
+ private _paint;
1673
+ private _observeResizeAncestors;
1674
+ private _paintRanges;
1675
+ }
1676
+
1677
+ export declare interface FindMatchesResult {
1678
+ readonly matches: readonly OffsetRange[];
1679
+ readonly isCapped: boolean;
1680
+ }
1681
+
1682
+ export declare class FindModel extends Disposable {
1683
+ private readonly _editorModel;
1684
+ readonly isRevealed: ISettableObservable<boolean, void>;
1685
+ readonly searchString: ISettableObservable<string, void>;
1686
+ readonly isRegex: ISettableObservable<boolean, void>;
1687
+ readonly matchCase: ISettableObservable<boolean, void>;
1688
+ readonly wholeWord: ISettableObservable<boolean, void>;
1689
+ readonly searchScope: ISettableObservable<OffsetRange | undefined, void>;
1690
+ readonly currentMatch: ISettableObservable<OffsetRange | undefined, void>;
1691
+ readonly loop: ISettableObservable<boolean, void>;
1692
+ readonly searchResult: IObservableWithChange< {
1693
+ kind: "invalid";
1694
+ error: Error;
1695
+ pattern?: undefined;
1696
+ matches?: undefined;
1697
+ isCapped?: undefined;
1698
+ } | {
1699
+ kind: "valid";
1700
+ pattern: FindPattern;
1701
+ matches: readonly OffsetRange[];
1702
+ isCapped: boolean;
1703
+ error?: undefined;
1704
+ }, void>;
1705
+ readonly matchesCount: IObservableWithChange<number, void>;
1706
+ readonly isCapped: IObservableWithChange<boolean, void>;
1707
+ readonly currentMatchPosition: IObservableWithChange<number, void>;
1708
+ private _searchOrigin;
1709
+ private readonly _sourceEditTracker;
1710
+ private _pendingInitialDirection;
1711
+ constructor(_editorModel: EditorModel);
1712
+ reveal(options: {
1713
+ readonly origin: number;
1714
+ readonly searchString?: string;
1715
+ readonly direction?: FindDirection;
1716
+ }): void;
1717
+ hide(): void;
1718
+ setSearchOrigin(offset: number): void;
1719
+ setSearchScope(scope: OffsetRange | undefined): void;
1720
+ moveToNextMatch(): OffsetRange | undefined;
1721
+ moveToPreviousMatch(): OffsetRange | undefined;
1722
+ private _move;
1723
+ private _selectFromOrigin;
1724
+ private _mapStateThroughEdit;
1725
+ private _inputSnapshot;
1726
+ private _readInputSnapshot;
1727
+ }
1728
+
1163
1729
  /**
1164
1730
  * Source offset (relative to `root`) of the node with `target`'s id, or
1165
1731
  * `undefined` when it is not in the tree. Ids are stable across edits, so this
@@ -1167,14 +1733,117 @@ declare class EmphasisViewData {
1167
1733
  */
1168
1734
  export declare function findNodeOffsetById(root: AstNode, target: AstNode): number | undefined;
1169
1735
 
1170
- export declare function findWordAt(text: string, offset: number): {
1736
+ export declare class FindPattern {
1737
+ private readonly _source;
1738
+ private readonly _flags;
1739
+ private readonly _wholeWord;
1740
+ private readonly _wordSeparators;
1741
+ readonly isEmpty: boolean;
1742
+ private constructor();
1743
+ static create(query: FindQuery): FindQueryResult;
1744
+ findMatches(text: string, scope?: OffsetRange, limit?: number): FindMatchesResult;
1745
+ findNextMatch(text: string, after: number, scope?: OffsetRange, loop?: boolean, skip?: OffsetRange): OffsetRange | undefined;
1746
+ findPreviousMatch(text: string, before: number, scope?: OffsetRange, loop?: boolean, skip?: OffsetRange): OffsetRange | undefined;
1747
+ private _forEachMatch;
1748
+ }
1749
+
1750
+ export declare interface FindQuery {
1751
+ readonly searchString: string;
1752
+ readonly isRegex: boolean;
1753
+ readonly matchCase: boolean;
1754
+ readonly wholeWord: boolean;
1755
+ readonly wordSeparators: string;
1756
+ }
1757
+
1758
+ export declare type FindQueryResult = {
1759
+ readonly kind: 'valid';
1760
+ readonly pattern: FindPattern;
1761
+ } | {
1762
+ readonly kind: 'invalid';
1763
+ readonly error: Error;
1764
+ };
1765
+
1766
+ export declare type FindSearchResult = {
1767
+ readonly kind: 'valid';
1768
+ readonly pattern: FindPattern;
1769
+ readonly matches: readonly OffsetRange[];
1770
+ readonly isCapped: boolean;
1771
+ } | {
1772
+ readonly kind: 'invalid';
1773
+ readonly error: Error;
1774
+ };
1775
+
1776
+ export declare class FindWidget extends Disposable {
1777
+ private readonly _view;
1778
+ private readonly _options;
1779
+ readonly element: HTMLElement;
1780
+ readonly panelElement: HTMLElement;
1781
+ readonly focused: ISettableObservable<boolean, void>;
1782
+ private readonly _inputShell;
1783
+ private readonly _input;
1784
+ private readonly _matchesCount;
1785
+ private readonly _previousButton;
1786
+ private readonly _nextButton;
1787
+ private readonly _selectionButton;
1788
+ private readonly _caseButton;
1789
+ private readonly _wholeWordButton;
1790
+ private readonly _regexButton;
1791
+ private readonly _error;
1792
+ constructor(_view: EditorView, _options: FindWidgetOptions);
1793
+ focusAndSelect(): void;
1794
+ private _registerButton;
1795
+ private _render;
1796
+ }
1797
+
1798
+ export declare interface FindWidgetOptions {
1799
+ readonly findModel: FindModel;
1800
+ readonly canFindInSelection: IObservable<boolean>;
1801
+ readonly onNext: () => void;
1802
+ readonly onPrevious: () => void;
1803
+ readonly onToggleFindInSelection: () => void;
1804
+ readonly onClose: () => void;
1805
+ }
1806
+
1807
+ export declare function findWordAt(text: string, offset: number, config?: WordNavigationConfig): {
1171
1808
  start: number;
1172
1809
  end: number;
1173
1810
  };
1174
1811
 
1175
- export declare function findWordBoundaryLeft(text: string, offset: number): number;
1812
+ export declare function findWordBoundaryLeft(text: string, offset: number, config?: WordNavigationConfig): number;
1813
+
1814
+ export declare function findWordBoundaryRight(text: string, offset: number, config?: WordNavigationConfig): number;
1815
+
1816
+ export declare function findWordDeleteBoundaryLeft(text: string, offset: number, config?: WordNavigationConfig): number;
1817
+
1818
+ export declare function findWordDeleteBoundaryRight(text: string, offset: number, config?: WordNavigationConfig): number;
1819
+
1820
+ /**
1821
+ * A leading YAML front matter block. The YAML value is intentionally opaque:
1822
+ * only the two fences and the exact source between them are modeled.
1823
+ */
1824
+ export declare class FrontMatterAstNode extends BlockAstNodeBase {
1825
+ readonly content: readonly (MarkerAstNode | GlueAstNode)[];
1826
+ readonly leadingTrivia?: GlueAstNode | undefined;
1827
+ readonly kind = "frontMatter";
1828
+ constructor(content: readonly (MarkerAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
1829
+ get children(): readonly AstNode[];
1830
+ get openFence(): MarkerAstNode | undefined;
1831
+ get closeFence(): MarkerAstNode | undefined;
1832
+ get value(): MarkerAstNode | undefined;
1833
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1834
+ withLeadingTrivia(trivia: GlueAstNode | undefined): FrontMatterAstNode;
1835
+ }
1176
1836
 
1177
- export declare function findWordBoundaryRight(text: string, offset: number): number;
1837
+ declare class FrontMatterViewData {
1838
+ readonly ast: FrontMatterAstNode;
1839
+ /** Active: render both fences; inactive: render only the opaque YAML value. */
1840
+ readonly showMarkup: boolean;
1841
+ readonly content: readonly AnyViewData[];
1842
+ readonly kind = "frontMatter";
1843
+ constructor(ast: FrontMatterAstNode,
1844
+ /** Active: render both fences; inactive: render only the opaque YAML value. */
1845
+ showMarkup: boolean, content: readonly AnyViewData[]);
1846
+ }
1178
1847
 
1179
1848
  export declare function getAnnotatedSource(node: AstNode, source: string, offset?: number): string;
1180
1849
 
@@ -1197,6 +1866,8 @@ declare class GlueViewData {
1197
1866
  * block children) the break is already visible, so no `↵` is drawn.
1198
1867
  */
1199
1868
  readonly decorateNewline: boolean;
1869
+ readonly showWhitespace: boolean;
1870
+ readonly listContinuation?: ListContinuation | undefined;
1200
1871
  readonly kind = "glue";
1201
1872
  constructor(ast: GlueAstNode, visible: boolean,
1202
1873
  /**
@@ -1205,7 +1876,7 @@ declare class GlueViewData {
1205
1876
  * the line ending hiding there; between block-level siblings (list items,
1206
1877
  * block children) the break is already visible, so no `↵` is drawn.
1207
1878
  */
1208
- decorateNewline: boolean);
1879
+ decorateNewline: boolean, showWhitespace?: boolean, listContinuation?: ListContinuation | undefined);
1209
1880
  }
1210
1881
 
1211
1882
  /**
@@ -1234,10 +1905,10 @@ export declare type GutterMarkerType = 'added' | 'modified' | 'deleted';
1234
1905
  export declare class HeadingAstNode extends BlockAstNodeBase {
1235
1906
  readonly level: 1 | 2 | 3 | 4 | 5 | 6;
1236
1907
  readonly marker: MarkerAstNode;
1237
- readonly content: readonly (InlineAstNode | GlueAstNode)[];
1908
+ readonly content: readonly InlineContentAstNode[];
1238
1909
  readonly leadingTrivia?: GlueAstNode | undefined;
1239
1910
  readonly kind = "heading";
1240
- constructor(level: 1 | 2 | 3 | 4 | 5 | 6, marker: MarkerAstNode, content: readonly (InlineAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
1911
+ constructor(level: 1 | 2 | 3 | 4 | 5 | 6, marker: MarkerAstNode, content: readonly InlineContentAstNode[], leadingTrivia?: GlueAstNode | undefined);
1241
1912
  get children(): readonly AstNode[];
1242
1913
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1243
1914
  withLeadingTrivia(trivia: GlueAstNode | undefined): HeadingAstNode;
@@ -1251,6 +1922,19 @@ declare class HeadingViewData {
1251
1922
  constructor(ast: HeadingAstNode, content: readonly AnyViewData[]);
1252
1923
  }
1253
1924
 
1925
+ export declare function hiddenCursorRanges(doc: DocumentAstNode, markerVisibleBlocks: ReadonlySet<BlockAstNode>, selectionRange: OffsetRange): readonly OffsetRange[];
1926
+
1927
+ export declare type HistoryKeyboardAction = 'undo' | 'redo';
1928
+
1929
+ /** A block HTML comment, discriminated by whether its closing delimiter is present. */
1930
+ declare type HtmlCommentSource = OpenHtmlCommentSource | CompleteHtmlCommentSource;
1931
+
1932
+ declare interface HtmlCommentSourceBase {
1933
+ readonly leadingWhitespace: string;
1934
+ readonly opening: '<!--';
1935
+ readonly body: string;
1936
+ }
1937
+
1254
1938
  /**
1255
1939
  * The editor operations a clipboard strategy drives. The strategy never
1256
1940
  * touches the model or the DOM directly — it asks through this seam, so the
@@ -1263,8 +1947,8 @@ export declare interface IClipboardContext {
1263
1947
  getSelectedText(): string | undefined;
1264
1948
  /** Delete the current selection (the cut half of cut). */
1265
1949
  deleteSelection(): void;
1266
- /** Insert text at the caret, replacing any selection (the paste action). */
1267
- insertText(text: string): void;
1950
+ /** Paste text, linking a suitable selection when the payload is a URL unless plain text was requested. */
1951
+ insertText(text: string, plainText?: boolean): void;
1268
1952
  }
1269
1953
 
1270
1954
  /**
@@ -1280,6 +1964,8 @@ export declare interface IClipboardContext {
1280
1964
  * swallow the native clipboard events before they reach the editor.
1281
1965
  */
1282
1966
  export declare interface IClipboardStrategy {
1967
+ /** Copy an explicit payload without changing the editor selection. Falls back to the browser API when omitted. */
1968
+ writeText?(text: string): Promise<void>;
1283
1969
  /**
1284
1970
  * Wire up clipboard handling against `context`. The returned disposable
1285
1971
  * tears down every listener the strategy installed.
@@ -1287,9 +1973,6 @@ export declare interface IClipboardStrategy {
1287
1973
  connect(context: IClipboardContext): IDisposable;
1288
1974
  }
1289
1975
 
1290
- /** A live rendering of a {@link CommentsModel}. Dispose to unmount it. */
1291
- export declare type ICommentsPresenter = IDisposable;
1292
-
1293
1976
  /** The Monarch language definitions the default highlighter wires up. */
1294
1977
  export declare interface IDefaultMonarchGrammars {
1295
1978
  typescript: unknown;
@@ -1299,6 +1982,91 @@ export declare interface IDefaultMonarchGrammars {
1299
1982
  python: unknown;
1300
1983
  rust: unknown;
1301
1984
  shell: unknown;
1985
+ yaml: unknown;
1986
+ }
1987
+
1988
+ /**
1989
+ * A live editor embedded in place of a fenced code block's *rendered* form.
1990
+ *
1991
+ * This is the internal seam between the block view and a concrete embedded
1992
+ * editor (e.g. an `<iframe>` speaking the web-editor protocol). The block view
1993
+ * only speaks string edits: it pushes the block's content down via
1994
+ * {@link setContent} and receives the editor's own changes back through
1995
+ * {@link onEdit} (set by the block view on each (re)construction, so it always
1996
+ * routes to the current AST node). The concrete implementation owns its DOM,
1997
+ * transport, and lifecycle.
1998
+ *
1999
+ * A single instance is adopted across re-renders (like the highlighter session)
2000
+ * so the underlying editor keeps its state across edits — see
2001
+ * {@link CodeBlockViewNode}.
2002
+ */
2003
+ declare interface IEmbeddedCodeEditor {
2004
+ /** The element mounted as the block's rendered form. */
2005
+ readonly element: HTMLElement;
2006
+ /**
2007
+ * Document → editor. The block's content changed (from any source). Must be
2008
+ * idempotent: pushing the content the editor already holds is a no-op, which
2009
+ * is how edits the editor itself originated are prevented from echoing back.
2010
+ */
2011
+ setContent(content: string): void;
2012
+ /** Update whether the embedded editor may change its content. */
2013
+ setReadOnly?(readOnly: boolean): void;
2014
+ /** Mount host actions alongside the embedded editor's own presentation controls. */
2015
+ setActions?(actions: HTMLElement): void;
2016
+ /**
2017
+ * Optional synchronous height (px) to reserve for `content` *before* the
2018
+ * editor has laid out. Return `undefined` to let the editor size itself
2019
+ * (the implementation may report its real height later). Lets a registration
2020
+ * avoid a layout jump when it can cheaply estimate the size from content.
2021
+ */
2022
+ estimateHeight?(content: string): number | undefined;
2023
+ /**
2024
+ * Editor → document. Set by the block view on every (re)construction to
2025
+ * route the editor's own edits, expressed in the block's *content*
2026
+ * coordinates, to the current AST node.
2027
+ */
2028
+ onEdit?: (edit: StringEdit) => void;
2029
+ dispose(): void;
2030
+ }
2031
+
2032
+ /** Creates an {@link IEmbeddedCodeEditor} for a fenced block, or opts out. */
2033
+ declare interface IEmbeddedCodeEditorFactory {
2034
+ /**
2035
+ * Return an editor for a fenced block, or `undefined` to fall
2036
+ * back to the default (highlighting / {@link BlockViewOptions.renderCustomCodeBlock}).
2037
+ */
2038
+ create(language: string, infoString: string, initialContent: string): IEmbeddedCodeEditor | undefined;
2039
+ /** Reposition overlays after the document's layout has been measured. */
2040
+ layout?(): void;
2041
+ }
2042
+
2043
+ /**
2044
+ * Routes undo and redo to whatever owns the document's history: the editor
2045
+ * itself on a standalone page, or the enclosing document in a host like
2046
+ * VS Code.
2047
+ */
2048
+ export declare interface IHistoryStrategy {
2049
+ undo(): void;
2050
+ redo(): void;
2051
+ /**
2052
+ * Invoked around each source mutation so the strategy can record it.
2053
+ * Implemented only by strategies that build their own history; a host that
2054
+ * forwards edits to a VS Code `TextDocument` lets it record them instead.
2055
+ */
2056
+ record?(operation: () => void, edit?: StringEdit): void;
2057
+ }
2058
+
2059
+ export declare interface ILinkPresentation extends IDisposable {
2060
+ /** Current presentation, updated without rebuilding the editor. */
2061
+ readonly presentation: IObservable<LinkPresentation | undefined>;
2062
+ }
2063
+
2064
+ export declare interface ILinkPresentationProvider {
2065
+ /**
2066
+ * Returns `undefined` for unsupported links. The caller disposes the returned
2067
+ * reference when the rendered link disappears.
2068
+ */
2069
+ createLinkPresentation(url: string): ILinkPresentation | undefined;
1302
2070
  }
1303
2071
 
1304
2072
  export declare class ImageAstNode extends AstNode {
@@ -1335,6 +2103,14 @@ export declare interface IMonarchApi {
1335
2103
  MonarchTokenizer: new (languageService: unknown, standaloneThemeService: unknown, languageId: string, lexer: unknown, configurationService: unknown) => MonarchTokenizer;
1336
2104
  }
1337
2105
 
2106
+ /** Controls tab-stop insertion and non-list line indentation. */
2107
+ export declare interface IndentationConfig {
2108
+ /** Number of visual columns between tab stops. */
2109
+ readonly tabSize: number;
2110
+ /** Whether indentation uses spaces instead of tab characters. */
2111
+ readonly insertSpaces: boolean;
2112
+ }
2113
+
1338
2114
  export declare type InlineAstNode = TextAstNode | StrongAstNode | EmphasisAstNode | StrikethroughAstNode | InlineCodeAstNode | InlineMathAstNode | LinkAstNode | ImageAstNode;
1339
2115
 
1340
2116
  export declare class InlineCodeAstNode extends AstNode {
@@ -1352,6 +2128,8 @@ declare class InlineCodeViewData {
1352
2128
  constructor(ast: InlineCodeAstNode, content: readonly AnyViewData[]);
1353
2129
  }
1354
2130
 
2131
+ declare type InlineContentAstNode = InlineAstNode | MarkerAstNode | GlueAstNode;
2132
+
1355
2133
  export declare class InlineMathAstNode extends AstNode {
1356
2134
  readonly content: readonly (MarkerAstNode | GlueAstNode)[];
1357
2135
  readonly kind = "inlineMath";
@@ -1389,17 +2167,29 @@ export declare const insertParagraph: EditCommand;
1389
2167
  * - paragraph / heading / thematic break — the "rich text" thing: at the
1390
2168
  * block's end arm a transient empty paragraph (see {@link SmartEnterResult});
1391
2169
  * 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.
2170
+ * - fenced code / front matter — insert a newline that preserves the current
2171
+ * line's indentation, staying inside the fences.
2172
+ * - video — leave the completed HTML block at its end; otherwise insert a
2173
+ * normal source line break.
1394
2174
  * - block quote — continue the quote (`\n> `); an empty quote line exits it.
1395
2175
  * - list — continue the list with the next marker (incrementing ordered
1396
- * numbers, re-emitting task checkboxes); an empty item exits the list.
2176
+ * numbers, re-emitting task checkboxes); an empty item outdents one level
2177
+ * before exiting the list.
2178
+ * - complete HTML comment — at the comment's end, leave it by arming a
2179
+ * transient paragraph; inside it (or while the comment is open), insert a
2180
+ * normal source line break.
1397
2181
  * A non-collapsed selection, or any other block, falls back to a plain soft line
1398
2182
  * break, preserving today's behaviour.
1399
2183
  */
1400
- export declare const insertSmartEnter: (ctx: CursorCommandContext) => SmartEnterResult;
2184
+ export declare const insertSmartEnter: (ctx: CursorCommandContext, useSourceLineBreaks?: boolean) => SmartEnterResult;
1401
2185
 
1402
- export declare function insertText(text: string): EditCommand;
2186
+ /**
2187
+ * VS Code-style Tab: insert to the next tab stop for a caret or partial
2188
+ * single-line selection, and indent every selected line for a line selection.
2189
+ */
2190
+ export declare function insertTab(config?: IndentationConfig): EditCommand;
2191
+
2192
+ export declare function insertText(text: string, generatedIndentation?: OffsetRange, completeFences?: boolean): EditCommand;
1403
2193
 
1404
2194
  /**
1405
2195
  * An immutable view of one document's tokens at a point in time. It may be a
@@ -1440,6 +2230,31 @@ export declare interface ISyntaxHighlighterDocument extends IDisposable {
1440
2230
  readonly snapshot: IObservableWithChange<ISyntaxHighlightedSnapshot, LengthEdit>;
1441
2231
  }
1442
2232
 
2233
+ export declare const joinLines: EditCommand;
2234
+
2235
+ export declare interface KeyboardBinding {
2236
+ readonly key: string;
2237
+ readonly modifiers?: KeyboardModifiers;
2238
+ readonly platforms?: readonly KeyboardPlatform[];
2239
+ readonly action: EditorKeyboardAction;
2240
+ }
2241
+
2242
+ export declare interface KeyboardModifiers {
2243
+ readonly shift?: boolean;
2244
+ readonly alt?: boolean;
2245
+ readonly ctrl?: boolean;
2246
+ readonly meta?: boolean;
2247
+ }
2248
+
2249
+ export declare type KeyboardPlatform = 'macos' | 'windows' | 'linux';
2250
+
2251
+ export declare interface KeyboardProfile {
2252
+ /**
2253
+ * Bindings in priority order. The first exact key/modifier/platform match wins.
2254
+ */
2255
+ readonly bindings: readonly KeyboardBinding[];
2256
+ }
2257
+
1443
2258
  declare abstract class LeafAstNode extends AstNode {
1444
2259
  abstract readonly content: string;
1445
2260
  get children(): readonly AstNode[];
@@ -1488,27 +2303,64 @@ export declare class LengthReplacement {
1488
2303
 
1489
2304
  export declare class LinkAstNode extends AstNode {
1490
2305
  readonly url: string;
1491
- readonly content: readonly (MarkerAstNode | InlineAstNode | GlueAstNode)[];
2306
+ readonly content: readonly InlineContentAstNode[];
2307
+ readonly title?: string | undefined;
1492
2308
  readonly kind = "link";
1493
- constructor(url: string, content: readonly (MarkerAstNode | InlineAstNode | GlueAstNode)[]);
2309
+ constructor(url: string, content: readonly InlineContentAstNode[], title?: string | undefined);
1494
2310
  get children(): readonly AstNode[];
1495
2311
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1496
2312
  protected _localEquals(o: this): boolean;
1497
2313
  }
1498
2314
 
2315
+ /**
2316
+ * Declarative rendering data for one link. `kind` selects the package-owned
2317
+ * visual treatment; providers never supply DOM or CSS.
2318
+ */
2319
+ export declare interface LinkPresentation {
2320
+ readonly kind: LinkPresentationKind;
2321
+ readonly title?: string;
2322
+ readonly detail?: string;
2323
+ readonly reference?: string;
2324
+ /** Primary resource state, such as pull-request lifecycle or session state. */
2325
+ readonly status?: LinkPresentationStatus;
2326
+ /** Secondary state, such as pull-request CI status. */
2327
+ readonly secondaryStatus?: LinkPresentationStatus;
2328
+ readonly changes?: LinkPresentationChanges;
2329
+ readonly tooltip?: string;
2330
+ readonly ariaLabel?: string;
2331
+ }
2332
+
2333
+ declare interface LinkPresentationChanges {
2334
+ readonly insertions: number;
2335
+ readonly deletions: number;
2336
+ }
2337
+
2338
+ export declare type LinkPresentationKind = 'resource' | 'issue' | 'pullRequest' | 'commit' | 'file' | 'folder' | 'session' | 'repository' | 'branch';
2339
+
2340
+ export declare interface LinkPresentationStatus {
2341
+ readonly kind: LinkPresentationStatusKind;
2342
+ readonly label: string;
2343
+ }
2344
+
2345
+ export declare type LinkPresentationStatusKind = 'neutral' | 'pending' | 'success' | 'warning' | 'error' | 'open' | 'closed' | 'merged' | 'draft' | 'notPlanned';
2346
+
1499
2347
  declare class LinkViewData {
1500
2348
  readonly ast: LinkAstNode;
2349
+ /** Active: render the Markdown source; inactive: allow a rich presentation. */
2350
+ readonly showMarkup: boolean;
1501
2351
  readonly content: readonly AnyViewData[];
1502
2352
  readonly kind = "link";
1503
- constructor(ast: LinkAstNode, content: readonly AnyViewData[]);
2353
+ constructor(ast: LinkAstNode,
2354
+ /** Active: render the Markdown source; inactive: allow a rich presentation. */
2355
+ showMarkup: boolean, content: readonly AnyViewData[]);
1504
2356
  }
1505
2357
 
1506
2358
  export declare class ListAstNode extends BlockAstNodeBase {
1507
2359
  readonly ordered: boolean;
1508
- readonly content: readonly (ListItemAstNode | GlueAstNode)[];
2360
+ readonly content: readonly (ListItemAstNode | EmptyBlockAstNode | GlueAstNode)[];
1509
2361
  readonly leadingTrivia?: GlueAstNode | undefined;
1510
2362
  readonly kind = "list";
1511
- constructor(ordered: boolean, content: readonly (ListItemAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
2363
+ constructor(ordered: boolean, content: readonly (ListItemAstNode | EmptyBlockAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
1512
2364
  get children(): readonly AstNode[];
1513
2365
  get items(): readonly ListItemAstNode[];
1514
2366
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
@@ -1516,6 +2368,14 @@ export declare class ListAstNode extends BlockAstNodeBase {
1516
2368
  protected _localEquals(o: this): boolean;
1517
2369
  }
1518
2370
 
2371
+ declare interface ListContinuation {
2372
+ readonly item: ListItemAstNode;
2373
+ readonly level: number;
2374
+ readonly indentation: number;
2375
+ readonly mixedTasks: boolean;
2376
+ readonly outsideList: boolean;
2377
+ }
2378
+
1519
2379
  export declare class ListItemAstNode extends AstNode {
1520
2380
  readonly marker: MarkerAstNode;
1521
2381
  readonly content: readonly (BlockAstNode | GlueAstNode)[];
@@ -1525,6 +2385,7 @@ export declare class ListItemAstNode extends AstNode {
1525
2385
  constructor(marker: MarkerAstNode, content: readonly (BlockAstNode | GlueAstNode)[], checked?: boolean | undefined, leadingTrivia?: GlueAstNode | undefined);
1526
2386
  get children(): readonly AstNode[];
1527
2387
  get blocks(): readonly BlockAstNode[];
2388
+ get isIncomplete(): boolean;
1528
2389
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1529
2390
  withLeadingTrivia(trivia: GlueAstNode | undefined): ListItemAstNode;
1530
2391
  protected _localEquals(o: this): boolean;
@@ -1537,12 +2398,27 @@ declare class ListItemViewData {
1537
2398
  readonly content: readonly AnyViewData[];
1538
2399
  /** 1-based list nesting depth, used to size the indentation gutter. */
1539
2400
  readonly level: number;
2401
+ /**
2402
+ * Whether this is an inactive task item whose first paragraph begins
2403
+ * with the `:running:` marker (see {@link TextViewData.hiddenPrefixLength}).
2404
+ * Always `false` while the item is active — an active/editing task
2405
+ * reveals the literal marker instead of the progress affordance.
2406
+ */
2407
+ readonly isRunning: boolean;
2408
+ readonly sourceIndentation: number;
1540
2409
  readonly kind = "listItem";
1541
2410
  constructor(ast: ListItemAstNode,
1542
2411
  /** Whether the selection reaches this item (reveals its markers). */
1543
2412
  isActive: boolean, content: readonly AnyViewData[],
1544
2413
  /** 1-based list nesting depth, used to size the indentation gutter. */
1545
- level: number);
2414
+ level: number,
2415
+ /**
2416
+ * Whether this is an inactive task item whose first paragraph begins
2417
+ * with the `:running:` marker (see {@link TextViewData.hiddenPrefixLength}).
2418
+ * Always `false` while the item is active — an active/editing task
2419
+ * reveals the literal marker instead of the progress affordance.
2420
+ */
2421
+ isRunning?: boolean, sourceIndentation?: number);
1546
2422
  }
1547
2423
 
1548
2424
  declare class ListViewData {
@@ -1552,6 +2428,41 @@ declare class ListViewData {
1552
2428
  constructor(ast: ListAstNode, content: readonly AnyViewData[]);
1553
2429
  }
1554
2430
 
2431
+ /**
2432
+ * Compact in-memory history for editors that hold the only copy of the
2433
+ * document, such as a standalone browser page. Where the surrounding host
2434
+ * already records history — a VS Code `TextDocument` — forward to that
2435
+ * instead.
2436
+ */
2437
+ export declare class LocalHistoryStrategy implements IHistoryStrategy {
2438
+ private readonly _model;
2439
+ private readonly _past;
2440
+ private readonly _future;
2441
+ /**
2442
+ * The source text as of the last change this strategy recorded or applied.
2443
+ * Any other value means the document was replaced behind its back, so the
2444
+ * stored edits no longer line up and must be discarded rather than applied.
2445
+ */
2446
+ private _lastKnownText;
2447
+ constructor(_model: EditorModel);
2448
+ record(operation: () => void, edit?: StringEdit): void;
2449
+ undo(): void;
2450
+ redo(): void;
2451
+ /** The entry on top of `stack`, or `undefined` when it cannot be applied. */
2452
+ private _peekApplicable;
2453
+ private _apply;
2454
+ private _clear;
2455
+ }
2456
+
2457
+ export declare interface MarkdownParseOptions {
2458
+ readonly explicitBlankLineBlocks?: boolean;
2459
+ readonly explicitFinalEmptyLine?: boolean;
2460
+ readonly preserveTrailingListContinuation?: boolean;
2461
+ readonly allowEmptyListItemInterrupts?: boolean;
2462
+ readonly requireListMarkerWhitespace?: boolean;
2463
+ readonly allowEmptyTaskItems?: boolean;
2464
+ }
2465
+
1555
2466
  /**
1556
2467
  * Parses markdown into a {@link DocumentAstNode}.
1557
2468
  *
@@ -1561,7 +2472,7 @@ declare class ListViewData {
1561
2472
  * blocks keep their incremental highlighting sessions.
1562
2473
  */
1563
2474
  export declare class MarkdownParser {
1564
- parse(text: StringValue, previous?: DocumentAstNode, edit?: StringEdit): DocumentAstNode;
2475
+ parse(text: StringValue, previous?: DocumentAstNode, edit?: StringEdit, options?: MarkdownParseOptions): DocumentAstNode;
1565
2476
  }
1566
2477
 
1567
2478
  /** A semantic syntax marker (heading `#`, fences, brackets, list bullet, …). */
@@ -1658,8 +2569,8 @@ export declare class MeasuredLayoutDebugRendering {
1658
2569
  * Exposes two DOM nodes the caller can place independently:
1659
2570
  *
1660
2571
  * - {@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.
2572
+ * inside the editor overlay container so dashed line-bands and run-boxes
2573
+ * share the measured editor-local coordinates.
1663
2574
  * - {@link infoElement} — block-flow; the caller mounts it as a sibling
1664
2575
  * *below* the editor. Contains the per-block summary table that used
1665
2576
  * to live on the overlay.
@@ -1670,7 +2581,6 @@ export declare class MeasuredLayoutDebugRendering {
1670
2581
  * the derived subscribed.
1671
2582
  */
1672
2583
  export declare class MeasuredLayoutDebugView extends Disposable {
1673
- private readonly _overlayParent;
1674
2584
  readonly overlayElement: HTMLElement;
1675
2585
  readonly infoElement: HTMLElement;
1676
2586
  readonly rendering: IObservable<MeasuredLayoutDebugRendering>;
@@ -1683,6 +2593,7 @@ export declare class MeasuredLayoutDebugView extends Disposable {
1683
2593
 
1684
2594
  export declare interface MeasuredLayoutDebugViewOptions {
1685
2595
  readonly model: MeasuredLayoutModel;
2596
+ readonly coordinateSpace: EditorCoordinateSpace;
1686
2597
  /**
1687
2598
  * DEBUG ONLY. Maps an absolute source offset to a fill color for that
1688
2599
  * character's glyph rect. The fixture passes the same function to the
@@ -1715,14 +2626,16 @@ export declare interface MeasuredLayoutDebugViewOptions {
1715
2626
  * through this model and never touches view fields directly.
1716
2627
  */
1717
2628
  export declare class MeasuredLayoutModel {
1718
- readonly measurements: ISettableObservable<readonly BlockMeasurement[], void>;
2629
+ private readonly _measurements;
2630
+ readonly measurements: IObservable<readonly BlockMeasurement[]>;
2631
+ private readonly _virtualLines;
1719
2632
  /**
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.
2633
+ * Concatenated visual line map across all mounted blocks. Every per-block
2634
+ * map uses the same editor-local coordinate space, so concatenation is
2635
+ * well-formed without translation or re-sorting.
1724
2636
  */
1725
2637
  readonly visualLineMap: IObservableWithChange<VisualLineMap, void>;
2638
+ setMeasurements(measurements: readonly BlockMeasurement[], virtualLines: readonly VirtualLineMeasurement[]): void;
1726
2639
  }
1727
2640
 
1728
2641
  /**
@@ -1751,6 +2664,15 @@ export declare class MonacoSyntaxHighlighter implements ISyntaxHighlighter {
1751
2664
  private _tokenizerFor;
1752
2665
  }
1753
2666
 
2667
+ export declare const moveLinesDown: EditCommand;
2668
+
2669
+ export declare const moveLinesUp: EditCommand;
2670
+
2671
+ export declare interface NativeClipboardData {
2672
+ readonly text: string;
2673
+ readonly files: readonly File[];
2674
+ }
2675
+
1754
2676
  /**
1755
2677
  * Default strategy: handle the browser's native `copy`/`cut`/`paste` events,
1756
2678
  * reading and writing the synchronous {@link ClipboardEvent.clipboardData}.
@@ -1772,13 +2694,15 @@ declare interface NestedItem {
1772
2694
  }
1773
2695
 
1774
2696
  /**
1775
- * Move the cursor one position left or right, skipping over hidden marker
2697
+ * Move the cursor one position left or right, skipping over hidden source
1776
2698
  * ranges in inactive blocks (and inactive items of an active list).
1777
2699
  */
1778
- export declare function nextCursorPosition(doc: DocumentAstNode, activeBlock: BlockAstNode | undefined, cursor: number, direction: 'left' | 'right'): number;
2700
+ export declare function nextCursorPosition(doc: DocumentAstNode, markerVisibleBlocks: ReadonlySet<BlockAstNode>, cursor: number, direction: 'left' | 'right', selectionRange?: OffsetRange): number;
1779
2701
 
1780
2702
  declare const NO_ACTIVE_BLOCKS: unique symbol;
1781
2703
 
2704
+ export declare function normalizeCursorPosition(doc: DocumentAstNode, markerVisibleBlocks: ReadonlySet<BlockAstNode>, cursor: number, target: number, direction: 'left' | 'right', includeHiddenRangeBoundary?: boolean, selectionRange?: OffsetRange): number;
2705
+
1782
2706
  export declare class OffsetRange {
1783
2707
  readonly start: number;
1784
2708
  readonly endExclusive: number;
@@ -1806,11 +2730,19 @@ export declare class OffsetRange {
1806
2730
  toString(): string;
1807
2731
  }
1808
2732
 
2733
+ /** The lossless source slices of a block HTML comment whose closer has not been typed. */
2734
+ declare interface OpenHtmlCommentSource extends HtmlCommentSourceBase {
2735
+ readonly kind: 'open';
2736
+ }
2737
+
2738
+ /** Outdent the current line, or every line touched by the selection. */
2739
+ export declare function outdent(config?: IndentationConfig): EditCommand;
2740
+
1809
2741
  export declare class ParagraphAstNode extends BlockAstNodeBase {
1810
- readonly content: readonly (InlineAstNode | GlueAstNode)[];
2742
+ readonly content: readonly InlineContentAstNode[];
1811
2743
  readonly leadingTrivia?: GlueAstNode | undefined;
1812
2744
  readonly kind = "paragraph";
1813
- constructor(content: readonly (InlineAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
2745
+ constructor(content: readonly InlineContentAstNode[], leadingTrivia?: GlueAstNode | undefined);
1814
2746
  get children(): readonly AstNode[];
1815
2747
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
1816
2748
  withLeadingTrivia(trivia: GlueAstNode | undefined): ParagraphAstNode;
@@ -1824,23 +2756,32 @@ declare class ParagraphViewData {
1824
2756
  }
1825
2757
 
1826
2758
  /**
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).
2759
+ * A *transient* editing state: an empty paragraph adjacent to a real block.
2760
+ * Markdown has no empty-paragraph node, so this never lives in
2761
+ * {@link EditorModel['sourceText']} or the parsed {@link EditorModel.document}
2762
+ * — it is pure edit intent that the view renders as a synthetic blank line and
2763
+ * that the controller either *materializes* (the user types) or *cancels* (the
2764
+ * user navigates away / backspaces).
1833
2765
  */
1834
2766
  declare interface PendingParagraph {
1835
- /** The paragraph the blank line is rendered directly after. */
2767
+ /** The block the blank line is rendered directly after. */
1836
2768
  readonly anchorBlock: BlockAstNode;
1837
2769
  /**
1838
2770
  * Source region rewritten when the pending paragraph is materialized — the
1839
2771
  * gap between {@link anchorBlock}'s text and whatever follows it.
1840
2772
  */
1841
2773
  readonly replaceRange: OffsetRange;
2774
+ /** Whether materialized text needs a blank-line separator before it. */
2775
+ readonly separateFromPreviousBlock: boolean;
1842
2776
  /** Whether {@link replaceRange} ends at the end of the document. */
1843
2777
  readonly atEof: boolean;
2778
+ /**
2779
+ * Horizontal whitespace typed on the source-less line. It remains transient
2780
+ * until other input materializes the paragraph. Contains only spaces and tabs.
2781
+ */
2782
+ readonly text: string;
2783
+ /** The source-less visual line occupied by the pending caret. */
2784
+ readonly cursorLine: VirtualCursorLine;
1844
2785
  /**
1845
2786
  * A throwaway AST node that exists only to give the synthetic view child a
1846
2787
  * stable identity across render frames (the view pairs nodes by `ast.id`).
@@ -1849,21 +2790,51 @@ declare interface PendingParagraph {
1849
2790
  readonly syntheticAst: ParagraphAstNode;
1850
2791
  }
1851
2792
 
2793
+ declare interface PendingParagraphResult {
2794
+ readonly kind: 'pending';
2795
+ readonly anchorBlock: BlockAstNode;
2796
+ readonly replaceRange: OffsetRange;
2797
+ /** Whether materialized text needs a blank-line separator before it. */
2798
+ readonly separateFromPreviousBlock: boolean;
2799
+ readonly atEof: boolean;
2800
+ }
2801
+
1852
2802
  /**
1853
2803
  * 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.
2804
+ * model). It carries the throwaway {@link ParagraphAstNode} that gives the
2805
+ * rendered line a stable identity across frames, its anchor block, source-less
2806
+ * cursor line, and transient horizontal whitespace. It has no source content or
2807
+ * selection range.
1858
2808
  */
1859
2809
  declare class PendingParagraphViewData {
1860
2810
  readonly ast: ParagraphAstNode;
2811
+ readonly anchorBlock: BlockAstNode;
2812
+ readonly cursorLine: VirtualCursorLine;
2813
+ readonly text: string;
1861
2814
  readonly kind = "pendingParagraph";
1862
- constructor(ast: ParagraphAstNode);
2815
+ constructor(ast: ParagraphAstNode, anchorBlock: BlockAstNode, cursorLine: VirtualCursorLine, text: string);
2816
+ }
2817
+
2818
+ /**
2819
+ * The mounted transient empty paragraph: a `<p class="md-pending-paragraph">`
2820
+ * holding either a `<br>` or decorated transient horizontal whitespace. It is a
2821
+ * leaf view node with no inline source content; the document view publishes its
2822
+ * element geometry as a virtual visual line.
2823
+ */
2824
+ declare class PendingParagraphViewNode extends ViewNode {
2825
+ readonly element: HTMLElement;
2826
+ readonly anchorBlock: BlockAstNode;
2827
+ readonly cursorLine: VirtualCursorLine;
2828
+ private _text;
2829
+ constructor(view: PendingParagraphViewData);
2830
+ update(text: string): void;
2831
+ getCaretClientRect(): DOMRect;
1863
2832
  }
1864
2833
 
1865
2834
  /**
1866
- * Immutable point in 2D space, in CSS-pixel client coordinates.
2835
+ * Immutable point in a caller-defined 2D CSS-pixel coordinate space.
2836
+ * Coordinate-owning APIs must document whether values are viewport-client or
2837
+ * editor-local; values from different spaces must not be mixed.
1867
2838
  */
1868
2839
  export declare class Point2D {
1869
2840
  readonly x: number;
@@ -1873,9 +2844,25 @@ export declare class Point2D {
1873
2844
  translate(dx: number, dy: number): Point2D;
1874
2845
  }
1875
2846
 
2847
+ export declare const presentationPolicies: Readonly<Record<EditorPresentation, PresentationPolicy>>;
2848
+
2849
+ declare interface PresentationPolicy {
2850
+ readonly parseOptions: MarkdownParseOptions;
2851
+ readonly preserveSourceWhitespace: boolean;
2852
+ readonly useSourceLineBreaks: boolean;
2853
+ }
2854
+
2855
+ /**
2856
+ * Read native clipboard formats through an editable target. Electron can expose
2857
+ * file clipboard entries here that navigator.clipboard.read() omits. EditContext
2858
+ * roots themselves do not receive execCommand('paste') events.
2859
+ * Returns undefined when the host does not support native programmatic paste.
2860
+ */
2861
+ export declare function readNativeClipboard(focusTarget: HTMLElement, executePaste?: () => void): NativeClipboardData | undefined;
2862
+
1876
2863
  /**
1877
- * Immutable axis-aligned rectangle in 2D space, in CSS-pixel client
1878
- * coordinates. `x`/`y` is the top-left corner, growing right/down.
2864
+ * Immutable axis-aligned rectangle in a caller-defined 2D CSS-pixel coordinate
2865
+ * space. `x`/`y` is the top-left corner, growing right/down.
1879
2866
  *
1880
2867
  * Half-open in both dimensions: `right` and `bottom` are excluded.
1881
2868
  */
@@ -1908,6 +2895,89 @@ declare interface RemovedItem {
1908
2895
  readonly deletedLocal: readonly AnnotatedRange[];
1909
2896
  }
1910
2897
 
2898
+ export declare interface RenameAnchor {
2899
+ readonly left: number;
2900
+ readonly top: number;
2901
+ readonly height: number;
2902
+ }
2903
+
2904
+ export declare class RenameModel<TContext = undefined> {
2905
+ private readonly _options;
2906
+ readonly name: ISettableObservable<string, void>;
2907
+ private readonly _session;
2908
+ private readonly _pending;
2909
+ private readonly _failure;
2910
+ private _submission;
2911
+ private _disposed;
2912
+ readonly session: IObservable<RenameSession<TContext> | undefined>;
2913
+ readonly pending: IObservable<boolean>;
2914
+ readonly isOpen: IObservableWithChange<boolean, void>;
2915
+ readonly error: IObservableWithChange<Error | undefined, void>;
2916
+ readonly validationMessage: IObservableWithChange<string | undefined, void>;
2917
+ readonly canSubmit: IObservableWithChange<boolean, void>;
2918
+ private readonly _nameObserver;
2919
+ constructor(_options: RenameModelOptions<TContext>);
2920
+ open(session: RenameSession<TContext>): void;
2921
+ submit(): Promise<RenameSubmitResult>;
2922
+ cancel(): void;
2923
+ dispose(): void;
2924
+ private _close;
2925
+ private _abortSubmission;
2926
+ private _isCurrent;
2927
+ }
2928
+
2929
+ export declare interface RenameModelOptions<TContext = undefined> {
2930
+ readonly onSubmit: (request: RenameRequest<TContext>) => void | Promise<void>;
2931
+ readonly onCancel?: (session: RenameSession<TContext>) => void;
2932
+ readonly validate?: (name: string, session: RenameSession<TContext>) => string | undefined;
2933
+ }
2934
+
2935
+ export declare interface RenameRequest<TContext = undefined> extends RenameSession<TContext> {
2936
+ readonly name: string;
2937
+ readonly signal: AbortSignal;
2938
+ }
2939
+
2940
+ export declare interface RenameSession<TContext = undefined> {
2941
+ readonly initialName: string;
2942
+ readonly context: TContext;
2943
+ }
2944
+
2945
+ export declare type RenameSubmitResult = {
2946
+ readonly kind: 'submitted';
2947
+ readonly name: string;
2948
+ } | {
2949
+ readonly kind: 'invalid';
2950
+ readonly message: string;
2951
+ } | {
2952
+ readonly kind: 'error';
2953
+ readonly error: Error;
2954
+ } | {
2955
+ readonly kind: 'closed' | 'pending' | 'cancelled' | 'superseded';
2956
+ };
2957
+
2958
+ export declare class RenameWidget<TContext = undefined> extends Disposable {
2959
+ private readonly _container;
2960
+ private readonly _model;
2961
+ private readonly _options;
2962
+ readonly element: HTMLDivElement;
2963
+ readonly inputElement: HTMLInputElement;
2964
+ private readonly _message;
2965
+ private _anchor;
2966
+ private _focusedSession;
2967
+ constructor(_container: HTMLElement, _model: RenameModel<TContext>, _options?: RenameWidgetOptions);
2968
+ focusAndSelect(): void;
2969
+ /** Anchor coordinates are relative to the positioned container's padding box. */
2970
+ layout(anchor?: RenameAnchor): void;
2971
+ }
2972
+
2973
+ export declare interface RenameWidgetOptions {
2974
+ readonly autoFocus?: boolean;
2975
+ /** Called when a focused widget closes; the host can restore editor focus. */
2976
+ readonly onDidHide?: () => void;
2977
+ }
2978
+
2979
+ export declare type RenderMarkupText = 'none' | 'selection' | 'all';
2980
+
1911
2981
  declare interface ReplacedItem {
1912
2982
  readonly kind: 'replaced';
1913
2983
  readonly original: AstNode;
@@ -1918,6 +2988,39 @@ declare interface ReplacedItem {
1918
2988
  readonly deletedLocal: readonly AnnotatedRange[];
1919
2989
  }
1920
2990
 
2991
+ export declare class RichLink {
2992
+ private readonly _displayHints?;
2993
+ static create(options: RichLinkOptions): RichLink;
2994
+ static mount(element: HTMLElement, authoredLabel: HTMLSpanElement, displayHints?: RichLinkDisplayHints): RichLink;
2995
+ static clear(element: HTMLElement): void;
2996
+ readonly element: HTMLElement;
2997
+ readonly authoredLabel: HTMLSpanElement;
2998
+ private readonly _icon;
2999
+ private readonly _title;
3000
+ private readonly _detail;
3001
+ private readonly _reference;
3002
+ private readonly _changes;
3003
+ private readonly _status;
3004
+ private readonly _secondaryStatus;
3005
+ private constructor();
3006
+ update(presentation: LinkPresentation | undefined): void;
3007
+ private _renderUnavailable;
3008
+ private _layout;
3009
+ private _setDefaultOrder;
3010
+ }
3011
+
3012
+ declare interface RichLinkDisplayHints {
3013
+ readonly iconOnly?: boolean;
3014
+ readonly maxWidthChars?: number;
3015
+ }
3016
+
3017
+ export declare interface RichLinkOptions {
3018
+ readonly href: string;
3019
+ readonly authoredLabel: string;
3020
+ readonly presentation?: LinkPresentation;
3021
+ readonly displayHints?: RichLinkDisplayHints;
3022
+ }
3023
+
1921
3024
  export declare const selectAll: SelectionCommand;
1922
3025
 
1923
3026
  export declare function selectBlock(ctx: CursorCommandContext, blockRange: OffsetRange): Selection_2;
@@ -1925,13 +3028,14 @@ export declare function selectBlock(ctx: CursorCommandContext, blockRange: Offse
1925
3028
  declare class Selection_2 {
1926
3029
  readonly anchor: SourceOffset;
1927
3030
  readonly active: SourceOffset;
1928
- static collapsed(offset: SourceOffset): Selection_2;
1929
- constructor(anchor: SourceOffset, active: SourceOffset);
3031
+ static collapsed(offset: SourceOffset, affinity?: SourceCursorPosition['affinity']): Selection_2;
3032
+ readonly activeAffinity?: SourceCursorPosition['affinity'];
3033
+ constructor(anchor: SourceOffset, active: SourceOffset, activeAffinity?: SourceCursorPosition['affinity']);
1930
3034
  get isCollapsed(): boolean;
1931
3035
  get isForward(): boolean;
1932
3036
  get range(): OffsetRange;
1933
3037
  collapseToActive(): Selection_2;
1934
- withActive(active: SourceOffset): Selection_2;
3038
+ withActive(active: SourceOffset, affinity?: SourceCursorPosition['affinity']): Selection_2;
1935
3039
  }
1936
3040
  export { Selection_2 as Selection }
1937
3041
 
@@ -1943,8 +3047,13 @@ export { Selection_2 as Selection }
1943
3047
  export declare interface SelectionBlock {
1944
3048
  readonly block: BlockAstNode;
1945
3049
  readonly absoluteStart: number;
1946
- readonly viewNode: ViewNode;
1947
- readonly element: HTMLElement;
3050
+ /** Block border box in editor-local coordinates. */
3051
+ readonly rect: Rect2D;
3052
+ /** Visible horizontal padding-box bounds for a scrolling block. */
3053
+ readonly viewportClip: {
3054
+ readonly left: number;
3055
+ readonly right: number;
3056
+ } | undefined;
1948
3057
  }
1949
3058
 
1950
3059
  export declare type SelectionCommand = (ctx: CursorCommandContext, offset: SourceOffset) => Selection_2;
@@ -1956,6 +3065,9 @@ export declare interface SelectionRect {
1956
3065
  readonly height: number;
1957
3066
  }
1958
3067
 
3068
+ /** The interaction that produced the current editor selection. */
3069
+ export declare type SelectionSource = 'user' | 'find';
3070
+
1959
3071
  /**
1960
3072
  * Owns the SVG overlay that paints the selection.
1961
3073
  *
@@ -1976,11 +3088,10 @@ export declare interface SelectionRect {
1976
3088
  * envelope shape used by IDE selection rendering.
1977
3089
  */
1978
3090
  export declare class SelectionView extends Disposable {
1979
- private readonly _parent;
1980
3091
  readonly element: SVGSVGElement;
1981
3092
  readonly rendering: IObservable<SelectionViewRendering>;
1982
3093
  private readonly _path;
1983
- constructor(_parent: HTMLElement, options: SelectionViewOptions);
3094
+ constructor(options: SelectionViewOptions);
1984
3095
  }
1985
3096
 
1986
3097
  export declare interface SelectionViewOptions {
@@ -2008,12 +3119,9 @@ export declare type SmartEnterResult = {
2008
3119
  readonly kind: 'edit';
2009
3120
  readonly edit: StringEdit;
2010
3121
  readonly selection: Selection_2;
2011
- } | {
2012
- readonly kind: 'pending';
2013
- readonly anchorBlock: BlockAstNode;
2014
- readonly replaceRange: OffsetRange;
2015
- readonly atEof: boolean;
2016
- };
3122
+ /** Post-edit range of indentation copied onto a new fenced-code line. */
3123
+ readonly generatedIndentation?: OffsetRange;
3124
+ } | PendingParagraphResult;
2017
3125
 
2018
3126
  /**
2019
3127
  * A run of {@link Token}s together with the exact {@link OffsetRange} they
@@ -2028,34 +3136,29 @@ export declare interface SnapshotTokens {
2028
3136
  readonly tokens: readonly Token[];
2029
3137
  }
2030
3138
 
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;
3139
+ declare interface SourceCursorPosition {
3140
+ readonly kind: 'source';
3141
+ readonly offset: SourceOffset;
3142
+ /** Prefer the preceding visual line at a shared soft-wrap boundary. */
3143
+ readonly affinity?: 'upstream';
2045
3144
  }
2046
3145
 
2047
- /** The minimal widget contract a subclass must produce. */
2048
- export declare interface StackWidget {
2049
- readonly element: HTMLElement;
2050
- dispose(): void;
3146
+ /** Metadata delivered synchronously immediately before a model-owned source edit is applied. */
3147
+ export declare interface SourceEditEvent {
3148
+ readonly baseSourceTextId: number;
3149
+ readonly resultSourceTextId: number;
3150
+ readonly edit: StringEdit;
3151
+ readonly transaction: ITransaction;
2051
3152
  }
2052
3153
 
3154
+ export declare type SourceOffset = number;
3155
+
2053
3156
  export declare class StrikethroughAstNode extends AstNode {
2054
3157
  readonly openMarker: MarkerAstNode;
2055
- readonly content: readonly (InlineAstNode | GlueAstNode)[];
3158
+ readonly content: readonly InlineContentAstNode[];
2056
3159
  readonly closeMarker: MarkerAstNode;
2057
3160
  readonly kind = "strikethrough";
2058
- constructor(openMarker: MarkerAstNode, content: readonly (InlineAstNode | GlueAstNode)[], closeMarker: MarkerAstNode);
3161
+ constructor(openMarker: MarkerAstNode, content: readonly InlineContentAstNode[], closeMarker: MarkerAstNode);
2059
3162
  get children(): readonly AstNode[];
2060
3163
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
2061
3164
  }
@@ -2092,6 +3195,11 @@ export declare class StringReplacement {
2092
3195
  constructor(replaceRange: OffsetRange, newText: string);
2093
3196
  get isEmpty(): boolean;
2094
3197
  equals(other: StringReplacement): boolean;
3198
+ /**
3199
+ * Narrows this replacement to the span that actually changes, by trimming
3200
+ * the prefix and suffix it shares with the text it replaces in `source`.
3201
+ */
3202
+ removeCommonSuffixPrefix(source: string): StringReplacement;
2095
3203
  toString(): string;
2096
3204
  }
2097
3205
 
@@ -2105,10 +3213,10 @@ export declare class StringValue {
2105
3213
 
2106
3214
  export declare class StrongAstNode extends AstNode {
2107
3215
  readonly openMarker: MarkerAstNode;
2108
- readonly content: readonly (InlineAstNode | GlueAstNode)[];
3216
+ readonly content: readonly InlineContentAstNode[];
2109
3217
  readonly closeMarker: MarkerAstNode;
2110
3218
  readonly kind = "strong";
2111
- constructor(openMarker: MarkerAstNode, content: readonly (InlineAstNode | GlueAstNode)[], closeMarker: MarkerAstNode);
3219
+ constructor(openMarker: MarkerAstNode, content: readonly InlineContentAstNode[], closeMarker: MarkerAstNode);
2112
3220
  get children(): readonly AstNode[];
2113
3221
  mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
2114
3222
  }
@@ -2120,6 +3228,85 @@ declare class StrongViewData {
2120
3228
  constructor(ast: StrongAstNode, content: readonly AnyViewData[]);
2121
3229
  }
2122
3230
 
3231
+ export declare type SuggestAcceptance = 'enter' | 'tab' | 'pointer';
3232
+
3233
+ export declare interface SuggestCallbacks<T extends SuggestItem> {
3234
+ readonly onAccept: (item: T, source: SuggestAcceptance) => void;
3235
+ readonly onCancel?: () => void;
3236
+ readonly onSelect?: (item: T | undefined) => void;
3237
+ }
3238
+
3239
+ export declare interface SuggestItem {
3240
+ readonly id: string;
3241
+ readonly label: string;
3242
+ readonly detail?: string;
3243
+ readonly type?: string;
3244
+ readonly highlightLength?: number;
3245
+ }
3246
+
3247
+ export declare class SuggestModel<T extends SuggestItem = SuggestItem> {
3248
+ private readonly _callbacks;
3249
+ private readonly _state;
3250
+ readonly state: IObservable<SuggestState<T>>;
3251
+ readonly selectedItem: IObservableWithChange<T | undefined, void>;
3252
+ constructor(_callbacks: SuggestCallbacks<T>);
3253
+ show(items: readonly T[], selectedId?: string | undefined): void;
3254
+ showLoading(): void;
3255
+ showError(message: string): void;
3256
+ close(): void;
3257
+ select(id: string): boolean;
3258
+ navigate(direction: SuggestNavigation, pageSize?: number): boolean;
3259
+ accept(source?: SuggestAcceptance): boolean;
3260
+ cancel(): boolean;
3261
+ private _update;
3262
+ }
3263
+
3264
+ export declare type SuggestNavigation = 'next' | 'previous' | 'first' | 'last' | 'nextPage' | 'previousPage';
3265
+
3266
+ export declare type SuggestState<T extends SuggestItem = SuggestItem> = {
3267
+ readonly kind: 'closed';
3268
+ } | {
3269
+ readonly kind: 'loading';
3270
+ } | {
3271
+ readonly kind: 'empty';
3272
+ } | {
3273
+ readonly kind: 'error';
3274
+ readonly message: string;
3275
+ } | {
3276
+ readonly kind: 'ready';
3277
+ readonly items: readonly T[];
3278
+ readonly selectedIndex: number;
3279
+ };
3280
+
3281
+ export declare class SuggestWidget<T extends SuggestItem = SuggestItem> extends Disposable {
3282
+ private readonly _options;
3283
+ readonly element: HTMLDivElement;
3284
+ readonly listElement: HTMLDivElement;
3285
+ private readonly _message;
3286
+ private readonly _savedAttributes;
3287
+ private _items;
3288
+ private _disposed;
3289
+ private _pendingReveal;
3290
+ constructor(_options: SuggestWidgetOptions<T>);
3291
+ handleKeyDown(event: KeyboardEvent): boolean;
3292
+ dispose(): void;
3293
+ private _rowFromEvent;
3294
+ private _render;
3295
+ private _revealSelection;
3296
+ private _createRow;
3297
+ private _restoreAttributes;
3298
+ }
3299
+
3300
+ export declare interface SuggestWidgetOptions<T extends SuggestItem> {
3301
+ readonly model: SuggestModel<T>;
3302
+ readonly focusTarget: HTMLElement;
3303
+ readonly id: string;
3304
+ readonly label?: string;
3305
+ readonly listenForKeyboard?: boolean;
3306
+ }
3307
+
3308
+ export declare type TabKeyboardAction = 'insert' | 'outdent';
3309
+
2123
3310
  export declare class TableAstNode extends BlockAstNodeBase {
2124
3311
  readonly content: readonly (TableRowAstNode | GlueAstNode)[];
2125
3312
  readonly leadingTrivia?: GlueAstNode | undefined;
@@ -2182,10 +3369,10 @@ declare class TableViewData {
2182
3369
  }
2183
3370
 
2184
3371
  /**
2185
- * Source range (relative to `item`) of a task list item's `[x]`/`[ ]`
3372
+ * Source range (relative to `item`) of a task list item's `[x]`/`[ ]`/`[]`
2186
3373
  * checkbox, or `undefined` when the item is not a task item. The checkbox is
2187
3374
  * plain glue in the AST, so a host that wants to toggle it locates the literal
2188
- * `[x]`/`[ ]` token here.
3375
+ * checkbox token here.
2189
3376
  */
2190
3377
  export declare function taskCheckboxRange(item: ListItemAstNode): OffsetRange | undefined;
2191
3378
 
@@ -2202,6 +3389,14 @@ declare class TextViewData {
2202
3389
  readonly showWhitespace: boolean;
2203
3390
  readonly leftWordBoundary: boolean;
2204
3391
  readonly rightWordBoundary: boolean;
3392
+ /**
3393
+ * Number of leading source characters to keep out of the rendered
3394
+ * text (but not out of the source): the `:running:` marker plus its
3395
+ * mandatory leading separator, once
3396
+ * {@link isRunnerMarkerText} has matched this node. Zero otherwise.
3397
+ */
3398
+ readonly hiddenPrefixLength: number;
3399
+ readonly taskLabel: boolean;
2205
3400
  readonly kind = "text";
2206
3401
  /**
2207
3402
  * Whether non-obvious whitespace in this text is revealed (block is active).
@@ -2210,7 +3405,14 @@ declare class TextViewData {
2210
3405
  * emphasis); a single space touching such a sibling is obvious and stays
2211
3406
  * undecorated, just like a space between two words within this leaf.
2212
3407
  */
2213
- constructor(ast: TextAstNode, showWhitespace: boolean, leftWordBoundary?: boolean, rightWordBoundary?: boolean);
3408
+ constructor(ast: TextAstNode, showWhitespace: boolean, leftWordBoundary?: boolean, rightWordBoundary?: boolean,
3409
+ /**
3410
+ * Number of leading source characters to keep out of the rendered
3411
+ * text (but not out of the source): the `:running:` marker plus its
3412
+ * mandatory leading separator, once
3413
+ * {@link isRunnerMarkerText} has matched this node. Zero otherwise.
3414
+ */
3415
+ hiddenPrefixLength?: number, taskLabel?: boolean);
2214
3416
  }
2215
3417
 
2216
3418
  export declare class ThematicBreakAstNode extends BlockAstNodeBase {
@@ -2261,6 +3463,91 @@ declare interface UnchangedItem {
2261
3463
  readonly modifiedStart: number;
2262
3464
  }
2263
3465
 
3466
+ /**
3467
+ * A block whose token type the parser does not understand (a setext heading or
3468
+ * any future/extension construct). Rather than dropping the
3469
+ * span — which would demote its text to invisible glue — the parser captures the
3470
+ * whole source range verbatim as a single {@link MarkerAstNode} of kind
3471
+ * `content` and records the originating micromark {@link tokenType}, so the view
3472
+ * can render it as raw, editable text with an "unhandled" affordance. Offsets
3473
+ * stay sound: `content` tiles the block's full source span exactly.
3474
+ */
3475
+ declare class UnhandledBlockAstNode extends BlockAstNodeBase {
3476
+ readonly tokenType: string;
3477
+ readonly content: readonly (MarkerAstNode | GlueAstNode)[];
3478
+ readonly leadingTrivia?: GlueAstNode | undefined;
3479
+ readonly kind = "unhandledBlock";
3480
+ constructor(tokenType: string, content: readonly (MarkerAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
3481
+ get children(): readonly AstNode[];
3482
+ get code(): MarkerAstNode | undefined;
3483
+ /**
3484
+ * Lossless slices when this raw HTML block starts one comment after optional
3485
+ * whitespace. An open comment consumes the remaining source as its body. A
3486
+ * complete comment permits only trailing whitespace after its closer.
3487
+ */
3488
+ get htmlComment(): HtmlCommentSource | undefined;
3489
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
3490
+ withLeadingTrivia(trivia: GlueAstNode | undefined): UnhandledBlockAstNode;
3491
+ protected _localEquals(o: this): boolean;
3492
+ }
3493
+
3494
+ /**
3495
+ * View-data for an {@link UnhandledBlockAstNode}. The source remains verbatim
3496
+ * in both states. Complete HTML comments use {@link showMarkup} to switch
3497
+ * between their quiet reading treatment and editable source presentation;
3498
+ * other unhandled blocks ignore the flag and keep their warning treatment.
3499
+ */
3500
+ declare class UnhandledBlockViewData {
3501
+ readonly ast: UnhandledBlockAstNode;
3502
+ readonly showMarkup: boolean;
3503
+ readonly content: readonly AnyViewData[];
3504
+ readonly kind = "unhandledBlock";
3505
+ constructor(ast: UnhandledBlockAstNode, showMarkup: boolean, content: readonly AnyViewData[]);
3506
+ }
3507
+
3508
+ /**
3509
+ * A standalone HTML `<video>` whose source can be rendered without executing
3510
+ * arbitrary raw HTML. Its exact HTML remains in `content`, so activating the
3511
+ * block restores the original source for editing.
3512
+ */
3513
+ export declare class VideoAstNode extends BlockAstNodeBase {
3514
+ readonly attributes: VideoAttributes;
3515
+ readonly content: readonly (MarkerAstNode | GlueAstNode)[];
3516
+ readonly leadingTrivia?: GlueAstNode | undefined;
3517
+ readonly kind = "video";
3518
+ constructor(attributes: VideoAttributes, content: readonly (MarkerAstNode | GlueAstNode)[], leadingTrivia?: GlueAstNode | undefined);
3519
+ get children(): readonly AstNode[];
3520
+ get source(): MarkerAstNode | undefined;
3521
+ mapChildren(m: ReadonlyMap<AstNode, AstNode>): AstNode;
3522
+ withLeadingTrivia(trivia: GlueAstNode | undefined): VideoAstNode;
3523
+ protected _localEquals(o: this): boolean;
3524
+ }
3525
+
3526
+ /** The supported semantic attributes of a standalone HTML `<video>` block. */
3527
+ export declare interface VideoAttributes {
3528
+ readonly src: string;
3529
+ readonly title?: string;
3530
+ readonly autoplay: boolean;
3531
+ readonly controls: boolean;
3532
+ readonly loop: boolean;
3533
+ readonly muted: boolean;
3534
+ }
3535
+
3536
+ declare class VideoViewData {
3537
+ readonly ast: VideoAstNode;
3538
+ /** Active: reveal the exact HTML source; inactive: render the native video. */
3539
+ readonly showMarkup: boolean;
3540
+ readonly content: readonly AnyViewData[];
3541
+ /** Nested diff state; top-level video diff state lives on the document child. */
3542
+ readonly diffKind?: "added" | "modified" | undefined;
3543
+ readonly kind = "video";
3544
+ constructor(ast: VideoAstNode,
3545
+ /** Active: reveal the exact HTML source; inactive: render the native video. */
3546
+ showMarkup: boolean, content: readonly AnyViewData[],
3547
+ /** Nested diff state; top-level video diff state lives on the document child. */
3548
+ diffKind?: "added" | "modified" | undefined);
3549
+ }
3550
+
2264
3551
  /**
2265
3552
  * Immutable view of an AST node. Pairs `ast` with its rendered `dom` and a
2266
3553
  * mirror of `ast.children` as ViewNode children. Source offsets are NEVER
@@ -2352,6 +3639,24 @@ export declare class ViewNode extends Disposable {
2352
3639
  forEachTextLeaf(nodeOffset: number, visitor: (leaf: ViewNode, leafOffset: number) => void): void;
2353
3640
  }
2354
3641
 
3642
+ /**
3643
+ * A visual cursor line that has no representation in the source text.
3644
+ *
3645
+ * The two source offsets are the positions immediately before and after the
3646
+ * virtual line. The object itself is the stable identity of the line.
3647
+ */
3648
+ export declare class VirtualCursorLine {
3649
+ readonly sourceOffsetBefore: SourceOffset;
3650
+ readonly sourceOffsetAfter: SourceOffset;
3651
+ constructor(sourceOffsetBefore: SourceOffset, sourceOffsetAfter: SourceOffset);
3652
+ }
3653
+
3654
+ /** A measured source-less line inserted directly after a source block. */
3655
+ declare interface VirtualLineMeasurement {
3656
+ readonly afterBlock: BlockAstNode;
3657
+ readonly line: VisualLine;
3658
+ }
3659
+
2355
3660
  export declare type VisualCursorCommand = (ctx: VisualCursorCommandContext) => CursorMoveResult;
2356
3661
 
2357
3662
  export declare interface VisualCursorCommandContext extends CursorCommandContext {
@@ -2369,12 +3674,15 @@ export declare function visualizeAst(root: AstNode, source: string): AstVisualiz
2369
3674
  export declare class VisualLine {
2370
3675
  readonly rect: Rect2D;
2371
3676
  readonly runs: readonly VisualRun[];
2372
- constructor(rect: Rect2D, runs: readonly VisualRun[]);
3677
+ readonly virtualCursorLine?: VirtualCursorLine | undefined;
3678
+ static virtual(cursorLine: VirtualCursorLine, rect: Rect2D): VisualLine;
3679
+ constructor(rect: Rect2D, runs: readonly VisualRun[], virtualCursorLine?: VirtualCursorLine | undefined);
2373
3680
  containsOffset(offset: SourceOffset): boolean;
2374
3681
  /**
2375
3682
  * How `offset` relates to this line's runs:
2376
3683
  * - `'covers'`: a run starts at or strictly contains the offset
2377
- * (`start <= offset < endExclusive`) — the caret belongs on this line.
3684
+ * (`start <= offset < endExclusive`), or a zero-length visual-line
3685
+ * anchor sits at the offset — the caret belongs on this line.
2378
3686
  * - `'end'`: the offset is only some run's trailing boundary
2379
3687
  * (`offset === endExclusive`) with no run covering it — a line-break
2380
3688
  * boundary the caret should leave for the next line.
@@ -2387,10 +3695,27 @@ export declare class VisualLine {
2387
3695
  */
2388
3696
  sourceDistanceTo(offset: SourceOffset): number;
2389
3697
  /**
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.
3698
+ * x of the caret position before `offset` on this line.
3699
+ *
3700
+ * The runs tile the source but are stored in paint order, not sorted by
3701
+ * source offset (hidden-marker runs are appended last). So this scans all
3702
+ * runs rather than assuming any ordering:
3703
+ *
3704
+ * - A zero-source visual anchor owns its exact offset, so a marker-only line
3705
+ * wins over the preceding line's inclusive end boundary.
3706
+ * - Otherwise a run starting at `offset` owns that seam. This keeps an
3707
+ * out-of-flow prefix from placing the caret at its trailing edge when the
3708
+ * following body starts at a visually separate x.
3709
+ * - Otherwise, if some run *covers* `offset`, its own geometry places the
3710
+ * caret (exact glyph boundary for text runs). In the active,
3711
+ * markers-visible form every interior offset is covered, so this branch
3712
+ * keeps distinct offsets distinct.
3713
+ * - Otherwise `offset` sits in a gap — a hidden inline marker such as the
3714
+ * `**` of `**bold**`, or before/after the painted text. It snaps to the
3715
+ * seam between the source-nearest runs on either side: the right edge of
3716
+ * the closest run ending at/before `offset`, else the left edge of the
3717
+ * closest run starting at/after it. A hidden marker collapses to zero
3718
+ * width, so both edges coincide at the seam.
2394
3719
  */
2395
3720
  xAtOffset(offset: SourceOffset): number;
2396
3721
  /**
@@ -2404,7 +3729,8 @@ export declare class VisualLine {
2404
3729
 
2405
3730
  /**
2406
3731
  * Geometry of the rendered document, as a map from source offsets to 2D
2407
- * positions and back.
3732
+ * positions and back. All geometry is expressed in the editor overlay's local
3733
+ * CSS-pixel coordinate space.
2408
3734
  *
2409
3735
  * Structure (top to bottom):
2410
3736
  *
@@ -2439,7 +3765,9 @@ export declare class VisualLineMap {
2439
3765
  static measure(blockViews: readonly {
2440
3766
  readonly absoluteStart: number;
2441
3767
  readonly viewNode: ViewNode;
2442
- }[]): VisualLineMap;
3768
+ }[], coordinateSpace: EditorCoordinateSpace, transform?: EditorCoordinateTransform): VisualLineMap;
3769
+ /** Lines backed by source ranges, excluding source-less cursor lines. */
3770
+ readonly sourceLines: readonly VisualLine[];
2443
3771
  constructor(lines: readonly VisualLine[]);
2444
3772
  get lineCount(): number;
2445
3773
  get isEmpty(): boolean;
@@ -2458,12 +3786,18 @@ export declare class VisualLineMap {
2458
3786
  * The first such trailing-boundary line is remembered as a fallback for the
2459
3787
  * document's very last offset, where no later line starts it.
2460
3788
  */
2461
- lineIndexOfOffset(offset: SourceOffset): number;
3789
+ lineIndexOfOffset(offset: SourceOffset, affinity?: SourceCursorPosition['affinity']): number;
2462
3790
  /**
2463
3791
  * x of the caret position before `offset`, on the line returned by
2464
3792
  * {@link lineIndexOfOffset}. Returns `0` when the map is empty.
2465
3793
  */
2466
3794
  xAtOffset(offset: SourceOffset): number;
3795
+ /**
3796
+ * Line occupied by a source or virtual cursor position. A virtual position
3797
+ * returns `undefined` until its corresponding DOM line has been measured.
3798
+ */
3799
+ lineIndexOfPosition(position: CursorPosition): number | undefined;
3800
+ xAtPosition(position: CursorPosition): number;
2467
3801
  /**
2468
3802
  * Line whose vertical band contains `y`, clamped to the first/last
2469
3803
  * line when `y` is outside the document.
@@ -2475,8 +3809,13 @@ export declare class VisualLineMap {
2475
3809
  * uses {@link offsetInLineAtX} directly to preserve desired column.
2476
3810
  */
2477
3811
  offsetAtPoint(point: Point2D): SourceOffset;
3812
+ positionAtPoint(point: Point2D): SourceCursorPosition;
3813
+ positionAtOffsetInLine(lineIndex: number, offset: SourceOffset): SourceCursorPosition;
2478
3814
  /** Snap `x` to the nearest offset on a specific line. */
2479
3815
  offsetInLineAtX(lineIndex: number, x: number): SourceOffset;
3816
+ positionInLineAtX(lineIndex: number, x: number): CursorPosition;
3817
+ lineStartOffset(lineIndex: number): SourceOffset | undefined;
3818
+ lineEndOffset(lineIndex: number): SourceOffset | undefined;
2480
3819
  }
2481
3820
 
2482
3821
  /**
@@ -2498,7 +3837,9 @@ export declare class VisualRun {
2498
3837
  readonly sourceRange: OffsetRange;
2499
3838
  readonly rect: Rect2D;
2500
3839
  readonly source?: VisualRunSource | undefined;
2501
- constructor(sourceRange: OffsetRange, rect: Rect2D, source?: VisualRunSource | undefined);
3840
+ readonly isVisualLineAnchor: boolean;
3841
+ static visualLineAnchor(sourceOffset: SourceOffset, rect: Rect2D): VisualRun;
3842
+ constructor(sourceRange: OffsetRange, rect: Rect2D, source?: VisualRunSource | undefined, isVisualLineAnchor?: boolean);
2502
3843
  get sourceStart(): SourceOffset;
2503
3844
  get sourceEndExclusive(): SourceOffset;
2504
3845
  get sourceLength(): number;
@@ -2524,14 +3865,18 @@ declare interface VisualRunSource {
2524
3865
  readonly textNode: Text;
2525
3866
  /** Offset within `textNode.data` corresponding to `sourceRange.start`. */
2526
3867
  readonly textNodeStart: number;
3868
+ readonly coordinateSpace: EditorCoordinateSpace;
2527
3869
  }
2528
3870
 
2529
- export declare class VscodeStackedCommentsView extends StackedCommentsPresenter {
2530
- protected createWidget(comment: Comment_2): StackWidget;
2531
- }
3871
+ export declare const vscodeHostKeyboardProfile: KeyboardProfile;
3872
+
3873
+ export declare const vscodeKeyboardProfile: KeyboardProfile;
3874
+
3875
+ export declare const vscodeLocalKeyboardProfile: KeyboardProfile;
2532
3876
 
2533
- export declare class VsCodeV2CommentsView extends StackedCommentsPresenter {
2534
- protected createWidget(comment: Comment_2): StackWidget;
3877
+ export declare interface WordNavigationConfig {
3878
+ readonly wordSeparators: string;
3879
+ readonly wordSegmenterLocales: readonly string[];
2535
3880
  }
2536
3881
 
2537
3882
  export { }