@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
@@ -0,0 +1,47 @@
1
+ export function stopCount(geometry) {
2
+ return geometry.uniform === undefined ? geometry.offsets.length : geometry.text.length + 1;
3
+ }
4
+ export function offsetOfStop(geometry, stop) {
5
+ return geometry.uniform === undefined ? geometry.offsets[stop] : stop;
6
+ }
7
+ export function rowOfStop(geometry, stop) {
8
+ if (geometry.uniform === undefined) {
9
+ return geometry.rowOf[stop];
10
+ }
11
+ let first = 0;
12
+ let last = geometry.rowStarts.length;
13
+ while (first < last) {
14
+ const middle = (first + last) >>> 1;
15
+ if (geometry.rowStarts[middle] <= stop) {
16
+ first = middle + 1;
17
+ }
18
+ else {
19
+ last = middle;
20
+ }
21
+ }
22
+ return Math.max(0, first - 1);
23
+ }
24
+ export function xOfStop(geometry, stop, affinity = 'before') {
25
+ if (geometry.uniform === undefined) {
26
+ return geometry[affinity][stop];
27
+ }
28
+ const row = rowOfStop(geometry, stop);
29
+ return geometry.uniform[row === 0 ? 'first' : 'continuation'][stop - geometry.rowStarts[row]];
30
+ }
31
+ export function stopAtOffset(geometry, offset) {
32
+ if (geometry.uniform !== undefined) {
33
+ return Math.min(geometry.text.length, Math.max(0, Math.ceil(offset)));
34
+ }
35
+ let first = 0;
36
+ let last = geometry.offsets.length;
37
+ while (first < last) {
38
+ const middle = (first + last) >>> 1;
39
+ if (geometry.offsets[middle] < offset) {
40
+ first = middle + 1;
41
+ }
42
+ else {
43
+ last = middle;
44
+ }
45
+ }
46
+ return Math.min(geometry.offsets.length - 1, first);
47
+ }
@@ -0,0 +1,29 @@
1
+ import type { DocumentChange, DocumentModel } from '@adecore/editor-core';
2
+ import type { LineTokenizer } from './types.ts';
3
+ type Schedule = (callback: () => void, delay: number) => () => void;
4
+ export declare class GrammarPreparation {
5
+ private tokenizer;
6
+ private generation;
7
+ private pending;
8
+ private size;
9
+ private lastLine;
10
+ private full;
11
+ private running;
12
+ private due;
13
+ private paused;
14
+ private disposed;
15
+ private cancelTimer;
16
+ private readonly model;
17
+ private readonly changed;
18
+ private readonly schedule;
19
+ constructor(model: Pick<DocumentModel, 'getText' | 'getLine' | 'positionAt'>, changed: () => void, schedule?: Schedule);
20
+ begin(): void;
21
+ ready(tokenizer: LineTokenizer | null): void;
22
+ edited(batches: readonly (readonly DocumentChange[])[]): void;
23
+ pause(paused: boolean): void;
24
+ dispose(): void;
25
+ private clear;
26
+ private scheduleFlush;
27
+ private flush;
28
+ }
29
+ export {};
@@ -0,0 +1,147 @@
1
+ const scheduleTimer = (callback, delay) => {
2
+ const timer = setTimeout(callback, delay);
3
+ return () => clearTimeout(timer);
4
+ };
5
+ const MAX_BUFFER = 64 * 1024;
6
+ /* Edits collect language declarations without making every key wait for grammar loading. */
7
+ export class GrammarPreparation {
8
+ tokenizer = null;
9
+ generation = 0;
10
+ pending = [];
11
+ size = 0;
12
+ lastLine = -1;
13
+ full = false;
14
+ running = false;
15
+ due = false;
16
+ paused = false;
17
+ disposed = false;
18
+ cancelTimer = null;
19
+ model;
20
+ changed;
21
+ schedule;
22
+ constructor(model, changed, schedule = scheduleTimer) {
23
+ this.model = model;
24
+ this.changed = changed;
25
+ this.schedule = schedule;
26
+ }
27
+ begin() {
28
+ this.generation++;
29
+ this.tokenizer = null;
30
+ this.clear();
31
+ }
32
+ ready(tokenizer) {
33
+ this.tokenizer = tokenizer;
34
+ this.scheduleFlush();
35
+ }
36
+ edited(batches) {
37
+ if (this.disposed || this.paused) {
38
+ return;
39
+ }
40
+ if (this.tokenizer === null || batches.length !== 1) {
41
+ this.full = true;
42
+ this.lastLine = -1;
43
+ }
44
+ else if (this.tokenizer.prepare === undefined) {
45
+ return;
46
+ }
47
+ else if (!this.full) {
48
+ let shift = 0;
49
+ let through = -1;
50
+ for (const change of batches[0]) {
51
+ const first = this.model.positionAt(change.from + shift).line;
52
+ const last = this.model.positionAt(change.from + shift + change.insertedLength).line;
53
+ shift += change.insertedLength - (change.to - change.from);
54
+ for (let line = Math.max(first, through + 1); line <= last; line++) {
55
+ const text = this.model.getLine(line).text;
56
+ const replacing = batches[0].length === 1 && first === last && line === this.lastLine;
57
+ if (replacing) {
58
+ this.size -= this.pending.pop().length + 1;
59
+ }
60
+ this.size += text.length + 1;
61
+ if (this.size > MAX_BUFFER) {
62
+ this.full = true;
63
+ this.pending = [];
64
+ this.lastLine = -1;
65
+ break;
66
+ }
67
+ this.pending.push(text);
68
+ this.lastLine = line;
69
+ }
70
+ through = last;
71
+ if (this.full) {
72
+ break;
73
+ }
74
+ }
75
+ }
76
+ this.scheduleFlush();
77
+ }
78
+ pause(paused) {
79
+ if (this.paused === paused) {
80
+ return;
81
+ }
82
+ this.paused = paused;
83
+ this.generation++;
84
+ this.clear();
85
+ if (!paused) {
86
+ this.full = true;
87
+ this.scheduleFlush();
88
+ }
89
+ }
90
+ dispose() {
91
+ this.disposed = true;
92
+ this.generation++;
93
+ this.clear();
94
+ this.tokenizer = null;
95
+ }
96
+ clear() {
97
+ this.cancelTimer?.();
98
+ this.cancelTimer = null;
99
+ this.pending = [];
100
+ this.size = 0;
101
+ this.lastLine = -1;
102
+ this.full = false;
103
+ this.due = false;
104
+ }
105
+ scheduleFlush() {
106
+ if (this.disposed || this.paused || this.tokenizer?.prepare === undefined || (!this.full && this.pending.length === 0)) {
107
+ return;
108
+ }
109
+ this.cancelTimer?.();
110
+ this.due = false;
111
+ this.cancelTimer = this.schedule(() => {
112
+ this.cancelTimer = null;
113
+ this.due = true;
114
+ void this.flush();
115
+ }, 200);
116
+ }
117
+ async flush() {
118
+ const tokenizer = this.tokenizer;
119
+ if (this.running || this.disposed || this.paused || tokenizer?.prepare === undefined || !this.due) {
120
+ return;
121
+ }
122
+ const generation = this.generation;
123
+ const text = this.full ? this.model.getText() : this.pending.join('\n');
124
+ this.pending = [];
125
+ this.size = 0;
126
+ this.lastLine = -1;
127
+ this.full = false;
128
+ this.due = false;
129
+ this.running = true;
130
+ try {
131
+ await tokenizer.prepare(text);
132
+ if (!this.disposed && !this.paused && generation === this.generation && tokenizer === this.tokenizer) {
133
+ // A load completed while paused may already have rebuilt this grammar.
134
+ this.changed();
135
+ }
136
+ }
137
+ catch {
138
+ // Keep the current colors; a later edit may retry the failed load.
139
+ }
140
+ finally {
141
+ this.running = false;
142
+ if (this.due) {
143
+ void this.flush();
144
+ }
145
+ }
146
+ }
147
+ }
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
+ export { MAX_REPLACEMENT_PAGE, MAX_REPLACEMENT_CHARACTERS } from './search-protocol.ts';
1
2
  export { AGENT_COLORS } from './attribution.ts';
3
+ export { findDocComments, MAX_DOC_COMMENTS, type DocComment } from '@adecore/editor-core';
2
4
  export { createSmartEditorEngine } from './engine.ts';
3
5
  export { DEFAULT_SMART_KEYS } from './smart-keys.ts';
4
6
  export { shikiScopeColors, shikiTokenizers } from './shiki.ts';
5
- export type { Editor, EditorAttributionHover, EditorAttributionMark, EditorMarkColor, EditorBlock, EditorChangeKind, EditorChangeMark, EditorCodeVision, EditorCodeVisionEntry, EditorClick, EditorCodeBlockOptions, EditorClickHandler, EditorCommand, EditorContextMenu, EditorEngine, EditorFindQuery, EditorFoldHints, EditorFoldRangeHint, EditorFoldOutline, EditorFoldRange, EditorFoldSymbol, EditorFolds, EditorFindState, EditorReplaceOptions, EditorGutterAction, EditorGutterMarker, EditorIndentation, EditorContentChange, EditorHighlight, EditorHighlightKind, EditorHover, EditorGhostText, EditorInlayHint, EditorKeyHandler, EditorLineAction, EditorLineHighlight, EditorMarker, EditorMessages, EditorMarkerSeverity, EditorReveal, EditorRect, EditorSmartKeys, EditorOptions, EditorPosition, EditorRemoteCursor, EditorRange, EditorTextChange, EditorTrackedRange, EditorRunCommand, EditorSelectionRanges, EditorTheme, EditorViewCommand, EditorWidget, FoldRole, KeyChord, LineToken, ScopeColorSource, ScopeColors, ScopeStyle, EditorSemanticToken, LineTokenizer, SmartEditorEngineOptions, TokenizedLine, TokenizerSource } from './types.ts';
7
+ export type { Editor, EditorAttributionHover, EditorAttributionMark, EditorMarkColor, EditorBlock, EditorChangeKind, EditorChangeMark, EditorCodeVision, EditorCodeVisionEntry, EditorClick, EditorCodeBlockOptions, EditorClickHandler, EditorCommand, EditorContextMenu, EditorEngine, EditorFindQuery, EditorFoldHints, EditorFoldRangeHint, EditorFoldOutline, EditorFoldRange, EditorFoldSymbol, EditorFolds, EditorFindState, EditorReplaceOptions, EditorGutterAction, EditorGutterIcon, EditorGutterMarker, EditorReplacement, EditorIndentation, EditorContentChange, EditorHighlight, EditorHighlightKind, EditorHover, EditorGhostText, EditorInlayClick, EditorInlayClickHandler, EditorInlayHint, EditorInlayTarget, EditorKeyHandler, EditorLineAction, EditorLineHighlight, EditorMarker, EditorInputPopup, EditorMessages, EditorMarkerSeverity, EditorReveal, EditorRect, EditorSmartKeys, EditorOptions, EditorPosition, EditorRemoteCursor, EditorRange, EditorApplyEditsOptions, EditorTextChange, EditorTrackedRange, EditorRunCommand, EditorSelectionRanges, EditorTheme, EditorViewCommand, EditorWidget, FoldRole, KeyChord, LineToken, LineTokenKind, ScopeColorSource, ScopeColors, ScopeStyle, EditorSemanticToken, LineTokenizer, SmartEditorEngineOptions, TokenizedLine, TokenizerSource } from './types.ts';
package/dist/index.js CHANGED
@@ -1,4 +1,6 @@
1
+ export { MAX_REPLACEMENT_PAGE, MAX_REPLACEMENT_CHARACTERS } from './search-protocol.js';
1
2
  export { AGENT_COLORS } from './attribution.js';
3
+ export { findDocComments, MAX_DOC_COMMENTS } from '@adecore/editor-core';
2
4
  export { createSmartEditorEngine } from './engine.js';
3
5
  export { DEFAULT_SMART_KEYS } from './smart-keys.js';
4
6
  export { shikiScopeColors, shikiTokenizers } from './shiki.js';
@@ -82,6 +82,8 @@ export declare const KEYMAP: {
82
82
  readonly goToImplementation: KeyBinding;
83
83
  readonly peekDefinition: KeyBinding;
84
84
  readonly peekReferences: KeyBinding;
85
+ readonly callHierarchy: KeyBinding;
86
+ readonly toggleRenderedDocs: KeyBinding;
85
87
  readonly historyBack: KeyBinding;
86
88
  readonly historyForward: KeyBinding;
87
89
  readonly recentLocations: KeyBinding;
@@ -94,9 +96,16 @@ export declare const KEYMAP: {
94
96
  readonly replace: KeyBinding;
95
97
  };
96
98
  export type KeymapId = keyof typeof KEYMAP;
97
- export type Keymap = Readonly<Record<KeymapId, KeyBinding>>;
99
+ export type OptionalKeymapId = 'toggleRenderedDocs';
100
+ export type Keymap = Readonly<Record<Exclude<KeymapId, OptionalKeymapId>, KeyBinding> & Partial<Record<OptionalKeymapId, KeyBinding>>>;
98
101
  export type KeymapOverrides = Partial<Record<KeymapId, Partial<KeyBinding>>>;
99
102
  export declare const KEYMAP_IDS: KeymapId[];
100
103
  export declare function resolveKeymap(overrides?: KeymapOverrides): Keymap;
101
104
  export declare function chordOf(id: KeymapId, apple: boolean, keymap?: Keymap): string | null;
102
105
  export declare function parseChord(text: string): KeyChord;
106
+ export declare function typesInsteadOfChord(event: {
107
+ key: string;
108
+ code?: string;
109
+ ctrlKey: boolean;
110
+ altKey: boolean;
111
+ }, apple: boolean): boolean;
@@ -81,6 +81,8 @@ export const KEYMAP = {
81
81
  goToImplementation: bind('Mod+Alt+B'),
82
82
  peekDefinition: bind('Alt+Space', 'Ctrl+Shift+I'),
83
83
  peekReferences: bind('Alt+F7'),
84
+ callHierarchy: bind('Ctrl+Alt+H'),
85
+ toggleRenderedDocs: bind('Ctrl+Alt+Q'),
84
86
  historyBack: bind('Mod+[', 'Ctrl+Alt+ArrowLeft'),
85
87
  historyForward: bind('Mod+]', 'Ctrl+Alt+ArrowRight'),
86
88
  recentLocations: bind('Mod+Shift+E'),
@@ -98,7 +100,7 @@ export function resolveKeymap(overrides = {}) {
98
100
  }
99
101
  /* The chord of a command on a platform, or null when the platform has none. */
100
102
  export function chordOf(id, apple, keymap = KEYMAP) {
101
- return keymap[id][apple ? 'mac' : 'other'];
103
+ return (keymap[id] ?? KEYMAP[id])[apple ? 'mac' : 'other'];
102
104
  }
103
105
  const MODIFIERS = new Map([
104
106
  ['Mod', 'mod'],
@@ -128,3 +130,37 @@ export function parseChord(text) {
128
130
  }
129
131
  return chord;
130
132
  }
133
+ const BASE_PUNCTUATION = {
134
+ Comma: ',',
135
+ Period: '.',
136
+ Slash: '/',
137
+ Semicolon: ';',
138
+ Quote: "'",
139
+ Backquote: '`',
140
+ Backslash: '\\',
141
+ BracketLeft: '[',
142
+ BracketRight: ']',
143
+ Minus: '-',
144
+ Equal: '='
145
+ };
146
+ /* The character a physical key has with no layer on it, null for a key that has none, such as an arrow or Enter. */
147
+ function baseCharacter(code) {
148
+ const letter = /^Key([A-Z])$/.exec(code);
149
+ if (letter !== null) {
150
+ return letter[1].toLowerCase();
151
+ }
152
+ const digit = /^(?:Digit|Numpad)([0-9])$/.exec(code);
153
+ return digit !== null ? digit[1] : (BASE_PUNCTUATION[code] ?? null);
154
+ }
155
+ /*
156
+ * Whether Ctrl and Alt together type a character instead of pressing a chord. AltGr reports both, on Windows even
157
+ * for the left Ctrl and Alt, and a browser may report AltGraph for Option, so the state is no evidence: the character is.
158
+ * Never on Apple platforms, where Option types with no Ctrl.
159
+ */
160
+ export function typesInsteadOfChord(event, apple) {
161
+ if (apple || !event.ctrlKey || !event.altKey || event.code === undefined || [...event.key].length !== 1) {
162
+ return false;
163
+ }
164
+ const base = baseCharacter(event.code);
165
+ return base !== null && event.key.toLowerCase() !== base;
166
+ }
package/dist/keymap.d.ts CHANGED
@@ -8,6 +8,7 @@ export interface KeyLike {
8
8
  metaKey: boolean;
9
9
  altKey: boolean;
10
10
  shiftKey: boolean;
11
+ getModifierState?(key: string): boolean;
11
12
  }
12
13
  export type MoveKey = 'ArrowLeft' | 'ArrowRight' | 'ArrowUp' | 'ArrowDown' | 'PageUp' | 'PageDown';
13
14
  export type KeyAction = {
package/dist/keymap.js CHANGED
@@ -1,4 +1,4 @@
1
- import { chordOf, KEYMAP, KEYMAP_IDS, parseChord } from './keymap-table.js';
1
+ import { chordOf, KEYMAP, KEYMAP_IDS, parseChord, typesInsteadOfChord } from './keymap-table.js';
2
2
  const MOVES = new Set(['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'PageUp', 'PageDown']);
3
3
  function command(name) {
4
4
  return { type: 'command', command: name };
@@ -98,6 +98,9 @@ function keyMatches(chordKey, event) {
98
98
  }
99
99
  /* Whether an event is a chord, with `mod` as Cmd on macOS and Ctrl elsewhere and every modifier the chord does not name up. */
100
100
  export function chordMatches(chord, event, apple) {
101
+ if (typesInsteadOfChord(event, apple)) {
102
+ return false;
103
+ }
101
104
  const wantsMeta = chord.meta || (chord.mod && apple);
102
105
  const wantsCtrl = chord.ctrl || (chord.mod && !apple);
103
106
  return (wantsMeta === event.metaKey &&
@@ -0,0 +1,6 @@
1
+ import type { DocumentChange } from '@adecore/editor-core';
2
+ export interface LineBounds {
3
+ start: number;
4
+ end: number;
5
+ }
6
+ export declare function lineChangeMapper(batches: readonly (readonly DocumentChange[])[]): (bounds: LineBounds) => LineBounds | null;
@@ -0,0 +1,27 @@
1
+ import { offsetMapper } from './offsets.js';
2
+ export function lineChangeMapper(batches) {
3
+ const steps = batches.map((changes) => ({ changes, map: offsetMapper(changes) }));
4
+ return (bounds) => {
5
+ let { start, end } = bounds;
6
+ for (const { changes, map } of steps) {
7
+ let first = 0;
8
+ let last = changes.length;
9
+ while (first < last) {
10
+ const middle = (first + last) >>> 1;
11
+ if (changes[middle].to < start) {
12
+ first = middle + 1;
13
+ }
14
+ else {
15
+ last = middle;
16
+ }
17
+ }
18
+ // Touching either boundary can merge lines or change a CRLF ending.
19
+ if (changes[first] !== undefined && changes[first].from <= end) {
20
+ return null;
21
+ }
22
+ start = map(start);
23
+ end = map(end);
24
+ }
25
+ return { start, end };
26
+ };
27
+ }
package/dist/layout.d.ts CHANGED
@@ -1,5 +1,14 @@
1
- import type { Position } from '@adecore/editor-core';
1
+ import type { DocumentChange, Position } from '@adecore/editor-core';
2
2
  export type Affinity = 'before' | 'after';
3
+ export interface VerticalWindow {
4
+ top: number;
5
+ bottom: number;
6
+ }
7
+ export interface SubRowBand {
8
+ first: number;
9
+ last: number;
10
+ }
11
+ export declare function subRowBand(top: number, subRows: number, lineHeight: number, window: VerticalWindow, block?: number): SubRowBand;
3
12
  export interface LayoutDocument {
4
13
  getLineCount(): number;
5
14
  getLine(line: number): {
@@ -22,6 +31,9 @@ export interface Inlay {
22
31
  at: number;
23
32
  text: string;
24
33
  tooltip?: string;
34
+ parts?: readonly string[];
35
+ gapLeft?: number;
36
+ gapRight?: number;
25
37
  composition?: boolean;
26
38
  ghost?: boolean;
27
39
  }
@@ -34,6 +46,18 @@ export interface BlockWidget {
34
46
  height?: number;
35
47
  revision?: number;
36
48
  lens?: boolean;
49
+ fixed?: boolean;
50
+ }
51
+ export interface BlockReplacement {
52
+ id: string;
53
+ from: number;
54
+ to: number;
55
+ render: (container: HTMLElement) => void;
56
+ height?: number;
57
+ revision?: number;
58
+ label?: string;
59
+ enterable?: boolean;
60
+ onReveal?: () => void;
37
61
  }
38
62
  export interface FoldState {
39
63
  startLine: number;
@@ -55,6 +79,7 @@ export interface TextRow extends RowBase {
55
79
  tail: number | null;
56
80
  head: number | null;
57
81
  subRows: number;
82
+ replacement?: BlockReplacement;
58
83
  }
59
84
  export interface BlockRow extends RowBase {
60
85
  kind: 'block';
@@ -77,6 +102,7 @@ export interface InlineBox {
77
102
  export interface LineGeometry {
78
103
  start: number;
79
104
  end: number;
105
+ next: number;
80
106
  text: string;
81
107
  offsets: number[];
82
108
  before: number[];
@@ -84,6 +110,11 @@ export interface LineGeometry {
84
110
  rowOf: number[];
85
111
  rowStarts: number[];
86
112
  rowEnds: number[];
113
+ rowTriggers: number[];
114
+ uniform?: {
115
+ first: readonly number[];
116
+ continuation: readonly number[];
117
+ };
87
118
  runs: TextRun[];
88
119
  inlays: InlineBox[];
89
120
  subRows: number;
@@ -100,22 +131,32 @@ export declare const BOTTOM_PADDING = 8;
100
131
  export declare const RIGHT_PADDING = 16;
101
132
  export declare function wrapIndent(text: string, metrics: LayoutMetrics, limit: number): number;
102
133
  export declare function wrapStops(text: string, offsets: readonly number[], metrics: LayoutMetrics, limit: number): number[];
134
+ export declare function scanDenseLine(line: {
135
+ start: number;
136
+ end: number;
137
+ text: string;
138
+ next?: number;
139
+ }, metrics: LayoutMetrics, limit: number | null, lineInlays: readonly Inlay[]): LineGeometry;
103
140
  export declare function scanLine(line: {
104
141
  start: number;
105
142
  end: number;
106
143
  text: string;
144
+ next?: number;
107
145
  }, metrics: LayoutMetrics, limit: number | null, lineInlays: readonly Inlay[]): LineGeometry;
108
146
  export interface LayoutConfig {
109
147
  textChanged?: boolean;
148
+ changes?: readonly (readonly DocumentChange[])[];
110
149
  metrics?: LayoutMetrics;
111
150
  wrapWidth?: number | null;
112
151
  inlays?: readonly Inlay[];
113
152
  blocks?: readonly BlockWidget[];
114
153
  folds?: readonly FoldState[];
154
+ replacements?: readonly BlockReplacement[];
115
155
  }
116
156
  export declare class EditorLayout {
117
157
  rows: LayoutRow[];
118
158
  height: number;
159
+ lineHeightsVersion: number;
119
160
  width: number;
120
161
  private lineRows;
121
162
  private geometryCache;
@@ -125,12 +166,14 @@ export declare class EditorLayout {
125
166
  private inlays;
126
167
  private blocks;
127
168
  private folds;
169
+ private replacements;
128
170
  private wrapWidth;
129
171
  readonly document: LayoutDocument;
130
172
  metrics: LayoutMetrics;
131
173
  constructor(document: LayoutDocument, metrics: LayoutMetrics);
132
174
  get wrapping(): boolean;
133
175
  configure(config: LayoutConfig): void;
176
+ private retainGeometry;
134
177
  private rowCountOf;
135
178
  private rebuild;
136
179
  private clampToLine;
@@ -163,7 +206,7 @@ export declare class EditorLayout {
163
206
  offset: number;
164
207
  rowEnd: boolean;
165
208
  };
166
- rectangles(from: number, to: number, rows: readonly LayoutRow[]): LayoutRect[];
209
+ rectangles(from: number, to: number, rows: readonly LayoutRow[], window?: VerticalWindow): LayoutRect[];
167
210
  verticalOffset(offset: number, direction: -1 | 1, x: number, distance?: number): number;
168
211
  horizontalOffset(offset: number, direction: -1 | 1): number;
169
212
  }