@adecore/editor 0.22.0 → 0.23.0

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 (94) hide show
  1. package/dist/attribution.d.ts +9 -8
  2. package/dist/attribution.js +44 -9
  3. package/dist/bidi.d.ts +44 -0
  4. package/dist/bidi.js +26 -0
  5. package/dist/column-selection.js +2 -1
  6. package/dist/controller.d.ts +6 -1
  7. package/dist/controller.js +93 -3
  8. package/dist/editor.css +81 -1
  9. package/dist/engine.js +184 -41
  10. package/dist/fake.d.ts +43 -5
  11. package/dist/fake.js +117 -13
  12. package/dist/find-search.d.ts +26 -0
  13. package/dist/find-search.js +130 -0
  14. package/dist/find.d.ts +50 -2
  15. package/dist/find.js +575 -25
  16. package/dist/geometry-stops.d.ts +6 -0
  17. package/dist/geometry-stops.js +47 -0
  18. package/dist/grammar-preparation.d.ts +29 -0
  19. package/dist/grammar-preparation.js +147 -0
  20. package/dist/index.d.ts +3 -1
  21. package/dist/index.js +2 -0
  22. package/dist/keymap-table.d.ts +10 -1
  23. package/dist/keymap-table.js +37 -1
  24. package/dist/keymap.d.ts +1 -0
  25. package/dist/keymap.js +4 -1
  26. package/dist/layout-changes.d.ts +6 -0
  27. package/dist/layout-changes.js +27 -0
  28. package/dist/layout.d.ts +45 -2
  29. package/dist/layout.js +202 -58
  30. package/dist/offsets.d.ts +1 -0
  31. package/dist/offsets.js +23 -0
  32. package/dist/outline.js +5 -4
  33. package/dist/paint.d.ts +11 -3
  34. package/dist/paint.js +180 -34
  35. package/dist/search-client.d.ts +27 -0
  36. package/dist/search-client.js +210 -0
  37. package/dist/search-protocol.d.ts +103 -0
  38. package/dist/search-protocol.js +3 -0
  39. package/dist/search-worker.d.ts +11 -0
  40. package/dist/search-worker.js +137 -0
  41. package/dist/semantic.d.ts +2 -1
  42. package/dist/semantic.js +6 -1
  43. package/dist/shiki-document.d.ts +8 -0
  44. package/dist/shiki-document.js +93 -0
  45. package/dist/shiki-worker.d.ts +65 -0
  46. package/dist/shiki-worker.js +265 -0
  47. package/dist/shiki.d.ts +1 -0
  48. package/dist/shiki.js +96 -33
  49. package/dist/testing.d.ts +1 -0
  50. package/dist/tokens.d.ts +2 -0
  51. package/dist/tokens.js +37 -7
  52. package/dist/touch.d.ts +27 -0
  53. package/dist/touch.js +100 -0
  54. package/dist/types.d.ts +84 -2
  55. package/dist/uniform-geometry.d.ts +7 -0
  56. package/dist/uniform-geometry.js +49 -0
  57. package/dist/view.d.ts +68 -17
  58. package/dist/view.js +424 -97
  59. package/dist/worker-client.d.ts +37 -0
  60. package/dist/worker-client.js +195 -0
  61. package/package.json +17 -2
  62. package/src/attribution.ts +50 -14
  63. package/src/bidi.ts +32 -0
  64. package/src/column-selection.ts +2 -1
  65. package/src/controller.ts +97 -3
  66. package/src/editor.css +81 -1
  67. package/src/engine.ts +216 -42
  68. package/src/fake.ts +152 -14
  69. package/src/find-search.ts +165 -0
  70. package/src/find.ts +622 -21
  71. package/src/geometry-stops.ts +51 -0
  72. package/src/grammar-preparation.ts +158 -0
  73. package/src/index.ts +10 -0
  74. package/src/keymap-table.ts +44 -2
  75. package/src/keymap.ts +5 -1
  76. package/src/layout-changes.ts +33 -0
  77. package/src/layout.ts +262 -63
  78. package/src/offsets.ts +24 -0
  79. package/src/outline.ts +5 -4
  80. package/src/paint.ts +202 -36
  81. package/src/search-client.ts +306 -0
  82. package/src/search-protocol.ts +100 -0
  83. package/src/search-worker.ts +171 -0
  84. package/src/semantic.ts +8 -2
  85. package/src/shiki-document.ts +143 -0
  86. package/src/shiki-worker.ts +344 -0
  87. package/src/shiki.ts +103 -33
  88. package/src/testing.ts +2 -0
  89. package/src/tokens.ts +36 -7
  90. package/src/touch.ts +134 -0
  91. package/src/types.ts +174 -8
  92. package/src/uniform-geometry.ts +57 -0
  93. package/src/view.ts +500 -102
  94. package/src/worker-client.ts +212 -0
package/dist/touch.js ADDED
@@ -0,0 +1,100 @@
1
+ /* A finger that moves further than this, in pixels, is scrolling and not tapping. */
2
+ const TAP_SLOP = 10;
3
+ /* A finger held still this long selects the word under it. */
4
+ const LONG_PRESS_MS = 500;
5
+ /* A second tap this soon after the first, this close to it, is a double tap. */
6
+ const DOUBLE_TAP_MS = 300;
7
+ const DOUBLE_TAP_DISTANCE = 30;
8
+ /*
9
+ * A finger on the text. The viewport scrolls natively, so a drag is left to the browser and makes no
10
+ * selection; a tap places the caret, a double tap or a long press selects a word.
11
+ */
12
+ export class TouchSelection {
13
+ contact;
14
+ timer;
15
+ lastTap;
16
+ host;
17
+ constructor(host) {
18
+ this.host = host;
19
+ }
20
+ /* Whether the finger that is down held still long enough to select a word. */
21
+ get pressed() {
22
+ return this.contact?.pressed === true;
23
+ }
24
+ start(event, area = 'text', taken) {
25
+ this.cancel();
26
+ this.contact = { id: event.pointerId, x: event.clientX, y: event.clientY, area, moved: false, pressed: false, taken };
27
+ if (area === 'text') {
28
+ this.timer = setTimeout(() => this.press(), LONG_PRESS_MS);
29
+ }
30
+ }
31
+ move(event) {
32
+ const contact = this.contact;
33
+ if (contact === undefined || event.pointerId !== contact.id || contact.moved) {
34
+ return;
35
+ }
36
+ if (Math.abs(event.clientX - contact.x) > TAP_SLOP || Math.abs(event.clientY - contact.y) > TAP_SLOP) {
37
+ contact.moved = true;
38
+ this.clearTimer();
39
+ }
40
+ }
41
+ /* The finger lifted: a tap that did not scroll and was not a long press lands here. */
42
+ end(event) {
43
+ const contact = this.contact;
44
+ if (contact === undefined || event.pointerId !== contact.id) {
45
+ return;
46
+ }
47
+ this.cancel();
48
+ if (event.type === 'pointercancel' || contact.moved || contact.pressed) {
49
+ return;
50
+ }
51
+ this.tap(contact, event);
52
+ }
53
+ dispose() {
54
+ this.cancel();
55
+ }
56
+ tap(contact, event) {
57
+ const { model } = this.host;
58
+ const offset = this.host.offsetAt(contact.x, contact.y);
59
+ this.host.focus();
60
+ if (contact.area === 'gutter') {
61
+ const line = this.host.lineAt(offset);
62
+ model.setSelections([{ anchor: line.from, head: line.to }]);
63
+ return;
64
+ }
65
+ if (contact.taken?.()) {
66
+ return;
67
+ }
68
+ const last = this.lastTap;
69
+ const double = last !== undefined &&
70
+ event.timeStamp - last.time <= DOUBLE_TAP_MS &&
71
+ Math.abs(contact.x - last.x) <= DOUBLE_TAP_DISTANCE &&
72
+ Math.abs(contact.y - last.y) <= DOUBLE_TAP_DISTANCE;
73
+ this.lastTap = double ? undefined : { time: event.timeStamp, x: contact.x, y: contact.y };
74
+ const word = double ? model.wordSelectionAt(offset, this.host.camelHumps()) : null;
75
+ model.setSelections([word === null ? { anchor: offset, head: offset } : { anchor: word.from, head: word.to }]);
76
+ }
77
+ press() {
78
+ const contact = this.contact;
79
+ this.timer = undefined;
80
+ if (contact === undefined || contact.moved) {
81
+ return;
82
+ }
83
+ contact.pressed = true;
84
+ this.lastTap = undefined;
85
+ const offset = this.host.offsetAt(contact.x, contact.y);
86
+ const word = this.host.model.wordSelectionAt(offset, this.host.camelHumps());
87
+ this.host.focus();
88
+ this.host.model.setSelections([word === null ? { anchor: offset, head: offset } : { anchor: word.from, head: word.to }]);
89
+ }
90
+ clearTimer() {
91
+ if (this.timer !== undefined) {
92
+ clearTimeout(this.timer);
93
+ }
94
+ this.timer = undefined;
95
+ }
96
+ cancel() {
97
+ this.clearTimer();
98
+ this.contact = undefined;
99
+ }
100
+ }
package/dist/types.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { EditorSearchClientOptions } from './search-client.ts';
1
2
  import type { Keymap } from './keymap-table.ts';
2
3
  import type { EditorCommand, FoldRole } from '@adecore/editor-core';
3
4
  export type { EditorCommand, FoldRole };
@@ -14,6 +15,7 @@ export interface EditorFolds {
14
15
  }
15
16
  export type EditorTheme = string;
16
17
  export interface EditorOptions {
18
+ readonly handBack?: readonly KeyChord[];
17
19
  readonly text: string;
18
20
  readonly language?: string;
19
21
  readonly path?: string;
@@ -27,6 +29,7 @@ export interface EditorOptions {
27
29
  readonly whitespace?: boolean;
28
30
  readonly rightMargin?: number | null;
29
31
  readonly foldOutline?: EditorFoldOutline;
32
+ readonly folding?: boolean;
30
33
  readonly messages?: Partial<EditorMessages>;
31
34
  readonly label?: string;
32
35
  readonly folds?: EditorFolds;
@@ -37,6 +40,12 @@ export interface EditorOptions {
37
40
  }
38
41
  export interface EditorMessages {
39
42
  readonly noMoreOccurrences: string;
43
+ readonly fold: string;
44
+ readonly unfold: string;
45
+ }
46
+ export interface EditorInputPopup {
47
+ readonly controls: string;
48
+ readonly activeDescendant?: string;
40
49
  }
41
50
  export interface EditorSmartKeys {
42
51
  readonly autoPairBrackets: boolean;
@@ -93,8 +102,11 @@ export interface EditorLineHighlight {
93
102
  readonly color: EditorMarkColor;
94
103
  readonly fill?: EditorMarkColor;
95
104
  readonly sign?: string;
105
+ readonly bar?: 'solid' | 'hatched';
106
+ readonly emphasis?: ReadonlyArray<ReadonlyArray<readonly [number, number]>>;
96
107
  }
97
108
  export interface EditorCodeBlockOptions {
109
+ readonly tokens?: ReadonlyArray<readonly LineToken[]> | null;
98
110
  readonly firstLine?: number;
99
111
  readonly sign?: string;
100
112
  readonly color?: EditorMarkColor;
@@ -117,9 +129,14 @@ export interface EditorContentChange {
117
129
  readonly range: EditorRange;
118
130
  readonly text: string;
119
131
  }
132
+ export interface EditorApplyEditsOptions {
133
+ readonly mapSelections?: (range: EditorRange) => EditorRange;
134
+ readonly mergeUndo?: boolean;
135
+ }
120
136
  export interface EditorTextChange {
121
137
  readonly changes: readonly EditorContentChange[];
122
138
  readonly source: 'input' | 'command' | 'external';
139
+ readonly typed?: boolean;
123
140
  }
124
141
  export type EditorMarkerSeverity = 'error' | 'warning' | 'info' | 'hint';
125
142
  export interface EditorMarker {
@@ -162,6 +179,17 @@ export interface EditorWidget {
162
179
  readonly line: number;
163
180
  readonly placement?: 'above' | 'below';
164
181
  readonly height?: number;
182
+ readonly fixed?: boolean;
183
+ render(container: HTMLElement): void;
184
+ }
185
+ export interface EditorReplacement {
186
+ readonly id: string;
187
+ readonly startLine: number;
188
+ readonly endLine: number;
189
+ readonly height?: number;
190
+ readonly label?: string;
191
+ readonly enterable?: boolean;
192
+ onReveal?(): void;
165
193
  render(container: HTMLElement): void;
166
194
  }
167
195
  export interface EditorLineAction {
@@ -187,6 +215,7 @@ export interface EditorSemanticToken {
187
215
  readonly character: number;
188
216
  readonly length: number;
189
217
  readonly scopes: readonly string[];
218
+ readonly within?: LineTokenKind;
190
219
  }
191
220
  export interface ScopeStyle {
192
221
  readonly color: string;
@@ -197,7 +226,26 @@ export type ScopeColorSource = (theme: EditorTheme) => Promise<ScopeColors | nul
197
226
  export interface EditorInlayHint {
198
227
  readonly position: EditorPosition;
199
228
  readonly label: string;
229
+ readonly id?: string;
230
+ readonly parts?: readonly string[];
231
+ readonly paddingLeft?: boolean;
232
+ readonly paddingRight?: boolean;
233
+ }
234
+ export interface EditorInlayTarget {
235
+ readonly id: string;
236
+ readonly part: number | null;
237
+ readonly rect: EditorRect;
238
+ }
239
+ export interface EditorInlayClick {
240
+ readonly id: string;
241
+ readonly part: number | null;
242
+ readonly mod: boolean;
243
+ readonly alt: boolean;
244
+ readonly shift: boolean;
245
+ readonly clicks: 1 | 2;
246
+ readonly touch: boolean;
200
247
  }
248
+ export type EditorInlayClickHandler = (click: EditorInlayClick) => boolean;
201
249
  export interface EditorGhostText {
202
250
  readonly position: EditorPosition;
203
251
  readonly text: string;
@@ -207,10 +255,13 @@ export interface EditorGutterAction {
207
255
  readonly line: number;
208
256
  readonly label: string;
209
257
  }
258
+ export type EditorGutterIcon = 'sparkles' | 'book-open';
210
259
  export interface EditorGutterMarker {
211
260
  readonly id: string;
212
261
  readonly line: number;
213
262
  readonly label: string;
263
+ readonly icon?: EditorGutterIcon;
264
+ readonly pressed?: boolean;
214
265
  }
215
266
  export type EditorReveal = 'relative' | 'center' | 'centerDown' | 'centerUp';
216
267
  export interface EditorIndentation {
@@ -228,6 +279,13 @@ export interface EditorFindState {
228
279
  readonly count: number;
229
280
  readonly current: number | null;
230
281
  readonly noSelection?: boolean;
282
+ readonly limited?: boolean;
283
+ readonly searching?: boolean;
284
+ readonly failed?: 'invalid' | 'timeout' | 'unavailable' | 'error';
285
+ readonly captureFailed?: 'timeout' | 'unavailable' | 'error';
286
+ readonly replaceFailed?: 'limit' | 'timeout' | 'unavailable' | 'error';
287
+ readonly replaced?: number;
288
+ readonly large?: boolean;
231
289
  }
232
290
  export interface EditorReplaceOptions {
233
291
  readonly preserveCase?: boolean;
@@ -251,6 +309,7 @@ export interface Editor {
251
309
  findStep(direction: 1 | -1): void;
252
310
  replace(replacement: string, options?: EditorReplaceOptions): boolean;
253
311
  replaceAll(replacement: string, options?: EditorReplaceOptions): number;
312
+ replaceAllAsync(replacement: string, options?: EditorReplaceOptions): Promise<number>;
254
313
  setReplacePreview(replacement: string | null, options?: EditorReplaceOptions): void;
255
314
  selectFindMatches(): number;
256
315
  findFromCursor(query: EditorFindQuery, direction: 1 | -1): boolean;
@@ -265,12 +324,15 @@ export interface Editor {
265
324
  setFoldOutline(outline: EditorFoldOutline): void;
266
325
  setLabel(label: string): void;
267
326
  setFoldHints(hints: EditorFoldHints | null): void;
268
- setChangeMarks(marks: readonly EditorChangeMark[]): void;
327
+ setChangeMarks(marks: readonly EditorChangeMark[], layer?: string): void;
269
328
  setBlocks(blocks: readonly EditorBlock[] | null): void;
270
329
  onScope(listener: (scope: readonly EditorBlock[]) => void): () => void;
271
330
  setAttributionMarks(marks: readonly EditorAttributionMark[]): void;
272
331
  setRemoteCursors(cursors: readonly EditorRemoteCursor[]): void;
273
332
  setLineHighlights(highlights: readonly EditorLineHighlight[]): void;
333
+ setLineNumbers(labels: ((line: number) => string | null) | null): void;
334
+ setLineLabels(labels: ((line: number) => string | null) | null): void;
335
+ setLineTokens(tokens: ((line: number) => readonly LineToken[] | null | undefined) | null): void;
274
336
  renderCode(container: HTMLElement, text: string, options?: EditorCodeBlockOptions): void;
275
337
  onAttributionHover(listener: (hover: EditorAttributionHover | null) => void): () => void;
276
338
  setMarkers(markers: readonly EditorMarker[]): void;
@@ -278,6 +340,12 @@ export interface Editor {
278
340
  setLink(range: EditorRange | null): void;
279
341
  setSemanticTokens(tokens: readonly EditorSemanticToken[] | null): void;
280
342
  setInlayHints(hints: readonly EditorInlayHint[]): void;
343
+ onInlayHover?(listener: (target: EditorInlayTarget | null) => void): () => void;
344
+ onInlayClick?(handler: EditorInlayClickHandler): () => void;
345
+ setInlayLink?(target: {
346
+ readonly id: string;
347
+ readonly part: number | null;
348
+ } | null): void;
281
349
  setGhostText(ghost: EditorGhostText | null): void;
282
350
  setGutterAction(action: EditorGutterAction | null): void;
283
351
  onGutterAction(listener: (line: number) => void): () => void;
@@ -285,6 +353,11 @@ export interface Editor {
285
353
  onGutterMarker(listener: (id: string) => void): () => void;
286
354
  getCaret(): EditorPosition;
287
355
  getScrollTop(): number;
356
+ setScrollTop(top: number): void;
357
+ getLineHeight(line: number): number;
358
+ getBaseLineHeight?(): number;
359
+ onLineHeights(listener: () => void): () => void;
360
+ getContentHeight(): number;
288
361
  getFolds(): EditorFolds;
289
362
  getSelection(): EditorRange;
290
363
  getSelections(): EditorRange[];
@@ -292,12 +365,16 @@ export interface Editor {
292
365
  setCaret(position: EditorPosition, reveal?: EditorReveal): void;
293
366
  setSelection(range: EditorRange, reveal?: EditorReveal): void;
294
367
  setSelections(ranges: readonly EditorRange[], reveal?: EditorReveal): void;
368
+ setInputPopup(popup: EditorInputPopup | null): void;
369
+ announce(message: string): void;
370
+ setMessages(messages: Partial<EditorMessages>): void;
295
371
  onCaret(listener: (position: EditorPosition) => void): () => void;
296
372
  onHover(listener: (hover: EditorHover | null) => void): () => void;
297
373
  rectAt(position: EditorPosition): EditorRect | null;
298
374
  getVisibleRange(): EditorRange;
299
375
  onViewChange(listener: () => void): () => void;
300
376
  setWidgets(widgets: readonly EditorWidget[], owner?: string): void;
377
+ setReplacements?(replacements: readonly EditorReplacement[], owner?: string): void;
301
378
  setLineActions(actions: readonly EditorLineAction[], owner?: string): void;
302
379
  setCodeVision(rows: readonly EditorCodeVision[]): void;
303
380
  onClick(handler: EditorClickHandler): () => void;
@@ -305,10 +382,11 @@ export interface Editor {
305
382
  onKeyDown(handler: EditorKeyHandler): () => void;
306
383
  setSelectionRanges(provider: EditorSelectionRanges | null): void;
307
384
  trackRange(range: EditorRange): EditorTrackedRange;
308
- applyEdits(edits: readonly EditorContentChange[]): boolean;
385
+ applyEdits(edits: readonly EditorContentChange[], options?: EditorApplyEditsOptions): boolean;
309
386
  setTheme(theme: EditorTheme): void;
310
387
  refreshFont(): void;
311
388
  setReadOnly(readOnly: boolean, reason?: string): void;
389
+ isReadOnly?(): boolean;
312
390
  runCommand(command: EditorRunCommand): boolean;
313
391
  focus(): void;
314
392
  dispose(): void;
@@ -328,7 +406,9 @@ export interface LineToken {
328
406
  readonly length: number;
329
407
  readonly color: string;
330
408
  readonly fontStyle: number;
409
+ readonly kind?: LineTokenKind;
331
410
  }
411
+ export type LineTokenKind = 'comment' | 'string' | 'regex';
332
412
  export interface TokenizedLine {
333
413
  readonly tokens: readonly LineToken[];
334
414
  readonly state: unknown;
@@ -337,9 +417,11 @@ export interface LineTokenizer {
337
417
  tokenizeLine(text: string, state: unknown): TokenizedLine;
338
418
  sameState(a: unknown, b: unknown): boolean;
339
419
  stale?(): boolean;
420
+ prepare?(text: string): Promise<boolean>;
340
421
  }
341
422
  export type TokenizerSource = (language: string | undefined, theme: EditorTheme, text?: string) => Promise<LineTokenizer | null>;
342
423
  export interface SmartEditorEngineOptions {
424
+ readonly searchWorker?: EditorSearchClientOptions['workerFactory'];
343
425
  readonly keymap?: Keymap;
344
426
  readonly tokenizer: TokenizerSource;
345
427
  readonly scopeColors?: ScopeColorSource;
@@ -0,0 +1,7 @@
1
+ import type { LayoutMetrics, LineGeometry } from './layout.ts';
2
+ export declare function uniformGeometry(line: {
3
+ start: number;
4
+ end: number;
5
+ text: string;
6
+ next?: number;
7
+ }, metrics: LayoutMetrics, breaks: number[], triggers: number[], indent: number): LineGeometry | null;
@@ -0,0 +1,49 @@
1
+ export function uniformGeometry(line, metrics, breaks, triggers, indent) {
2
+ const rowStarts = [0, ...breaks];
3
+ const firstLength = rowStarts[1] ?? line.text.length;
4
+ let continuationLength = 0;
5
+ for (let row = 1; row < rowStarts.length; row++) {
6
+ continuationLength = Math.max(continuationLength, (rowStarts[row + 1] ?? line.text.length) - rowStarts[row]);
7
+ }
8
+ // A shared prefix preserves repeated floating-point addition exactly, even for fallback font metrics.
9
+ if (Math.max(firstLength, continuationLength) > 4096) {
10
+ return null;
11
+ }
12
+ const positions = (start, length) => {
13
+ const result = [start];
14
+ for (let index = 0; index < length; index++) {
15
+ result.push(result.at(-1) + metrics.charWidth);
16
+ }
17
+ return result;
18
+ };
19
+ const uniform = { first: positions(0, firstLength), continuation: positions(indent, continuationLength) };
20
+ const geometry = {
21
+ start: line.start,
22
+ end: line.end,
23
+ next: line.next ?? line.end,
24
+ text: line.text,
25
+ offsets: [],
26
+ before: [],
27
+ after: [],
28
+ rowOf: [],
29
+ rowStarts,
30
+ rowEnds: [],
31
+ rowTriggers: triggers,
32
+ runs: [],
33
+ inlays: [],
34
+ subRows: rowStarts.length,
35
+ width: 0,
36
+ uniform
37
+ };
38
+ for (let row = 0; row < rowStarts.length; row++) {
39
+ const from = rowStarts[row];
40
+ const to = rowStarts[row + 1] ?? line.text.length;
41
+ const end = uniform[row === 0 ? 'first' : 'continuation'][to - from];
42
+ geometry.rowEnds.push(end);
43
+ geometry.width = Math.max(geometry.width, end);
44
+ if (from < to) {
45
+ geometry.runs.push({ from, to, x: row === 0 ? 0 : indent, subRow: row, text: line.text.slice(from, to) });
46
+ }
47
+ }
48
+ return geometry;
49
+ }
package/dist/view.d.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  import { type DocumentModel, type FoldHints, type FoldRole, type FoldingRange, type Selection as EditorSelection } from '@adecore/editor-core';
2
+ import { type EditorSearchClientOptions } from './search-client.ts';
2
3
  import { FindController } from './find.ts';
3
- import { type BlockWidget, EditorLayout, type Inlay } from './layout.ts';
4
+ import { type BlockReplacement, type BlockWidget, EditorLayout, type Inlay } from './layout.ts';
4
5
  import { type ScrollKind } from './scroll.ts';
5
6
  import { TokenCache } from './tokens.ts';
6
- import type { EditorBlock, EditorChangeMark, EditorCodeBlockOptions, EditorFindQuery, EditorFindState, EditorHighlightKind, EditorMarkerSeverity, EditorMessages, EditorRect, EditorSmartKeys, LineTokenizer, ScopeColors } from './types.ts';
7
+ import type { EditorBlock, EditorChangeMark, EditorCodeBlockOptions, EditorFindQuery, EditorFindState, EditorHighlightKind, EditorInputPopup, EditorLineHighlight, EditorGutterIcon, EditorMarkerSeverity, EditorMessages, EditorRect, EditorSmartKeys, LineToken, LineTokenKind, LineTokenizer, ScopeColors } from './types.ts';
7
8
  export interface ViewSettings {
9
+ searchWorker?: EditorSearchClientOptions['workerFactory'];
8
10
  language: string | undefined;
9
11
  tabSize: number;
10
12
  insertSpaces: boolean;
@@ -18,6 +20,7 @@ export interface ViewSettings {
18
20
  whitespace: boolean;
19
21
  rightMargin: number | null;
20
22
  foldOutline: 'off' | 'hover' | 'always';
23
+ folding?: boolean;
21
24
  }
22
25
  export type ViewFold = Omit<FoldingRange, 'kind'> & {
23
26
  kind: FoldingRange['kind'] | 'custom';
@@ -31,6 +34,14 @@ export interface ViewSemanticToken {
31
34
  from: number;
32
35
  to: number;
33
36
  scopes: readonly string[];
37
+ within?: LineTokenKind;
38
+ }
39
+ export interface GutterMarker {
40
+ id: string;
41
+ line: number;
42
+ label: string;
43
+ icon?: EditorGutterIcon;
44
+ pressed?: boolean;
34
45
  }
35
46
  export interface ViewMarker {
36
47
  severity: EditorMarkerSeverity;
@@ -58,6 +69,7 @@ export declare class EditorView {
58
69
  private readonly preview;
59
70
  private readonly signs;
60
71
  private readonly notice;
72
+ private readonly live;
61
73
  private readonly sticky;
62
74
  private readonly overview;
63
75
  private readonly tickTip;
@@ -69,10 +81,17 @@ export declare class EditorView {
69
81
  private readonly findListeners;
70
82
  private readonly scopeListeners;
71
83
  private readonly viewListeners;
84
+ private readonly lineHeightListeners;
85
+ private announcedLineHeights;
72
86
  private readonly gutterActionListeners;
73
87
  private gutterAction;
74
88
  private readonly gutterMarkerListeners;
75
89
  private readonly gutterMarkers;
90
+ private lineTokenProvider;
91
+ private lineNumberProvider;
92
+ private lineNumberLabels;
93
+ private lineNumberRevision;
94
+ private lineNumberWidth;
76
95
  private semantic;
77
96
  private scopeColors;
78
97
  private semanticVersion;
@@ -86,8 +105,9 @@ export declare class EditorView {
86
105
  private readonly outline;
87
106
  private stickyEntries;
88
107
  private scopeKey;
89
- private changeMarks;
108
+ private readonly changeLayers;
90
109
  private changeVersion;
110
+ private changeCache;
91
111
  private readonly attribution;
92
112
  private readonly highlights;
93
113
  private remoteCarets;
@@ -111,8 +131,13 @@ export declare class EditorView {
111
131
  private frameGeometry;
112
132
  private disposed;
113
133
  private inlays;
134
+ private readonly inlayHoverListeners;
135
+ private inlayHover;
136
+ private inlayLink;
137
+ private inlayLinkElement;
114
138
  private readonly blocks;
115
139
  private lenses;
140
+ private readonly replacements;
116
141
  private occurrences;
117
142
  private replacePreview;
118
143
  private dropCaret;
@@ -133,6 +158,8 @@ export declare class EditorView {
133
158
  private foldTimer;
134
159
  private colorTimer;
135
160
  private noticeTimer;
161
+ private liveTimer;
162
+ private lineLabelProvider;
136
163
  private bracketCache;
137
164
  private wrapWidth;
138
165
  private rowEndCaret;
@@ -141,10 +168,17 @@ export declare class EditorView {
141
168
  readonly settings: ViewSettings;
142
169
  constructor(container: HTMLElement, model: DocumentModel, settings: ViewSettings);
143
170
  applySettings(): void;
171
+ repaint(): void;
144
172
  refreshFont(): void;
145
173
  setTokenizer(tokenizer: LineTokenizer | null): void;
174
+ grammarChanged(): void;
175
+ setLineTokens(tokens: ((line: number) => readonly LineToken[] | null | undefined) | null): void;
176
+ setLineNumbers(labels: ((line: number) => string | null) | null): void;
177
+ private lineNumberLabel;
146
178
  setInlays(inlays: readonly Inlay[]): void;
147
179
  setBlockWidgets(owner: string, blocks: readonly BlockWidget[]): void;
180
+ setReplacements(owner: string, replacements: readonly BlockReplacement[]): void;
181
+ private allReplacements;
148
182
  setLenses(lenses: readonly BlockWidget[]): void;
149
183
  private allBlocks;
150
184
  setOccurrences(occurrences: readonly Occurrence[]): void;
@@ -159,10 +193,15 @@ export declare class EditorView {
159
193
  setMarkers(markers: readonly ViewMarker[]): void;
160
194
  setComposition(text: string | undefined): void;
161
195
  notify(message: string): void;
196
+ private foldName;
197
+ announce(message: string): void;
198
+ setInputPopup(popup: EditorInputPopup | null): void;
199
+ setLineLabels(labels: ((line: number) => string | null) | null): void;
162
200
  get gutterElement(): HTMLElement;
163
201
  get stickyElement(): HTMLElement;
164
202
  focus(): void;
165
203
  get focused(): boolean;
204
+ get contentHeight(): number;
166
205
  get viewportHeight(): number;
167
206
  private get scrollTop();
168
207
  private get scrollLeft();
@@ -272,6 +311,9 @@ export declare class EditorView {
272
311
  markRowEnd(offset: number): void;
273
312
  onHover(listener: (offset: number | null) => void): () => void;
274
313
  private selectionOccurrences;
314
+ private get paintWindow();
315
+ private paintRectangles;
316
+ private visibleTextBounds;
275
317
  private wrapSigns;
276
318
  private indentOf;
277
319
  private effectiveIndent;
@@ -283,7 +325,26 @@ export declare class EditorView {
283
325
  setColumnMode(on: boolean): void;
284
326
  setDropCaret(offset: number | null): void;
285
327
  hoverMoved(event: PointerEvent): void;
328
+ inlayAt(target: EventTarget | null): {
329
+ id: string;
330
+ part: number | null;
331
+ element: HTMLElement;
332
+ } | null;
333
+ setInlayHover(target: EventTarget | null): void;
334
+ onInlayHover(listener: (target: {
335
+ id: string;
336
+ part: number | null;
337
+ rect: EditorRect;
338
+ } | null) => void): () => void;
339
+ setInlayLink(target: {
340
+ id: string;
341
+ part: number | null;
342
+ } | null): void;
343
+ private applyInlayLink;
286
344
  setHover(offset: number | null): void;
345
+ getLineHeight(line: number): number;
346
+ onLineHeights(listener: () => void): () => void;
347
+ setScrollTop(top: number): void;
287
348
  onViewChange(listener: () => void): () => void;
288
349
  private announceView;
289
350
  private caretOf;
@@ -309,8 +370,8 @@ export declare class EditorView {
309
370
  scrolled(): void;
310
371
  render(): void;
311
372
  private paintDecorations;
312
- setChangeMarks(marks: readonly EditorChangeMark[]): void;
313
- private markedLines;
373
+ setChangeMarks(marks: readonly EditorChangeMark[], layer?: string): void;
374
+ private resolvedChanges;
314
375
  private changedLines;
315
376
  setRemoteCarets(carets: readonly {
316
377
  id: string;
@@ -331,13 +392,7 @@ export declare class EditorView {
331
392
  endLine: number;
332
393
  color: string;
333
394
  }[]): void;
334
- setLineHighlights(highlights: readonly {
335
- startLine: number;
336
- endLine: number;
337
- color: string;
338
- sign?: string;
339
- fill?: string;
340
- }[]): void;
395
+ setLineHighlights(highlights: readonly EditorLineHighlight[]): void;
341
396
  private highlightedLines;
342
397
  private highlightMarks;
343
398
  renderCode(container: HTMLElement, text: string, options: EditorCodeBlockOptions): void;
@@ -369,11 +424,7 @@ export declare class EditorView {
369
424
  label: string;
370
425
  } | null): void;
371
426
  onGutterAction(listener: (line: number) => void): () => void;
372
- setGutterMarkers(owner: string, markers: readonly {
373
- id: string;
374
- line: number;
375
- label: string;
376
- }[]): void;
427
+ setGutterMarkers(owner: string, markers: readonly GutterMarker[]): void;
377
428
  onGutterMarker(listener: (id: string) => void): () => void;
378
429
  gutterMarkerIdOf(target: EventTarget | null): string | null;
379
430
  pressGutterMarker(id: string): void;