@adecore/editor-react 0.42.0 → 0.44.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/CallHierarchyPanel.js +177 -181
- package/dist/EditorContextMenu.js +118 -105
- package/dist/LanguagePopups.js +7 -0
- package/dist/PickPopup.js +245 -104
- package/dist/WrapCard.d.ts +8 -0
- package/dist/WrapCard.js +172 -0
- package/dist/call-hierarchy-model.d.ts +4 -2
- package/dist/call-hierarchy-model.js +20 -0
- package/dist/call-hierarchy.d.ts +3 -0
- package/dist/call-hierarchy.js +54 -22
- package/dist/clipboard-history.d.ts +31 -0
- package/dist/clipboard-history.js +70 -0
- package/dist/code-actions.d.ts +3 -1
- package/dist/code-actions.js +50 -10
- package/dist/code-vision.js +2 -3
- package/dist/completion.d.ts +28 -0
- package/dist/completion.js +83 -27
- package/dist/context-menu-rows.d.ts +1 -1
- package/dist/context-menu-rows.js +4 -0
- package/dist/definition-link.js +15 -5
- package/dist/document-colors.d.ts +24 -0
- package/dist/document-colors.js +194 -0
- package/dist/document-links.d.ts +22 -0
- package/dist/document-links.js +133 -0
- package/dist/document-query.d.ts +15 -0
- package/dist/document-query.js +54 -0
- package/dist/edit-locations.d.ts +20 -0
- package/dist/edit-locations.js +136 -0
- package/dist/editor-language.d.ts +23 -1
- package/dist/editor-language.js +83 -2
- package/dist/emmet.d.ts +13 -0
- package/dist/emmet.js +62 -0
- package/dist/folding.js +2 -3
- package/dist/format-on-type.js +3 -5
- package/dist/highlights.js +2 -3
- package/dist/history.d.ts +7 -0
- package/dist/history.js +79 -1
- package/dist/host-types.d.ts +10 -0
- package/dist/index.d.ts +13 -2
- package/dist/index.js +10 -0
- package/dist/inlay-hints.js +2 -2
- package/dist/inline-completion.d.ts +39 -0
- package/dist/inline-completion.js +221 -0
- package/dist/key-priority.d.ts +9 -5
- package/dist/key-priority.js +11 -6
- package/dist/linked-editing.d.ts +26 -0
- package/dist/linked-editing.js +215 -0
- package/dist/live-templates.d.ts +16 -0
- package/dist/live-templates.js +289 -0
- package/dist/locales/en.json +61 -2
- package/dist/locales/nl.json +61 -2
- package/dist/markup-context.d.ts +55 -0
- package/dist/markup-context.js +408 -0
- package/dist/markup.d.ts +39 -0
- package/dist/markup.js +465 -0
- package/dist/navigation.js +4 -6
- package/dist/paste-history.d.ts +7 -0
- package/dist/paste-history.js +104 -0
- package/dist/peek.js +3 -4
- package/dist/pick.d.ts +21 -2
- package/dist/pick.js +152 -19
- package/dist/popups.d.ts +10 -0
- package/dist/popups.js +2 -1
- package/dist/postfix.d.ts +21 -0
- package/dist/postfix.js +212 -0
- package/dist/project-language.d.ts +20 -1
- package/dist/project-language.js +132 -18
- package/dist/rename.js +8 -11
- package/dist/rendered-docs.js +1 -2
- package/dist/selection-ranges.js +2 -3
- package/dist/shortcut-keys.d.ts +24 -0
- package/dist/signature.js +3 -6
- package/dist/snippet-insert.d.ts +10 -0
- package/dist/snippet-insert.js +217 -0
- package/dist/snippet-session.d.ts +2 -2
- package/dist/snippet-session.js +3 -3
- package/dist/snippet.d.ts +7 -1
- package/dist/snippet.js +65 -8
- package/dist/surround-constructs.d.ts +10 -0
- package/dist/surround-constructs.js +100 -0
- package/dist/surround.d.ts +18 -0
- package/dist/surround.js +399 -0
- package/dist/symbol-picker.js +4 -6
- package/dist/symbols.js +22 -3
- package/dist/template-builtins.d.ts +3 -0
- package/dist/template-builtins.js +46 -0
- package/dist/template-context.d.ts +12 -0
- package/dist/template-context.js +56 -0
- package/dist/templates.d.ts +59 -0
- package/dist/templates.js +103 -0
- package/dist/testing.d.ts +23 -1
- package/dist/testing.js +114 -0
- package/package.json +7 -6
- package/src/CallHierarchyPanel.tsx +26 -11
- package/src/EditorContextMenu.tsx +7 -0
- package/src/LanguagePopups.tsx +4 -0
- package/src/PickPopup.tsx +47 -5
- package/src/WrapCard.tsx +64 -0
- package/src/call-hierarchy-model.ts +25 -3
- package/src/call-hierarchy.ts +62 -20
- package/src/clipboard-history.ts +102 -0
- package/src/code-actions.ts +48 -11
- package/src/code-vision.ts +3 -3
- package/src/completion.ts +123 -25
- package/src/context-menu-rows.ts +3 -2
- package/src/definition-link.ts +17 -5
- package/src/document-colors.ts +189 -0
- package/src/document-links.ts +129 -0
- package/src/document-query.ts +71 -0
- package/src/edit-locations.ts +162 -0
- package/src/editor-language.ts +86 -3
- package/src/emmet-module.d.ts +44 -0
- package/src/emmet.ts +73 -0
- package/src/folding.ts +3 -3
- package/src/format-on-type.ts +5 -5
- package/src/highlights.ts +3 -3
- package/src/history.ts +81 -1
- package/src/host-types.ts +17 -0
- package/src/index.ts +28 -3
- package/src/inlay-hints.ts +2 -2
- package/src/inline-completion.ts +221 -0
- package/src/key-priority.ts +11 -6
- package/src/linked-editing.ts +199 -0
- package/src/live-templates.ts +315 -0
- package/src/locales/en.json +61 -2
- package/src/locales/nl.json +61 -2
- package/src/markup-context.ts +387 -0
- package/src/markup.ts +377 -0
- package/src/navigation.ts +6 -6
- package/src/paste-history.ts +111 -0
- package/src/peek.ts +4 -4
- package/src/pick.ts +218 -20
- package/src/popups.ts +21 -1
- package/src/postfix.ts +224 -0
- package/src/project-language.ts +139 -19
- package/src/rename.ts +11 -11
- package/src/rendered-docs.ts +2 -2
- package/src/selection-ranges.ts +3 -3
- package/src/signature.ts +6 -6
- package/src/snippet-insert.ts +258 -0
- package/src/snippet-session.ts +9 -4
- package/src/snippet.ts +82 -7
- package/src/surround-constructs.ts +85 -0
- package/src/surround.ts +430 -0
- package/src/symbol-picker.ts +6 -6
- package/src/symbols.ts +30 -4
- package/src/template-builtins.ts +94 -0
- package/src/template-context.ts +65 -0
- package/src/templates.ts +197 -0
- package/src/testing.ts +126 -1
package/dist/call-hierarchy.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export declare class CallHierarchyFeature {
|
|
|
9
9
|
private nodes;
|
|
10
10
|
private roots;
|
|
11
11
|
private prepared;
|
|
12
|
+
private position;
|
|
12
13
|
private direction;
|
|
13
14
|
private controller;
|
|
14
15
|
private epoch;
|
|
@@ -17,6 +18,7 @@ export declare class CallHierarchyFeature {
|
|
|
17
18
|
constructor(language: EditorLanguage, timers?: Timers);
|
|
18
19
|
get isOpen(): boolean;
|
|
19
20
|
get supported(): boolean;
|
|
21
|
+
get typesSupported(): boolean;
|
|
20
22
|
open(position?: EditorPosition, direction?: CallDirection): Promise<void>;
|
|
21
23
|
close(): void;
|
|
22
24
|
setDirection(direction: CallDirection): void;
|
|
@@ -31,6 +33,7 @@ export declare class CallHierarchyFeature {
|
|
|
31
33
|
private mounted;
|
|
32
34
|
private patch;
|
|
33
35
|
private load;
|
|
36
|
+
private childrenOf;
|
|
34
37
|
private preview;
|
|
35
38
|
private hasAncestor;
|
|
36
39
|
private key;
|
package/dist/call-hierarchy.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { StaleResultError } from '@adecore/lsp';
|
|
2
2
|
import { KEY_PRIORITY } from './key-priority.js';
|
|
3
|
-
import { CALL_LEVEL_LIMIT, childrenOf, moreIdOf, rootsOf, rowsOf, statusIdOf, stepsOf, targetOf } from './call-hierarchy-model.js';
|
|
3
|
+
import { CALL_LEVEL_LIMIT, childrenOf, isTypeDirection, moreIdOf, rootsOf, rowsOf, statusIdOf, stepsOf, targetOf, typeChildrenOf } from './call-hierarchy-model.js';
|
|
4
4
|
import { PEEK_HEIGHT } from './peek.js';
|
|
5
5
|
import { snippetOf } from './peek-model.js';
|
|
6
6
|
import { isShortcut } from './shortcut-keys.js';
|
|
@@ -8,6 +8,7 @@ import { messageOf } from './error-message.js';
|
|
|
8
8
|
import { realTimers, revealRow } from './timers.js';
|
|
9
9
|
const TOAST_ID = 'language-call-hierarchy';
|
|
10
10
|
const PREPARE = 'textDocument/prepareCallHierarchy';
|
|
11
|
+
const PREPARE_TYPES = 'textDocument/prepareTypeHierarchy';
|
|
11
12
|
/* The row the panel stands in is as tall as a peek's, plus the segmented control that is a pixel taller than the peek's title bar. */
|
|
12
13
|
export const CALL_HIERARCHY_HEIGHT = PEEK_HEIGHT + 2;
|
|
13
14
|
const OWNER = 'call-hierarchy';
|
|
@@ -24,6 +25,7 @@ export class CallHierarchyFeature {
|
|
|
24
25
|
nodes = new Map();
|
|
25
26
|
roots = [];
|
|
26
27
|
prepared = [];
|
|
28
|
+
position = null;
|
|
27
29
|
direction = 'incoming';
|
|
28
30
|
controller = new AbortController();
|
|
29
31
|
/* Raised whenever the tree starts over or closes, so an answer for the tree that was never lands in the one that is. */
|
|
@@ -37,11 +39,13 @@ export class CallHierarchyFeature {
|
|
|
37
39
|
editor
|
|
38
40
|
} = language;
|
|
39
41
|
const offs = [language.onKey(event => {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
const calls = isShortcut(this.language.shortcuts.callHierarchy, event);
|
|
43
|
+
if (calls || isShortcut(this.language.shortcuts.typeHierarchy, event)) {
|
|
44
|
+
const [first, second] = calls ? ['incoming', 'outgoing'] : ['supertypes', 'subtypes'];
|
|
45
|
+
if (this.isOpen && isTypeDirection(this.direction) !== calls) {
|
|
46
|
+
this.setDirection(this.direction === first ? second : first);
|
|
43
47
|
} else {
|
|
44
|
-
void this.open();
|
|
48
|
+
void this.open(undefined, first);
|
|
45
49
|
}
|
|
46
50
|
return true;
|
|
47
51
|
}
|
|
@@ -60,35 +64,45 @@ export class CallHierarchyFeature {
|
|
|
60
64
|
/* Whether a server of this document answers the three requests the tree is made of. */
|
|
61
65
|
get supported() {
|
|
62
66
|
const {
|
|
63
|
-
|
|
67
|
+
service,
|
|
64
68
|
uri
|
|
65
69
|
} = this.language;
|
|
66
|
-
const {
|
|
67
|
-
service
|
|
68
|
-
} = project;
|
|
69
70
|
return service.prepareCallHierarchy !== undefined && service.incomingCalls !== undefined && service.outgoingCalls !== undefined && service.supports(PREPARE, uri);
|
|
70
71
|
}
|
|
71
|
-
/*
|
|
72
|
+
/* Whether a server of this document answers the three requests of the type hierarchy. */
|
|
73
|
+
get typesSupported() {
|
|
74
|
+
const {
|
|
75
|
+
service,
|
|
76
|
+
uri
|
|
77
|
+
} = this.language;
|
|
78
|
+
return service.prepareTypeHierarchy !== undefined && service.supertypes !== undefined && service.subtypes !== undefined && service.supports(PREPARE_TYPES, uri);
|
|
79
|
+
}
|
|
80
|
+
/*
|
|
81
|
+
* Opens the tree for the symbol at the position, on its callers unless told otherwise; `supertypes` or `subtypes`
|
|
82
|
+
* open the type hierarchy of the type at the position.
|
|
83
|
+
*/
|
|
72
84
|
async open(position = this.language.editor.getCaret(), direction = 'incoming') {
|
|
73
85
|
const {
|
|
74
86
|
editor,
|
|
75
|
-
|
|
87
|
+
service,
|
|
76
88
|
uri
|
|
77
89
|
} = this.language;
|
|
78
|
-
|
|
79
|
-
|
|
90
|
+
const types = isTypeDirection(direction);
|
|
91
|
+
if (!(types ? this.typesSupported : this.supported)) {
|
|
92
|
+
this.tell(this.say(types ? 'typesUnavailable' : 'unavailable'));
|
|
80
93
|
return;
|
|
81
94
|
}
|
|
82
95
|
this.close();
|
|
83
96
|
const epoch = this.epoch;
|
|
84
97
|
let items;
|
|
85
98
|
try {
|
|
86
|
-
|
|
99
|
+
const options = {
|
|
87
100
|
signal: this.controller.signal
|
|
88
|
-
}
|
|
101
|
+
};
|
|
102
|
+
items = types ? await service.prepareTypeHierarchy(uri, position, options) : await service.prepareCallHierarchy(uri, position, options);
|
|
89
103
|
} catch (error) {
|
|
90
104
|
if (epoch === this.epoch && !(error instanceof StaleResultError)) {
|
|
91
|
-
this.tell(this.say('failed', {
|
|
105
|
+
this.tell(this.say(types ? 'typesFailed' : 'failed', {
|
|
92
106
|
message: messageOf(error)
|
|
93
107
|
}));
|
|
94
108
|
}
|
|
@@ -98,11 +112,12 @@ export class CallHierarchyFeature {
|
|
|
98
112
|
return;
|
|
99
113
|
}
|
|
100
114
|
if (items === null || items.length === 0) {
|
|
101
|
-
this.tell(this.say('none'));
|
|
115
|
+
this.tell(this.say(types ? 'typesNone' : 'none'));
|
|
102
116
|
return;
|
|
103
117
|
}
|
|
104
118
|
this.language.peek.close();
|
|
105
119
|
this.prepared = items;
|
|
120
|
+
this.position = position;
|
|
106
121
|
this.direction = direction;
|
|
107
122
|
this.seed();
|
|
108
123
|
const active = this.roots[0];
|
|
@@ -143,12 +158,16 @@ export class CallHierarchyFeature {
|
|
|
143
158
|
this.language.editor.setInputPopup(null);
|
|
144
159
|
this.language.editor.focus();
|
|
145
160
|
}
|
|
146
|
-
/* Starts the tree over from the same symbols for the other direction. */
|
|
161
|
+
/* Starts the tree over from the same symbols for the other direction; a switch between calls and types prepares the symbol again. */
|
|
147
162
|
setDirection(direction) {
|
|
148
163
|
const view = this.language.popups.getState().callHierarchy;
|
|
149
164
|
if (view === null || view.direction === direction) {
|
|
150
165
|
return;
|
|
151
166
|
}
|
|
167
|
+
if (isTypeDirection(direction) !== isTypeDirection(view.direction)) {
|
|
168
|
+
void this.open(this.position ?? undefined, direction);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
152
171
|
this.reset();
|
|
153
172
|
this.direction = direction;
|
|
154
173
|
this.seed();
|
|
@@ -309,11 +328,9 @@ export class CallHierarchyFeature {
|
|
|
309
328
|
return;
|
|
310
329
|
}
|
|
311
330
|
const {
|
|
312
|
-
service,
|
|
313
331
|
i18n
|
|
314
332
|
} = this.language.project;
|
|
315
333
|
const {
|
|
316
|
-
uri,
|
|
317
334
|
editor
|
|
318
335
|
} = this.language;
|
|
319
336
|
const {
|
|
@@ -329,11 +346,10 @@ export class CallHierarchyFeature {
|
|
|
329
346
|
error: null
|
|
330
347
|
});
|
|
331
348
|
try {
|
|
332
|
-
const
|
|
349
|
+
const children = await this.childrenOf(direction, node, options);
|
|
333
350
|
if (epoch !== this.epoch) {
|
|
334
351
|
return;
|
|
335
352
|
}
|
|
336
|
-
const children = childrenOf(direction, node, calls ?? []);
|
|
337
353
|
for (const child of children) {
|
|
338
354
|
this.nodes.set(child.id, child);
|
|
339
355
|
}
|
|
@@ -360,6 +376,22 @@ export class CallHierarchyFeature {
|
|
|
360
376
|
});
|
|
361
377
|
}
|
|
362
378
|
}
|
|
379
|
+
async childrenOf(direction, node, options) {
|
|
380
|
+
const {
|
|
381
|
+
service,
|
|
382
|
+
uri
|
|
383
|
+
} = this.language;
|
|
384
|
+
switch (direction) {
|
|
385
|
+
case 'incoming':
|
|
386
|
+
return childrenOf(direction, node, (await service.incomingCalls(uri, node.item, options)) ?? []);
|
|
387
|
+
case 'outgoing':
|
|
388
|
+
return childrenOf(direction, node, (await service.outgoingCalls(uri, node.item, options)) ?? []);
|
|
389
|
+
case 'supertypes':
|
|
390
|
+
return typeChildrenOf(node, (await service.supertypes(uri, node.item, options)) ?? []);
|
|
391
|
+
case 'subtypes':
|
|
392
|
+
return typeChildrenOf(node, (await service.subtypes(uri, node.item, options)) ?? []);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
363
395
|
async preview(node, site) {
|
|
364
396
|
const {
|
|
365
397
|
project
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface ClipboardEntry {
|
|
2
|
+
readonly text: string;
|
|
3
|
+
readonly wholeLines: boolean;
|
|
4
|
+
readonly at: number;
|
|
5
|
+
}
|
|
6
|
+
export interface ClipboardHistoryOptions {
|
|
7
|
+
readonly limit?: number;
|
|
8
|
+
readonly maxLength?: number;
|
|
9
|
+
readonly entries?: readonly ClipboardEntry[];
|
|
10
|
+
onChange?(entries: readonly ClipboardEntry[]): void;
|
|
11
|
+
readonly clock?: () => number;
|
|
12
|
+
}
|
|
13
|
+
export declare class ClipboardHistory {
|
|
14
|
+
private readonly limit;
|
|
15
|
+
private readonly maxLength;
|
|
16
|
+
private readonly onChange;
|
|
17
|
+
private readonly clock;
|
|
18
|
+
private readonly listeners;
|
|
19
|
+
private list;
|
|
20
|
+
constructor(options?: ClipboardHistoryOptions);
|
|
21
|
+
get entries(): readonly ClipboardEntry[];
|
|
22
|
+
add(text: string, options?: {
|
|
23
|
+
readonly wholeLines?: boolean;
|
|
24
|
+
}): void;
|
|
25
|
+
remove(entry: ClipboardEntry): void;
|
|
26
|
+
promote(entry: ClipboardEntry): void;
|
|
27
|
+
clear(): void;
|
|
28
|
+
subscribe(listener: () => void): () => void;
|
|
29
|
+
private change;
|
|
30
|
+
private trimmed;
|
|
31
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/* The texts copied or cut in the editors of a project, newest first, for Paste from History. */
|
|
2
|
+
export class ClipboardHistory {
|
|
3
|
+
limit;
|
|
4
|
+
maxLength;
|
|
5
|
+
onChange;
|
|
6
|
+
clock;
|
|
7
|
+
listeners = new Set();
|
|
8
|
+
list;
|
|
9
|
+
constructor(options = {}) {
|
|
10
|
+
this.limit = options.limit ?? 100;
|
|
11
|
+
this.maxLength = options.maxLength ?? 10_000_000;
|
|
12
|
+
this.onChange = options.onChange;
|
|
13
|
+
this.clock = options.clock ?? Date.now;
|
|
14
|
+
this.list = this.trimmed(options.entries ?? []);
|
|
15
|
+
}
|
|
16
|
+
/* Newest first. */
|
|
17
|
+
get entries() {
|
|
18
|
+
return this.list;
|
|
19
|
+
}
|
|
20
|
+
/* Puts a copy on top. The same text again moves up instead of being kept twice, and nothing is kept for an empty text. */
|
|
21
|
+
add(text, options = {}) {
|
|
22
|
+
if (text === '') {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const entry = {
|
|
26
|
+
text,
|
|
27
|
+
wholeLines: options.wholeLines === true,
|
|
28
|
+
at: this.clock()
|
|
29
|
+
};
|
|
30
|
+
this.change([entry, ...this.list.filter(other => other.text !== text)]);
|
|
31
|
+
}
|
|
32
|
+
remove(entry) {
|
|
33
|
+
if (this.list.includes(entry)) {
|
|
34
|
+
this.change(this.list.filter(other => other !== entry));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/* Moves an entry to the top, as choosing it does. */
|
|
38
|
+
promote(entry) {
|
|
39
|
+
if (this.list.includes(entry) && this.list[0] !== entry) {
|
|
40
|
+
this.change([entry, ...this.list.filter(other => other !== entry)]);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
clear() {
|
|
44
|
+
if (this.list.length > 0) {
|
|
45
|
+
this.change([]);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
subscribe(listener) {
|
|
49
|
+
this.listeners.add(listener);
|
|
50
|
+
return () => this.listeners.delete(listener);
|
|
51
|
+
}
|
|
52
|
+
change(entries) {
|
|
53
|
+
this.list = this.trimmed(entries);
|
|
54
|
+
this.onChange?.(this.list);
|
|
55
|
+
this.listeners.forEach(listener => listener());
|
|
56
|
+
}
|
|
57
|
+
/* Keeps the newest entries that fit the limit and the total length. */
|
|
58
|
+
trimmed(entries) {
|
|
59
|
+
const kept = [];
|
|
60
|
+
let length = 0;
|
|
61
|
+
for (const entry of entries.slice(0, this.limit)) {
|
|
62
|
+
length += entry.text.length;
|
|
63
|
+
if (kept.length > 0 && length > this.maxLength) {
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
kept.push(entry);
|
|
67
|
+
}
|
|
68
|
+
return kept;
|
|
69
|
+
}
|
|
70
|
+
}
|
package/dist/code-actions.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ActionEntry } from './code-actions-model.ts';
|
|
2
|
-
import type
|
|
2
|
+
import { type Problem } from './diagnostics-model.ts';
|
|
3
3
|
import type { EditorLanguage } from './editor-language.ts';
|
|
4
4
|
import { type Timers } from './timers.ts';
|
|
5
5
|
export declare class CodeActionsFeature {
|
|
@@ -14,6 +14,8 @@ export declare class CodeActionsFeature {
|
|
|
14
14
|
quickFixFor(problem: Problem): Promise<void>;
|
|
15
15
|
organizeImports(): Promise<void>;
|
|
16
16
|
formatDocument(): Promise<void>;
|
|
17
|
+
get formatsSelection(): boolean;
|
|
18
|
+
formatSelection(): Promise<void>;
|
|
17
19
|
list(only: readonly string[]): Promise<ActionEntry[] | null>;
|
|
18
20
|
private ask;
|
|
19
21
|
private request;
|
package/dist/code-actions.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ErrorCodes, LspError, StaleResultError } from '@adecore/lsp';
|
|
2
2
|
import { KEY_PRIORITY } from './key-priority.js';
|
|
3
3
|
import { ACTION_GROUPS, REFACTOR_GROUPS, actionsOf, diagnosticsAt, fixableOnLine, isHint, mergeEntries, previewOf } from './code-actions-model.js';
|
|
4
|
+
import { comparePositions } from './diagnostics-model.js';
|
|
4
5
|
import { Refresher } from './refresher.js';
|
|
5
6
|
import { isShortcut } from './shortcut-keys.js';
|
|
6
7
|
import { realTimers } from './timers.js';
|
|
@@ -64,7 +65,7 @@ export class CodeActionsFeature {
|
|
|
64
65
|
});
|
|
65
66
|
}
|
|
66
67
|
get supported() {
|
|
67
|
-
return this.language.
|
|
68
|
+
return this.language.service.supports(METHOD, this.language.uri);
|
|
68
69
|
}
|
|
69
70
|
/* The list under the caret, or under the selection's start. */
|
|
70
71
|
open() {
|
|
@@ -121,15 +122,14 @@ export class CodeActionsFeature {
|
|
|
121
122
|
async formatDocument() {
|
|
122
123
|
const {
|
|
123
124
|
editor,
|
|
124
|
-
project,
|
|
125
125
|
uri
|
|
126
126
|
} = this.language;
|
|
127
|
-
if (!
|
|
127
|
+
if (!this.language.service.supports('textDocument/formatting', uri)) {
|
|
128
128
|
this.tell('error', this.say('noFormatter'));
|
|
129
129
|
return;
|
|
130
130
|
}
|
|
131
131
|
try {
|
|
132
|
-
const edits = await
|
|
132
|
+
const edits = await this.language.service.formatting(uri, {
|
|
133
133
|
...editor.getIndentation()
|
|
134
134
|
});
|
|
135
135
|
if (edits !== null && edits.length > 0 && !editor.applyEdits(edits.map(edit => ({
|
|
@@ -142,6 +142,48 @@ export class CodeActionsFeature {
|
|
|
142
142
|
this.fail(error);
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
|
+
/* Whether a server formats a part of this document, so `formatSelection` has something to ask. */
|
|
146
|
+
get formatsSelection() {
|
|
147
|
+
return this.language.service.supports('textDocument/rangeFormatting', this.language.uri);
|
|
148
|
+
}
|
|
149
|
+
/*
|
|
150
|
+
* Formats what is selected, every selection in one request when the server formats several ranges at once and
|
|
151
|
+
* one by one otherwise; the whole document when nothing is selected.
|
|
152
|
+
*/
|
|
153
|
+
async formatSelection() {
|
|
154
|
+
const {
|
|
155
|
+
editor,
|
|
156
|
+
uri
|
|
157
|
+
} = this.language;
|
|
158
|
+
const ranges = editor.getSelections().filter(range => comparePositions(range.start, range.end) !== 0);
|
|
159
|
+
if (ranges.length === 0) {
|
|
160
|
+
await this.formatDocument();
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
if (!this.formatsSelection) {
|
|
164
|
+
this.tell('error', this.say('noFormatter'));
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const {
|
|
168
|
+
service
|
|
169
|
+
} = this.language;
|
|
170
|
+
const formatting = {
|
|
171
|
+
...editor.getIndentation()
|
|
172
|
+
};
|
|
173
|
+
try {
|
|
174
|
+
const edits = service.rangesFormatting !== undefined && service.supports('textDocument/rangesFormatting', uri) ? await service.rangesFormatting(uri, ranges, formatting) : (await Promise.all(ranges.map(range => service.rangeFormatting(uri, range, formatting, {
|
|
175
|
+
parallel: true
|
|
176
|
+
})))).flatMap(list => list ?? []);
|
|
177
|
+
if (edits !== null && edits.length > 0 && !editor.applyEdits(edits.map(edit => ({
|
|
178
|
+
range: edit.range,
|
|
179
|
+
text: edit.newText
|
|
180
|
+
})))) {
|
|
181
|
+
this.tell('error', this.say('readOnly'));
|
|
182
|
+
}
|
|
183
|
+
} catch (error) {
|
|
184
|
+
this.fail(error);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
145
187
|
/* The actions of one kind for the selection, as entries a menu can list and `apply` runs. */
|
|
146
188
|
list(only) {
|
|
147
189
|
if (!this.supported) {
|
|
@@ -206,7 +248,6 @@ export class CodeActionsFeature {
|
|
|
206
248
|
/* Asks the servers; null when they could not answer, with the reason said aloud for a request a person made. */
|
|
207
249
|
async request(range, triggerKind, options = {}) {
|
|
208
250
|
const {
|
|
209
|
-
project,
|
|
210
251
|
uri,
|
|
211
252
|
diagnostics
|
|
212
253
|
} = this.language;
|
|
@@ -224,7 +265,7 @@ export class CodeActionsFeature {
|
|
|
224
265
|
} : {}),
|
|
225
266
|
triggerKind: triggerKind
|
|
226
267
|
};
|
|
227
|
-
const entries = actionsOf(await
|
|
268
|
+
const entries = actionsOf(await this.language.service.codeActions(uri, range, context, {
|
|
228
269
|
signal
|
|
229
270
|
}), order);
|
|
230
271
|
// A server may answer with more than the kinds asked for.
|
|
@@ -283,16 +324,15 @@ export class CodeActionsFeature {
|
|
|
283
324
|
return known;
|
|
284
325
|
}
|
|
285
326
|
const {
|
|
286
|
-
project,
|
|
287
327
|
uri
|
|
288
328
|
} = this.language;
|
|
289
329
|
const {
|
|
290
330
|
action
|
|
291
331
|
} = entry;
|
|
292
332
|
let result = action;
|
|
293
|
-
if (action.edit === undefined &&
|
|
333
|
+
if (action.edit === undefined && this.language.service.providerOptions(METHOD, uri)?.resolveProvider === true) {
|
|
294
334
|
try {
|
|
295
|
-
result = await
|
|
335
|
+
result = await this.language.service.resolveCodeAction(uri, action, {
|
|
296
336
|
signal
|
|
297
337
|
});
|
|
298
338
|
} catch (error) {
|
|
@@ -383,7 +423,7 @@ export class CodeActionsFeature {
|
|
|
383
423
|
if (action.command?.command === INLINE_RENAME_COMMAND) {
|
|
384
424
|
await this.startRename(action.command);
|
|
385
425
|
} else if (action.command !== undefined) {
|
|
386
|
-
await
|
|
426
|
+
await this.language.service.executeCommand(uri, action.command);
|
|
387
427
|
}
|
|
388
428
|
} catch (error) {
|
|
389
429
|
this.fail(error);
|
package/dist/code-vision.js
CHANGED
|
@@ -111,7 +111,7 @@ export class CodeVisionFeature {
|
|
|
111
111
|
this.plan();
|
|
112
112
|
}
|
|
113
113
|
get canCount() {
|
|
114
|
-
return this.settings.usages && this.language.
|
|
114
|
+
return this.settings.usages && this.language.service.supports(REFERENCES, this.language.uri);
|
|
115
115
|
}
|
|
116
116
|
/* Queues the declarations in view whose count is not from the current text, nearest the top of the view first. */
|
|
117
117
|
plan() {
|
|
@@ -128,14 +128,13 @@ export class CodeVisionFeature {
|
|
|
128
128
|
}
|
|
129
129
|
async count(declaration) {
|
|
130
130
|
const {
|
|
131
|
-
project,
|
|
132
131
|
uri
|
|
133
132
|
} = this.language;
|
|
134
133
|
const controller = new AbortController();
|
|
135
134
|
this.running.set(declaration.id, controller);
|
|
136
135
|
const epoch = this.epoch;
|
|
137
136
|
try {
|
|
138
|
-
const locations = await
|
|
137
|
+
const locations = await this.language.service.references(uri, declaration.position, false, {
|
|
139
138
|
signal: controller.signal,
|
|
140
139
|
parallel: true
|
|
141
140
|
});
|
package/dist/completion.d.ts
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
|
+
import { type CompletionItem } from '@adecore/lsp';
|
|
2
|
+
import type { EditorPosition } from '@adecore/editor';
|
|
1
3
|
import type { EditorLanguage } from './editor-language.ts';
|
|
2
4
|
import { type Timers } from './timers.ts';
|
|
5
|
+
/** A row a source of the editor offers beside the language server's. */
|
|
6
|
+
export interface LocalCompletionItem {
|
|
7
|
+
/** The label, kind, detail, documentation, filter text and sort text of the row; its edit range is the typed prefix on the caret's line, ending at the caret. */
|
|
8
|
+
readonly item: CompletionItem;
|
|
9
|
+
/** Runs instead of the insertion: the source inserts the row itself. */
|
|
10
|
+
accept(): void;
|
|
11
|
+
}
|
|
12
|
+
/** What a source is asked for when the list is requested. */
|
|
13
|
+
export interface CompletionRequest {
|
|
14
|
+
readonly position: EditorPosition;
|
|
15
|
+
/** Whether the person asked for the list with the keyboard. */
|
|
16
|
+
readonly explicit: boolean;
|
|
17
|
+
readonly triggerCharacter?: string;
|
|
18
|
+
}
|
|
19
|
+
/** Rows that come from the editor itself, such as templates, merged into the list of the language server. */
|
|
20
|
+
export interface CompletionSource {
|
|
21
|
+
/** Synchronous and cheap; asked on every request of the list. */
|
|
22
|
+
items(request: CompletionRequest): readonly LocalCompletionItem[];
|
|
23
|
+
}
|
|
3
24
|
export declare class CompletionFeature {
|
|
4
25
|
private readonly language;
|
|
5
26
|
private readonly timers;
|
|
@@ -24,9 +45,16 @@ export declare class CompletionFeature {
|
|
|
24
45
|
private acceptSequence;
|
|
25
46
|
private disposed;
|
|
26
47
|
private readonly resolved;
|
|
48
|
+
private readonly sources;
|
|
49
|
+
private locals;
|
|
50
|
+
private shown;
|
|
27
51
|
constructor(language: EditorLanguage, timers?: Timers);
|
|
28
52
|
get isOpen(): boolean;
|
|
29
53
|
invoke(): void;
|
|
54
|
+
/** Adds rows to every list, also in a document without a language server. Returns the function that takes the source away again. */
|
|
55
|
+
addSource(source: CompletionSource): () => void;
|
|
56
|
+
/** Opens the list with only these rows, the typed prefix starting at `start`, as Insert Live Template does. */
|
|
57
|
+
showItems(items: readonly LocalCompletionItem[], start: EditorPosition): void;
|
|
30
58
|
move(delta: number): void;
|
|
31
59
|
accept(replace: boolean, index?: number, commit?: string): Promise<void>;
|
|
32
60
|
private insert;
|