@adecore/editor-react 0.31.11 → 0.32.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.
- package/dist/AnchoredPopup.js +73 -19
- package/dist/AttributionCard.js +162 -4
- package/dist/BaselineStatus.js +62 -8
- package/dist/CallHierarchyPanel.js +977 -60
- package/dist/ChangeReview.js +76 -25
- package/dist/CodeAuthorsCard.js +314 -14
- package/dist/CompletionPopup.js +490 -83
- package/dist/DiffView.js +548 -181
- package/dist/EditorContextMenu.js +352 -34
- package/dist/EditorView.js +276 -99
- package/dist/FindReplace.js +525 -67
- package/dist/HoverCard.js +378 -38
- package/dist/HoverSections.js +367 -56
- package/dist/LanguagePopups.js +95 -34
- package/dist/Markdown.js +41 -6
- package/dist/PanelResizeHandle.js +199 -66
- package/dist/PathText.js +49 -7
- package/dist/PeekPanel.js +675 -72
- package/dist/PickPopup.js +304 -34
- package/dist/RenameCard.js +679 -85
- package/dist/RenderedDocs.js +329 -58
- package/dist/SignatureCard.js +91 -7
- package/dist/SplitDiffView.js +344 -254
- package/dist/SymbolPicker.js +440 -85
- package/dist/call-hierarchy-model.js +102 -68
- package/dist/call-hierarchy.js +458 -359
- package/dist/code-actions-model.js +88 -76
- package/dist/code-actions.js +372 -283
- package/dist/code-authors.js +64 -55
- package/dist/code-vision-model.js +134 -127
- package/dist/code-vision.js +224 -206
- package/dist/completion-call.js +94 -67
- package/dist/completion-model.js +334 -244
- package/dist/completion.js +840 -649
- package/dist/conflict-model.js +35 -29
- package/dist/context-menu-rows.js +42 -17
- package/dist/context-menu.js +64 -46
- package/dist/definition-link.js +88 -85
- package/dist/diagnostics-model.js +74 -55
- package/dist/diagnostics.js +121 -100
- package/dist/diff-expansion.js +38 -35
- package/dist/diff-overlays.js +144 -22
- package/dist/diff-syntax.js +65 -42
- package/dist/diff-wordmarks.js +26 -23
- package/dist/doc-comment-model.js +265 -216
- package/dist/editor-language.js +177 -152
- package/dist/error-message.js +2 -2
- package/dist/find-query.js +49 -36
- package/dist/folding.js +81 -62
- package/dist/format-on-type.js +86 -67
- package/dist/highlight-layers.js +19 -20
- package/dist/highlights.js +105 -83
- package/dist/history.js +44 -38
- package/dist/holder.js +18 -18
- package/dist/host-types.js +1 -1
- package/dist/hover-content.js +167 -129
- package/dist/hover.js +285 -245
- package/dist/index.js +10 -10
- package/dist/inlay-hints.js +369 -324
- package/dist/key-priority.js +34 -31
- package/dist/language-ids.js +45 -42
- package/dist/line-edits.js +74 -28
- package/dist/line-text.js +18 -3
- package/dist/locales/en.json +38 -38
- package/dist/locales/nl.json +41 -41
- package/dist/models.js +1 -1
- package/dist/navigation-history.js +40 -41
- package/dist/navigation.js +141 -123
- package/dist/panel-size.js +8 -8
- package/dist/patch-decorations.js +236 -160
- package/dist/patch-layout.js +331 -262
- package/dist/paths.js +3 -3
- package/dist/peek-model.js +86 -69
- package/dist/peek.js +254 -192
- package/dist/pick.js +164 -157
- package/dist/popup-focus.js +5 -5
- package/dist/popup-placement.js +36 -21
- package/dist/popups.js +13 -13
- package/dist/project-language.js +228 -211
- package/dist/project-problems.js +81 -69
- package/dist/proposal-model.js +163 -126
- package/dist/recent-choices.js +25 -25
- package/dist/refresher.js +44 -49
- package/dist/rename-model.js +113 -113
- package/dist/rename.js +321 -233
- package/dist/rendered-docs.d.ts +4 -2
- package/dist/rendered-docs.js +384 -318
- package/dist/rendering-context.js +5 -3
- package/dist/rendering.js +22 -4
- package/dist/review-group.js +42 -39
- package/dist/row-host.d.ts +4 -2
- package/dist/row-host.js +90 -78
- package/dist/selection-ranges.js +21 -17
- package/dist/semantic-delta.js +22 -19
- package/dist/semantic-model.js +86 -73
- package/dist/semantic-tokens.js +201 -162
- package/dist/shortcut-keys.js +16 -10
- package/dist/signature-model.js +34 -28
- package/dist/signature.js +177 -129
- package/dist/snippet-field-transforms.js +118 -106
- package/dist/snippet-indent.js +48 -43
- package/dist/snippet-range-order.js +11 -11
- package/dist/snippet-session.js +703 -667
- package/dist/snippet-transform-client.js +59 -59
- package/dist/snippet-transform-format.js +285 -263
- package/dist/snippet-transform-protocol.js +1 -1
- package/dist/snippet-transform-queue.js +163 -153
- package/dist/snippet-transform-worker.js +42 -35
- package/dist/snippet-variable-names.js +1 -36
- package/dist/snippet-variables.js +53 -63
- package/dist/snippet.js +477 -405
- package/dist/split-alignment.js +47 -35
- package/dist/split-scroll.js +42 -40
- package/dist/symbol-links.js +33 -25
- package/dist/symbol-picker-model.js +126 -116
- package/dist/symbol-picker.js +98 -59
- package/dist/symbols.js +117 -88
- package/dist/testing.js +248 -165
- package/dist/timers.js +35 -30
- package/dist/use-panel-body.js +49 -8
- package/dist/use-problem-counts.js +29 -15
- package/dist/view-state.js +54 -33
- package/dist/word-diff.js +18 -18
- package/dist/workspace-edit.js +300 -249
- package/package.json +6 -6
- package/src/CallHierarchyPanel.tsx +2 -2
- package/src/DiffView.tsx +3 -3
- package/src/FindReplace.tsx +2 -2
- package/src/LanguagePopups.tsx +2 -0
- package/src/PeekPanel.tsx +3 -3
- package/src/RenderedDocs.tsx +9 -10
- package/src/SymbolPicker.tsx +2 -2
- package/src/diff-overlays.tsx +6 -4
- package/src/locales/en.json +38 -38
- package/src/locales/nl.json +41 -41
- package/src/rendered-docs.ts +14 -3
- package/src/row-host.ts +14 -3
package/dist/signature.js
CHANGED
|
@@ -10,142 +10,190 @@ const PAUSE_MS = 60;
|
|
|
10
10
|
* so the active parameter follows; the server answering nothing is the caret leaving the call.
|
|
11
11
|
*/
|
|
12
12
|
export class SignatureFeature {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
13
|
+
language;
|
|
14
|
+
timers;
|
|
15
|
+
timer;
|
|
16
|
+
request = 0;
|
|
17
|
+
controller = null;
|
|
18
|
+
help = null;
|
|
19
|
+
anchor = null;
|
|
20
|
+
constructor(language, timers = realTimers) {
|
|
21
|
+
this.language = language;
|
|
22
|
+
this.timers = timers;
|
|
23
|
+
const {
|
|
24
|
+
editor
|
|
25
|
+
} = language;
|
|
26
|
+
const offs = [editor.onTextChange(change => this.edited(change)), editor.onCaret(() => this.retrigger()), editor.onBlur(() => this.close()), language.onKey(event => {
|
|
27
|
+
if (event.key === 'Escape' && this.isOpen && this.language.popups.getState().callHierarchy === null) {
|
|
28
|
+
this.close();
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
if (isShortcut(this.language.shortcuts.parameterInfo, event)) {
|
|
32
|
+
this.invoke();
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
if ((event.key === 'ArrowUp' || event.key === 'ArrowDown') && !event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
|
|
36
|
+
return this.cycle(event.key === 'ArrowDown' ? 1 : -1);
|
|
37
|
+
}
|
|
38
|
+
return false;
|
|
39
|
+
}, KEY_PRIORITY.signature)];
|
|
40
|
+
language.onDispose(() => {
|
|
41
|
+
for (const off of offs) {
|
|
42
|
+
off();
|
|
43
|
+
}
|
|
44
|
+
this.close();
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
get isOpen() {
|
|
48
|
+
return this.language.popups.getState().signature !== null;
|
|
49
|
+
}
|
|
50
|
+
/* Asks for the parameters of the call at the caret, as its key does. */
|
|
51
|
+
invoke() {
|
|
52
|
+
this.ask({
|
|
53
|
+
triggerKind: 1,
|
|
54
|
+
isRetrigger: false
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/* Asks for the parameters as if `(` had just been typed, which is what a call opened by a completion is. */
|
|
58
|
+
trigger() {
|
|
59
|
+
this.ask({
|
|
60
|
+
triggerKind: 2,
|
|
61
|
+
triggerCharacter: '(',
|
|
62
|
+
isRetrigger: false
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/* Shows the next or previous overload; false when the card has fewer than two, which leaves the arrow to the caret. */
|
|
66
|
+
cycle(step) {
|
|
67
|
+
const {
|
|
68
|
+
help
|
|
69
|
+
} = this;
|
|
70
|
+
if (help === null || help.signatures.length < 2 || !this.isOpen) {
|
|
71
|
+
return false;
|
|
52
72
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
73
|
+
const count = help.signatures.length;
|
|
74
|
+
const next = {
|
|
75
|
+
...help,
|
|
76
|
+
activeSignature: (Math.min(Math.max(0, help.activeSignature ?? 0), count - 1) + step + count) % count
|
|
77
|
+
};
|
|
78
|
+
const model = signatureViewOf(next);
|
|
79
|
+
if (model === null || this.anchor === null) {
|
|
80
|
+
return false;
|
|
56
81
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
82
|
+
this.help = next;
|
|
83
|
+
this.language.popups.setState({
|
|
84
|
+
signature: {
|
|
85
|
+
anchor: this.anchor,
|
|
86
|
+
model
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
close() {
|
|
92
|
+
this.request++;
|
|
93
|
+
this.controller?.abort();
|
|
94
|
+
this.timers.clear(this.timer);
|
|
95
|
+
this.help = null;
|
|
96
|
+
this.anchor = null;
|
|
97
|
+
if (this.isOpen) {
|
|
98
|
+
this.language.popups.setState({
|
|
99
|
+
signature: null
|
|
100
|
+
});
|
|
60
101
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
102
|
+
}
|
|
103
|
+
options() {
|
|
104
|
+
const {
|
|
105
|
+
project,
|
|
106
|
+
uri
|
|
107
|
+
} = this.language;
|
|
108
|
+
const options = project.service.providerOptions(METHOD, uri);
|
|
109
|
+
return options === undefined ? null : {
|
|
110
|
+
triggers: options.triggerCharacters ?? [],
|
|
111
|
+
retriggers: options.retriggerCharacters ?? []
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
edited(change) {
|
|
115
|
+
const options = this.options();
|
|
116
|
+
if (change.source !== 'input' || options === null) {
|
|
117
|
+
this.close();
|
|
118
|
+
return;
|
|
76
119
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
120
|
+
const text = change.changes.length === 1 ? change.changes[0].text : '';
|
|
121
|
+
const last = Array.from(text).at(-1) ?? '';
|
|
122
|
+
if (text.length === 1 && options.triggers.includes(last)) {
|
|
123
|
+
this.ask({
|
|
124
|
+
triggerKind: 2,
|
|
125
|
+
triggerCharacter: last,
|
|
126
|
+
isRetrigger: this.isOpen
|
|
127
|
+
});
|
|
128
|
+
} else if (this.isOpen) {
|
|
129
|
+
this.ask({
|
|
130
|
+
triggerKind: text.length === 1 && options.retriggers.includes(last) ? 2 : 3,
|
|
131
|
+
...(options.retriggers.includes(last) ? {
|
|
132
|
+
triggerCharacter: last
|
|
133
|
+
} : {}),
|
|
134
|
+
isRetrigger: true
|
|
135
|
+
});
|
|
86
136
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
137
|
+
}
|
|
138
|
+
retrigger() {
|
|
139
|
+
if (this.isOpen) {
|
|
140
|
+
this.ask({
|
|
141
|
+
triggerKind: 3,
|
|
142
|
+
isRetrigger: true
|
|
143
|
+
});
|
|
91
144
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
if (text.length === 1 && options.triggers.includes(last)) {
|
|
101
|
-
this.ask({ triggerKind: 2, triggerCharacter: last, isRetrigger: this.isOpen });
|
|
102
|
-
}
|
|
103
|
-
else if (this.isOpen) {
|
|
104
|
-
this.ask({
|
|
105
|
-
triggerKind: text.length === 1 && options.retriggers.includes(last) ? 2 : 3,
|
|
106
|
-
...(options.retriggers.includes(last) ? { triggerCharacter: last } : {}),
|
|
107
|
-
isRetrigger: true
|
|
108
|
-
});
|
|
109
|
-
}
|
|
145
|
+
}
|
|
146
|
+
ask(context) {
|
|
147
|
+
const {
|
|
148
|
+
project,
|
|
149
|
+
uri
|
|
150
|
+
} = this.language;
|
|
151
|
+
if (!project.service.supports(METHOD, uri)) {
|
|
152
|
+
return;
|
|
110
153
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
154
|
+
this.timers.clear(this.timer);
|
|
155
|
+
const request = ++this.request;
|
|
156
|
+
const full = {
|
|
157
|
+
...context,
|
|
158
|
+
...(this.help === null ? {} : {
|
|
159
|
+
activeSignatureHelp: this.help
|
|
160
|
+
})
|
|
161
|
+
};
|
|
162
|
+
this.timer = this.timers.set(() => void this.fetch(full, request), PAUSE_MS);
|
|
163
|
+
}
|
|
164
|
+
async fetch(context, request) {
|
|
165
|
+
const {
|
|
166
|
+
editor,
|
|
167
|
+
project,
|
|
168
|
+
uri
|
|
169
|
+
} = this.language;
|
|
170
|
+
const caret = editor.getCaret();
|
|
171
|
+
this.controller?.abort();
|
|
172
|
+
const controller = new AbortController();
|
|
173
|
+
this.controller = controller;
|
|
174
|
+
let help;
|
|
175
|
+
try {
|
|
176
|
+
help = await project.service.signatureHelp(uri, caret, context, {
|
|
177
|
+
signal: controller.signal
|
|
178
|
+
});
|
|
179
|
+
} catch {
|
|
180
|
+
return;
|
|
115
181
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if (!project.service.supports(METHOD, uri)) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
this.timers.clear(this.timer);
|
|
122
|
-
const request = ++this.request;
|
|
123
|
-
const full = { ...context, ...(this.help === null ? {} : { activeSignatureHelp: this.help }) };
|
|
124
|
-
this.timer = this.timers.set(() => void this.fetch(full, request), PAUSE_MS);
|
|
182
|
+
if (request !== this.request) {
|
|
183
|
+
return;
|
|
125
184
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const controller = new AbortController();
|
|
131
|
-
this.controller = controller;
|
|
132
|
-
let help;
|
|
133
|
-
try {
|
|
134
|
-
help = await project.service.signatureHelp(uri, caret, context, { signal: controller.signal });
|
|
135
|
-
}
|
|
136
|
-
catch {
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
if (request !== this.request) {
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
const model = signatureViewOf(help);
|
|
143
|
-
if (model === null) {
|
|
144
|
-
this.close();
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
this.help = help;
|
|
148
|
-
this.anchor ??= caret;
|
|
149
|
-
this.language.popups.setState({ signature: { anchor: this.anchor, model } });
|
|
185
|
+
const model = signatureViewOf(help);
|
|
186
|
+
if (model === null) {
|
|
187
|
+
this.close();
|
|
188
|
+
return;
|
|
150
189
|
}
|
|
151
|
-
|
|
190
|
+
this.help = help;
|
|
191
|
+
this.anchor ??= caret;
|
|
192
|
+
this.language.popups.setState({
|
|
193
|
+
signature: {
|
|
194
|
+
anchor: this.anchor,
|
|
195
|
+
model
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
@@ -1,116 +1,128 @@
|
|
|
1
1
|
import { comparePositions, shiftPosition } from './diagnostics-model.js';
|
|
2
2
|
/* Navigation frames can pop before a worker replies; their tracked targets live independently. */
|
|
3
3
|
export class SnippetFieldTransforms {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
4
|
+
entries = new Set();
|
|
5
|
+
applying = null;
|
|
6
|
+
editor;
|
|
7
|
+
lease;
|
|
8
|
+
apply;
|
|
9
|
+
constructor(editor, lease, apply) {
|
|
10
|
+
this.editor = editor;
|
|
11
|
+
this.lease = lease;
|
|
12
|
+
this.apply = apply;
|
|
13
|
+
}
|
|
14
|
+
get pending() {
|
|
15
|
+
return this.entries.size > 0;
|
|
16
|
+
}
|
|
17
|
+
get ranges() {
|
|
18
|
+
return [...this.entries].reduce((sum, entry) => sum + entry.targets.length, 0);
|
|
19
|
+
}
|
|
20
|
+
async settle() {
|
|
21
|
+
await Promise.all([...this.entries].map(entry => entry.done));
|
|
22
|
+
}
|
|
23
|
+
enqueue(targets, current) {
|
|
24
|
+
if (targets.length === 0 || this.lease === null) {
|
|
25
|
+
return;
|
|
13
26
|
}
|
|
14
|
-
|
|
15
|
-
|
|
27
|
+
let finish;
|
|
28
|
+
const done = new Promise(resolve => {
|
|
29
|
+
finish = resolve;
|
|
30
|
+
});
|
|
31
|
+
const entry = {
|
|
32
|
+
targets,
|
|
33
|
+
current,
|
|
34
|
+
done,
|
|
35
|
+
finish,
|
|
36
|
+
cancelled: false
|
|
37
|
+
};
|
|
38
|
+
this.entries.add(entry);
|
|
39
|
+
const jobs = [],
|
|
40
|
+
keys = new Map();
|
|
41
|
+
const slots = targets.map(target => {
|
|
42
|
+
const job = {
|
|
43
|
+
...target.transform,
|
|
44
|
+
value: target.value
|
|
45
|
+
},
|
|
46
|
+
key = JSON.stringify(job);
|
|
47
|
+
let slot = keys.get(key);
|
|
48
|
+
if (slot === undefined) {
|
|
49
|
+
slot = jobs.length;
|
|
50
|
+
keys.set(key, slot);
|
|
51
|
+
jobs.push(job);
|
|
52
|
+
}
|
|
53
|
+
return slot;
|
|
54
|
+
});
|
|
55
|
+
const valid = () => !entry.cancelled && entry.current() && targets.every(target => this.editor.textInRange(target.range) === target.value);
|
|
56
|
+
void this.lease.request(jobs, {
|
|
57
|
+
kind: 'exit',
|
|
58
|
+
current: valid
|
|
59
|
+
}).then(values => {
|
|
60
|
+
if (!valid()) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
this.applying = entry;
|
|
64
|
+
try {
|
|
65
|
+
this.apply(targets, slots.map(slot => values[slot]));
|
|
66
|
+
} finally {
|
|
67
|
+
this.applying = null;
|
|
68
|
+
}
|
|
69
|
+
}).catch(() => {
|
|
70
|
+
/* Failed exits retain the raw field value without retrying. */
|
|
71
|
+
}).finally(() => {
|
|
72
|
+
this.entries.delete(entry);
|
|
73
|
+
finish();
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
prune() {
|
|
77
|
+
for (const entry of this.entries) {
|
|
78
|
+
if (!entry.current()) {
|
|
79
|
+
this.cancel(entry);
|
|
80
|
+
}
|
|
16
81
|
}
|
|
17
|
-
|
|
18
|
-
|
|
82
|
+
}
|
|
83
|
+
clear() {
|
|
84
|
+
for (const entry of this.entries) {
|
|
85
|
+
this.cancel(entry);
|
|
19
86
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
return slot;
|
|
43
|
-
});
|
|
44
|
-
const valid = () => !entry.cancelled && entry.current() && targets.every((target) => this.editor.textInRange(target.range) === target.value);
|
|
45
|
-
void this.lease
|
|
46
|
-
.request(jobs, { kind: 'exit', current: valid })
|
|
47
|
-
.then((values) => {
|
|
48
|
-
if (!valid()) {
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
this.applying = entry;
|
|
52
|
-
try {
|
|
53
|
-
this.apply(targets, slots.map((slot) => values[slot]));
|
|
54
|
-
}
|
|
55
|
-
finally {
|
|
56
|
-
this.applying = null;
|
|
57
|
-
}
|
|
58
|
-
})
|
|
59
|
-
.catch(() => {
|
|
60
|
-
/* Failed exits retain the raw field value without retrying. */
|
|
61
|
-
})
|
|
62
|
-
.finally(() => {
|
|
63
|
-
this.entries.delete(entry);
|
|
64
|
-
finish();
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
prune() {
|
|
68
|
-
for (const entry of this.entries) {
|
|
69
|
-
if (!entry.current()) {
|
|
70
|
-
this.cancel(entry);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
clear() {
|
|
75
|
-
for (const entry of this.entries) {
|
|
87
|
+
}
|
|
88
|
+
cancel(entry) {
|
|
89
|
+
entry.cancelled = true;
|
|
90
|
+
this.entries.delete(entry);
|
|
91
|
+
entry.finish();
|
|
92
|
+
}
|
|
93
|
+
edited(changes, detached) {
|
|
94
|
+
for (const entry of this.entries) {
|
|
95
|
+
if (entry === this.applying) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
for (const target of entry.targets) {
|
|
99
|
+
let {
|
|
100
|
+
start,
|
|
101
|
+
end
|
|
102
|
+
} = target.range;
|
|
103
|
+
for (const change of changes) {
|
|
104
|
+
const empty = comparePositions(start, end) === 0;
|
|
105
|
+
const insert = comparePositions(change.range.start, change.range.end) === 0;
|
|
106
|
+
const overlaps = insert ? empty ? comparePositions(start, change.range.start) === 0 : comparePositions(start, change.range.start) < 0 && comparePositions(change.range.start, end) < 0 : empty ? comparePositions(change.range.start, start) <= 0 && comparePositions(start, change.range.end) < 0 : comparePositions(change.range.start, end) < 0 && comparePositions(start, change.range.end) < 0;
|
|
107
|
+
if (overlaps && !(detached !== undefined && empty && insert)) {
|
|
76
108
|
this.cancel(entry);
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
const insertAtEnd = insert && !empty && comparePositions(end, change.range.start) === 0;
|
|
112
|
+
start = shiftPosition(start, change);
|
|
113
|
+
end = insertAtEnd ? end : shiftPosition(end, change);
|
|
77
114
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
continue;
|
|
88
|
-
}
|
|
89
|
-
for (const target of entry.targets) {
|
|
90
|
-
let { start, end } = target.range;
|
|
91
|
-
for (const change of changes) {
|
|
92
|
-
const empty = comparePositions(start, end) === 0;
|
|
93
|
-
const insert = comparePositions(change.range.start, change.range.end) === 0;
|
|
94
|
-
const overlaps = insert
|
|
95
|
-
? empty
|
|
96
|
-
? comparePositions(start, change.range.start) === 0
|
|
97
|
-
: comparePositions(start, change.range.start) < 0 && comparePositions(change.range.start, end) < 0
|
|
98
|
-
: empty
|
|
99
|
-
? comparePositions(change.range.start, start) <= 0 && comparePositions(start, change.range.end) < 0
|
|
100
|
-
: comparePositions(change.range.start, end) < 0 && comparePositions(start, change.range.end) < 0;
|
|
101
|
-
if (overlaps && !(detached !== undefined && empty && insert)) {
|
|
102
|
-
this.cancel(entry);
|
|
103
|
-
break;
|
|
104
|
-
}
|
|
105
|
-
const insertAtEnd = insert && !empty && comparePositions(end, change.range.start) === 0;
|
|
106
|
-
start = shiftPosition(start, change);
|
|
107
|
-
end = insertAtEnd ? end : shiftPosition(end, change);
|
|
108
|
-
}
|
|
109
|
-
target.range = detached === undefined ? { start, end } : detached({ ...target.range, order: target.order });
|
|
110
|
-
if (entry.cancelled) {
|
|
111
|
-
break;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
115
|
+
target.range = detached === undefined ? {
|
|
116
|
+
start,
|
|
117
|
+
end
|
|
118
|
+
} : detached({
|
|
119
|
+
...target.range,
|
|
120
|
+
order: target.order
|
|
121
|
+
});
|
|
122
|
+
if (entry.cancelled) {
|
|
123
|
+
break;
|
|
114
124
|
}
|
|
125
|
+
}
|
|
115
126
|
}
|
|
116
|
-
}
|
|
127
|
+
}
|
|
128
|
+
}
|
package/dist/snippet-indent.js
CHANGED
|
@@ -2,48 +2,53 @@ import { snippetOrderOf, withSnippetOrder } from './snippet-range-order.js';
|
|
|
2
2
|
import { MAX_SNIPPET_TEXT } from './snippet.js';
|
|
3
3
|
/* Indentation edits map the offsets once, including child projections in copied parents. */
|
|
4
4
|
export function indentSnippet(parsed, before) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return { text: parsed.text, stops: [], limited: true };
|
|
15
|
-
}
|
|
16
|
-
const shift = (offset, after = true) => {
|
|
17
|
-
let low = 0;
|
|
18
|
-
let high = insertions.length;
|
|
19
|
-
while (low < high) {
|
|
20
|
-
const middle = (low + high) >>> 1;
|
|
21
|
-
if (insertions[middle] < offset || (after && insertions[middle] === offset)) {
|
|
22
|
-
low = middle + 1;
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
high = middle;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
return offset + low * prefix.length;
|
|
29
|
-
};
|
|
30
|
-
const range = (range) => withSnippetOrder({
|
|
31
|
-
...range,
|
|
32
|
-
start: shift(range.start),
|
|
33
|
-
end: shift(range.end, range.start === range.end || range.tail === true)
|
|
34
|
-
}, snippetOrderOf(range));
|
|
5
|
+
const prefix = /^[\t ]*/.exec(before)?.[0] ?? '';
|
|
6
|
+
if (prefix === '' || !parsed.text.includes('\n')) {
|
|
7
|
+
return parsed;
|
|
8
|
+
}
|
|
9
|
+
const insertions = [];
|
|
10
|
+
for (let offset = parsed.text.indexOf('\n'); offset !== -1; offset = parsed.text.indexOf('\n', offset + 1)) {
|
|
11
|
+
insertions.push(offset + 1);
|
|
12
|
+
}
|
|
13
|
+
if (parsed.text.length + insertions.length * prefix.length > MAX_SNIPPET_TEXT) {
|
|
35
14
|
return {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
...(parsed.fields === undefined
|
|
40
|
-
? {}
|
|
41
|
-
: {
|
|
42
|
-
fields: parsed.fields.map((field) => ({
|
|
43
|
-
...field,
|
|
44
|
-
ranges: field.ranges.map((child) => range(child)),
|
|
45
|
-
...(field.linked === undefined ? {} : { linked: field.linked.map((child) => range(child)) })
|
|
46
|
-
}))
|
|
47
|
-
})
|
|
15
|
+
text: parsed.text,
|
|
16
|
+
stops: [],
|
|
17
|
+
limited: true
|
|
48
18
|
};
|
|
49
|
-
}
|
|
19
|
+
}
|
|
20
|
+
const shift = (offset, after = true) => {
|
|
21
|
+
let low = 0;
|
|
22
|
+
let high = insertions.length;
|
|
23
|
+
while (low < high) {
|
|
24
|
+
const middle = low + high >>> 1;
|
|
25
|
+
if (insertions[middle] < offset || after && insertions[middle] === offset) {
|
|
26
|
+
low = middle + 1;
|
|
27
|
+
} else {
|
|
28
|
+
high = middle;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return offset + low * prefix.length;
|
|
32
|
+
};
|
|
33
|
+
const range = range => withSnippetOrder({
|
|
34
|
+
...range,
|
|
35
|
+
start: shift(range.start),
|
|
36
|
+
end: shift(range.end, range.start === range.end || range.tail === true)
|
|
37
|
+
}, snippetOrderOf(range));
|
|
38
|
+
return {
|
|
39
|
+
text: parsed.text.replace(/\n/g, '\n' + prefix),
|
|
40
|
+
stops: parsed.stops.map(stop => range(stop)),
|
|
41
|
+
...(parsed.transforms === undefined ? {} : {
|
|
42
|
+
transforms: parsed.transforms.map(transform => range(transform))
|
|
43
|
+
}),
|
|
44
|
+
...(parsed.fields === undefined ? {} : {
|
|
45
|
+
fields: parsed.fields.map(field => ({
|
|
46
|
+
...field,
|
|
47
|
+
ranges: field.ranges.map(child => range(child)),
|
|
48
|
+
...(field.linked === undefined ? {} : {
|
|
49
|
+
linked: field.linked.map(child => range(child))
|
|
50
|
+
})
|
|
51
|
+
}))
|
|
52
|
+
})
|
|
53
|
+
};
|
|
54
|
+
}
|