@adecore/editor-react 0.23.1 → 0.24.1
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.d.ts +2 -1
- package/dist/AnchoredPopup.js +2 -2
- package/dist/CodeAuthorsCard.d.ts +4 -0
- package/dist/CodeAuthorsCard.js +8 -4
- package/dist/CompletionPopup.js +7 -3
- package/dist/EditorView.d.ts +8 -3
- package/dist/EditorView.js +79 -9
- package/dist/HoverCard.d.ts +3 -1
- package/dist/HoverCard.js +2 -2
- package/dist/LanguagePopups.d.ts +8 -4
- package/dist/LanguagePopups.js +4 -4
- package/dist/PickPopup.js +2 -1
- package/dist/RenameCard.js +10 -8
- package/dist/RenderedDocs.d.ts +10 -4
- package/dist/RenderedDocs.js +10 -6
- package/dist/call-hierarchy.js +15 -14
- package/dist/code-actions.js +5 -2
- package/dist/completion-model.js +3 -1
- package/dist/completion.d.ts +4 -2
- package/dist/completion.js +49 -27
- package/dist/diagnostics-model.d.ts +1 -0
- package/dist/diagnostics-model.js +1 -1
- package/dist/diagnostics.d.ts +1 -0
- package/dist/diagnostics.js +28 -10
- package/dist/diff-overlays.js +2 -2
- package/dist/editor-language.d.ts +3 -1
- package/dist/editor-language.js +10 -0
- package/dist/format-on-type.js +2 -3
- package/dist/highlights.js +3 -2
- package/dist/history.js +3 -2
- package/dist/holder.d.ts +3 -3
- package/dist/holder.js +2 -1
- package/dist/host-types.d.ts +3 -0
- package/dist/hover.d.ts +5 -0
- package/dist/hover.js +13 -5
- package/dist/index.d.ts +6 -2
- package/dist/index.js +3 -1
- package/dist/key-priority.d.ts +23 -0
- package/dist/key-priority.js +39 -0
- package/dist/locales/en.json +2 -1
- package/dist/locales/nl.json +2 -1
- package/dist/models.d.ts +2 -2
- package/dist/models.js +2 -2
- package/dist/navigation.js +3 -2
- package/dist/peek.js +3 -2
- package/dist/pick.js +2 -1
- package/dist/popup-focus.d.ts +5 -0
- package/dist/popup-focus.js +12 -0
- package/dist/popups.d.ts +1 -1
- package/dist/project-language.js +5 -4
- package/dist/project-problems.d.ts +10 -1
- package/dist/project-problems.js +34 -10
- package/dist/proposal-model.d.ts +0 -1
- package/dist/proposal-model.js +0 -8
- package/dist/rename-model.d.ts +2 -1
- package/dist/rename-model.js +57 -0
- package/dist/rename.d.ts +1 -0
- package/dist/rename.js +21 -5
- package/dist/rendered-docs.js +3 -2
- package/dist/signature.js +4 -3
- package/dist/snippet-session.d.ts +1 -1
- package/dist/snippet-session.js +8 -2
- package/dist/symbol-picker.js +3 -2
- package/package.json +6 -6
- package/src/AnchoredPopup.tsx +4 -2
- package/src/CodeAuthorsCard.tsx +21 -12
- package/src/CompletionPopup.tsx +11 -1
- package/src/EditorView.tsx +122 -11
- package/src/HoverCard.tsx +6 -1
- package/src/LanguagePopups.tsx +23 -4
- package/src/PickPopup.tsx +9 -1
- package/src/RenameCard.tsx +15 -9
- package/src/RenderedDocs.tsx +30 -8
- package/src/call-hierarchy.ts +15 -14
- package/src/code-actions.ts +5 -2
- package/src/completion-model.ts +3 -1
- package/src/completion.ts +48 -28
- package/src/diagnostics-model.ts +1 -1
- package/src/diagnostics.ts +29 -13
- package/src/diff-overlays.tsx +12 -8
- package/src/editor-language.ts +12 -1
- package/src/format-on-type.ts +2 -3
- package/src/highlights.ts +3 -2
- package/src/history.ts +3 -2
- package/src/holder.ts +5 -4
- package/src/host-types.ts +5 -0
- package/src/hover.ts +19 -5
- package/src/index.ts +6 -2
- package/src/key-priority.ts +49 -0
- package/src/locales/en.json +2 -1
- package/src/locales/nl.json +2 -1
- package/src/models.ts +1 -1
- package/src/navigation.ts +3 -2
- package/src/peek.ts +3 -2
- package/src/pick.ts +2 -1
- package/src/popup-focus.ts +17 -0
- package/src/popups.ts +1 -2
- package/src/project-language.ts +5 -4
- package/src/project-problems.ts +46 -11
- package/src/proposal-model.ts +0 -9
- package/src/rename-model.ts +60 -1
- package/src/rename.ts +21 -5
- package/src/rendered-docs.ts +3 -2
- package/src/signature.ts +4 -3
- package/src/snippet-session.ts +9 -3
- package/src/symbol-picker.ts +3 -2
- package/dist/relative-time.d.ts +0 -1
- package/dist/relative-time.js +0 -9
- package/src/relative-time.ts +0 -10
package/dist/holder.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* One value that an effect sets and a render reads through `useSyncExternalStore`, without a state update inside the effect. */
|
|
1
2
|
export function createHolder() {
|
|
2
3
|
let value = null;
|
|
3
4
|
const listeners = new Set();
|
|
@@ -5,7 +6,7 @@ export function createHolder() {
|
|
|
5
6
|
get: () => value,
|
|
6
7
|
set: (next) => {
|
|
7
8
|
value = next;
|
|
8
|
-
for (const listener of listeners) {
|
|
9
|
+
for (const listener of [...listeners]) {
|
|
9
10
|
listener();
|
|
10
11
|
}
|
|
11
12
|
},
|
package/dist/host-types.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { i18n } from 'i18next';
|
|
|
4
4
|
import type { Keymap } from '@adecore/editor/keymap';
|
|
5
5
|
import type { ProjectFiles } from './workspace-edit.ts';
|
|
6
6
|
import type { Place } from './navigation-history.ts';
|
|
7
|
+
import type { ProblemSource } from './project-problems.ts';
|
|
7
8
|
export interface DiskText {
|
|
8
9
|
text: string;
|
|
9
10
|
mtime: number;
|
|
@@ -30,6 +31,7 @@ export interface RenameSuggestionsRequest {
|
|
|
30
31
|
uri: string;
|
|
31
32
|
languageId: string;
|
|
32
33
|
name: string;
|
|
34
|
+
kind?: string;
|
|
33
35
|
context: string;
|
|
34
36
|
uses: readonly string[];
|
|
35
37
|
}
|
|
@@ -55,6 +57,7 @@ export interface LanguageHost {
|
|
|
55
57
|
readonly keymap?: Keymap;
|
|
56
58
|
readonly panelBodyHeight?: number;
|
|
57
59
|
onPanelResize?(height: number): void;
|
|
60
|
+
readonly problemSource?: ProblemSource;
|
|
58
61
|
openPlace?(place: Place): void;
|
|
59
62
|
pathOfUri?(uri: string): string | null;
|
|
60
63
|
serverNames?(uri: string): readonly string[];
|
package/dist/hover.d.ts
CHANGED
|
@@ -3,6 +3,9 @@ import type { EditorLanguage } from './editor-language.ts';
|
|
|
3
3
|
import { type HoverText } from './hover-content.ts';
|
|
4
4
|
import { type Timers } from './timers.ts';
|
|
5
5
|
export declare const SHOW_DELAY_MS = 300;
|
|
6
|
+
export interface HoverSettings {
|
|
7
|
+
readonly referenceCount?: boolean;
|
|
8
|
+
}
|
|
6
9
|
export declare class HoverFeature {
|
|
7
10
|
private readonly language;
|
|
8
11
|
private readonly timers;
|
|
@@ -11,11 +14,13 @@ export declare class HoverFeature {
|
|
|
11
14
|
private hideTimer;
|
|
12
15
|
private countTimer;
|
|
13
16
|
private inCard;
|
|
17
|
+
private referenceCount;
|
|
14
18
|
private request;
|
|
15
19
|
private lookup;
|
|
16
20
|
private pinned;
|
|
17
21
|
private held;
|
|
18
22
|
constructor(language: EditorLanguage, timers?: Timers);
|
|
23
|
+
configure(settings: HoverSettings): void;
|
|
19
24
|
holdCard(inside: boolean): void;
|
|
20
25
|
quickInfo(): void;
|
|
21
26
|
showProblemsAt(position: EditorPosition): boolean;
|
package/dist/hover.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { KEY_PRIORITY } from './key-priority.js';
|
|
1
2
|
import { rangeHolds } from './diagnostics-model.js';
|
|
2
3
|
import { hoverTextOf, isEmptyHover, locationsOf } from './hover-content.js';
|
|
3
4
|
import { lineTextOf } from './line-text.js';
|
|
@@ -23,6 +24,7 @@ export class HoverFeature {
|
|
|
23
24
|
hideTimer;
|
|
24
25
|
countTimer;
|
|
25
26
|
inCard = false;
|
|
27
|
+
referenceCount = true;
|
|
26
28
|
/* Counts every request, so an answer that arrives after the pointer moved on is dropped. */
|
|
27
29
|
request = 0;
|
|
28
30
|
lookup = null;
|
|
@@ -56,17 +58,17 @@ export class HoverFeature {
|
|
|
56
58
|
this.hide();
|
|
57
59
|
}
|
|
58
60
|
}),
|
|
59
|
-
|
|
61
|
+
language.onKey((event) => {
|
|
60
62
|
if (isShortcut(this.language.shortcuts.quickInfo, event)) {
|
|
61
63
|
this.quickInfo();
|
|
62
64
|
return true;
|
|
63
65
|
}
|
|
64
|
-
if (event.key === 'Escape' && this.language.popups.getState().hover !== null && this.language.popups.getState().callHierarchy
|
|
66
|
+
if (event.key === 'Escape' && this.language.popups.getState().hover !== null && this.language.popups.getState().callHierarchy === null) {
|
|
65
67
|
this.hide();
|
|
66
68
|
return true;
|
|
67
69
|
}
|
|
68
70
|
return false;
|
|
69
|
-
})
|
|
71
|
+
}, KEY_PRIORITY.hover)
|
|
70
72
|
];
|
|
71
73
|
language.onDispose(() => {
|
|
72
74
|
for (const off of offs) {
|
|
@@ -75,6 +77,12 @@ export class HoverFeature {
|
|
|
75
77
|
this.hide();
|
|
76
78
|
});
|
|
77
79
|
}
|
|
80
|
+
configure(settings) {
|
|
81
|
+
this.referenceCount = settings.referenceCount !== false;
|
|
82
|
+
if (!this.referenceCount) {
|
|
83
|
+
this.timers.clear(this.countTimer);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
78
86
|
/* The pointer entered or left the card, which is where a link in it is clicked. */
|
|
79
87
|
holdCard(inside) {
|
|
80
88
|
this.inCard = inside;
|
|
@@ -219,7 +227,7 @@ export class HoverFeature {
|
|
|
219
227
|
}
|
|
220
228
|
this.pinned = pinned;
|
|
221
229
|
this.present(position, problems, info, problems[0]?.diagnostic.range ?? range);
|
|
222
|
-
if (info !== null) {
|
|
230
|
+
if (info !== null && this.referenceCount) {
|
|
223
231
|
this.scheduleCount(position, request, controller.signal);
|
|
224
232
|
}
|
|
225
233
|
}
|
|
@@ -250,7 +258,7 @@ export class HoverFeature {
|
|
|
250
258
|
/* How many places use the symbol, which can take a while in a large project and so arrives after the card does. */
|
|
251
259
|
async count(position, key, request, signal) {
|
|
252
260
|
const { service } = this.language.project;
|
|
253
|
-
if (request !== this.request || !service.supports('textDocument/references', this.language.uri)) {
|
|
261
|
+
if (request !== this.request || !this.referenceCount || !service.supports('textDocument/references', this.language.uri)) {
|
|
254
262
|
return;
|
|
255
263
|
}
|
|
256
264
|
const found = await service.references(this.language.uri, position, false, { signal }).catch(() => null);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { EditorLanguage, type EditorLanguageOptions } from './editor-language.ts';
|
|
2
|
+
export { KEY_PRIORITY } from './key-priority.ts';
|
|
3
|
+
export { realTimers, type Timers } from './timers.ts';
|
|
2
4
|
export { DEFAULT_RANGE_LINES, DEFAULT_RANGE_CHARACTERS, type SemanticTokensOptions } from './semantic-tokens.ts';
|
|
3
5
|
export { ProjectLanguage, type FileOperationTarget } from './project-language.ts';
|
|
4
6
|
export type { LanguageDocumentHandle } from './project-language.ts';
|
|
@@ -7,6 +9,7 @@ export { EditorView } from './EditorView.tsx';
|
|
|
7
9
|
export { createHolder } from './holder.ts';
|
|
8
10
|
export type { EditorViewProps } from './EditorView.tsx';
|
|
9
11
|
export { LanguagePopups } from './LanguagePopups.tsx';
|
|
12
|
+
export type { LanguagePopupsProps } from './LanguagePopups.tsx';
|
|
10
13
|
export { AnchoredPopup } from './AnchoredPopup.tsx';
|
|
11
14
|
export { HoverCard } from './HoverCard.tsx';
|
|
12
15
|
export { CompletionPopup } from './CompletionPopup.tsx';
|
|
@@ -28,13 +31,14 @@ export type { EditorRendering } from './rendering-context.ts';
|
|
|
28
31
|
export { FindReplace } from './FindReplace.tsx';
|
|
29
32
|
export { ChangeReview } from './ChangeReview.tsx';
|
|
30
33
|
export type { ChangeReviewProps } from './ChangeReview.tsx';
|
|
31
|
-
export { ProjectProblems, countsOf, compareRows } from './project-problems.ts';
|
|
32
|
-
export type { ProblemFile, ProblemRow } from './project-problems.ts';
|
|
34
|
+
export { ProjectProblems, serviceProblems, countsOf, compareRows } from './project-problems.ts';
|
|
35
|
+
export type { ProblemFile, ProblemRow, ProblemReport, ProblemSource } from './project-problems.ts';
|
|
33
36
|
export { applyWorkspaceEdit, supportedResourceOperations } from './workspace-edit.ts';
|
|
34
37
|
export type { ProjectFiles, StagedFile, WorkspaceEditHost } from './workspace-edit.ts';
|
|
35
38
|
export { useProblemCounts } from './use-problem-counts.ts';
|
|
36
39
|
export type { ProblemCounts } from './diagnostics.ts';
|
|
37
40
|
export type { BlameSource, CodeVisionSettings } from './code-vision.ts';
|
|
41
|
+
export type { HoverSettings } from './hover.ts';
|
|
38
42
|
export type { Problem } from './diagnostics-model.ts';
|
|
39
43
|
export type { PopupState, PopupStore, HoverInfo, HoverView, CompletionView, CompletionDocs, CompletionRow, SignatureView, RenameView, RenameFileView, PeekView, CallHierarchyView, PickView, PickGroup, PickRow, PickPreview, SymbolsView, MenuView, AuthorsView } from './popups.ts';
|
|
40
44
|
export { RowHost, LineActionHost } from './row-host.ts';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { EditorLanguage } from './editor-language.js';
|
|
2
|
+
export { KEY_PRIORITY } from './key-priority.js';
|
|
3
|
+
export { realTimers } from './timers.js';
|
|
2
4
|
export { DEFAULT_RANGE_LINES, DEFAULT_RANGE_CHARACTERS } from './semantic-tokens.js';
|
|
3
5
|
export { ProjectLanguage } from './project-language.js';
|
|
4
6
|
export { EditorView } from './EditorView.js';
|
|
@@ -21,7 +23,7 @@ export { EditorContextMenu } from './EditorContextMenu.js';
|
|
|
21
23
|
export { EditorRenderingProvider } from './rendering.js';
|
|
22
24
|
export { FindReplace } from './FindReplace.js';
|
|
23
25
|
export { ChangeReview } from './ChangeReview.js';
|
|
24
|
-
export { ProjectProblems, countsOf, compareRows } from './project-problems.js';
|
|
26
|
+
export { ProjectProblems, serviceProblems, countsOf, compareRows } from './project-problems.js';
|
|
25
27
|
export { applyWorkspaceEdit, supportedResourceOperations } from './workspace-edit.js';
|
|
26
28
|
export { useProblemCounts } from './use-problem-counts.js';
|
|
27
29
|
export { RowHost, LineActionHost } from './row-host.js';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { EditorKeyHandler } from '@adecore/editor';
|
|
2
|
+
export declare const KEY_PRIORITY: {
|
|
3
|
+
readonly pick: 1500;
|
|
4
|
+
readonly diagnostics: 1400;
|
|
5
|
+
readonly hover: 1300;
|
|
6
|
+
readonly completion: 1200;
|
|
7
|
+
readonly snippets: 1100;
|
|
8
|
+
readonly signature: 1000;
|
|
9
|
+
readonly highlights: 900;
|
|
10
|
+
readonly codeActions: 800;
|
|
11
|
+
readonly rename: 700;
|
|
12
|
+
readonly navigation: 600;
|
|
13
|
+
readonly peek: 500;
|
|
14
|
+
readonly callHierarchy: 400;
|
|
15
|
+
readonly symbolPicker: 300;
|
|
16
|
+
readonly history: 200;
|
|
17
|
+
readonly renderedDocs: 100;
|
|
18
|
+
};
|
|
19
|
+
export declare class KeyDispatcher {
|
|
20
|
+
private readonly entries;
|
|
21
|
+
add(handler: EditorKeyHandler, priority: number): () => void;
|
|
22
|
+
dispatch(event: KeyboardEvent): boolean;
|
|
23
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Where each feature of an editor sees a key through `EditorLanguage.onKey`, the highest first. A hundred
|
|
3
|
+
* apart, so a handler of the app can stand between two features; 0, the default, comes after all of them.
|
|
4
|
+
*/
|
|
5
|
+
export const KEY_PRIORITY = {
|
|
6
|
+
pick: 1500,
|
|
7
|
+
diagnostics: 1400,
|
|
8
|
+
hover: 1300,
|
|
9
|
+
completion: 1200,
|
|
10
|
+
snippets: 1100,
|
|
11
|
+
signature: 1000,
|
|
12
|
+
highlights: 900,
|
|
13
|
+
codeActions: 800,
|
|
14
|
+
rename: 700,
|
|
15
|
+
navigation: 600,
|
|
16
|
+
peek: 500,
|
|
17
|
+
callHierarchy: 400,
|
|
18
|
+
symbolPicker: 300,
|
|
19
|
+
history: 200,
|
|
20
|
+
renderedDocs: 100
|
|
21
|
+
};
|
|
22
|
+
/* Hands a key to its handlers by priority until one takes it; of two of the same priority the one added first. */
|
|
23
|
+
export class KeyDispatcher {
|
|
24
|
+
entries = [];
|
|
25
|
+
add(handler, priority) {
|
|
26
|
+
const entry = { handler, priority };
|
|
27
|
+
const index = this.entries.findIndex((other) => other.priority < priority);
|
|
28
|
+
this.entries.splice(index === -1 ? this.entries.length : index, 0, entry);
|
|
29
|
+
return () => {
|
|
30
|
+
const at = this.entries.indexOf(entry);
|
|
31
|
+
if (at !== -1) {
|
|
32
|
+
this.entries.splice(at, 1);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
dispatch(event) {
|
|
37
|
+
return [...this.entries].some((entry) => entry.handler(event));
|
|
38
|
+
}
|
|
39
|
+
}
|
package/dist/locales/en.json
CHANGED
|
@@ -178,7 +178,8 @@
|
|
|
178
178
|
"details": "Details",
|
|
179
179
|
"none": "No suggestions",
|
|
180
180
|
"transformBusy": "Snippet transforms are busy; try again",
|
|
181
|
-
"transformFailed": "Snippet transform could not be applied"
|
|
181
|
+
"transformFailed": "Snippet transform could not be applied",
|
|
182
|
+
"failed": "Could not insert the suggestion: {{message}}"
|
|
182
183
|
},
|
|
183
184
|
"history": {
|
|
184
185
|
"recent": "Recent locations"
|
package/dist/locales/nl.json
CHANGED
|
@@ -178,7 +178,8 @@
|
|
|
178
178
|
"details": "Details",
|
|
179
179
|
"none": "Geen suggesties",
|
|
180
180
|
"transformBusy": "Snippettransformaties zijn bezig; probeer het opnieuw",
|
|
181
|
-
"transformFailed": "Snippettransformatie kon niet worden toegepast"
|
|
181
|
+
"transformFailed": "Snippettransformatie kon niet worden toegepast",
|
|
182
|
+
"failed": "De suggestie kon niet worden ingevoegd: {{message}}"
|
|
182
183
|
},
|
|
183
184
|
"history": {
|
|
184
185
|
"recent": "Recente plekken"
|
package/dist/models.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { isIdentifierCharacter, identifierPrefix, type MatchDetail, matchDetail, matchScore, editRangeOf, itemsOf, prefixFor, type Ranked, rankCompletions, matchedCharacters, qualifierOf, qualifiersOf, snippetToText, METHOD_KIND, FUNCTION_KIND, CONSTRUCTOR_KIND, CLASS_KIND, SNIPPET_FORMAT, type Insertion, type SnippetInsertionOptions, insertionOf, mirroredInsertions, documentationText, completionDocsOf, type KindTone, kindLetterOf, kindToneOf, type RowWindow, rowWindow } from './completion-model.ts';
|
|
2
2
|
export { PARAMETER_HINTS_COMMAND, type CallPlan, type CallSite, isCallItem, hasParameters, planCall, withParentheses } from './completion-call.ts';
|
|
3
|
-
export { type Problem, severityOf, markerOf, comparePositions, shiftPosition, shiftRange, rangeHolds, problemsAt, neighborProblem, codeLabelOf } from './diagnostics-model.ts';
|
|
3
|
+
export { type Problem, severityOf, markerOf, comparePositions, shiftPosition, endOfInsertion, shiftRange, rangeHolds, problemsAt, neighborProblem, codeLabelOf } from './diagnostics-model.ts';
|
|
4
4
|
export { type SignatureBlock, type HoverText, splitSignatures, hoverTextOf, isEmptyHover, locationsOf, sameRange, type DocTag, splitDocTags, type HoverSection, type BaselineLevel, type Baseline, docblockMarkdown, type MarkdownPart, markdownParts, hoverSectionsOf } from './hover-content.ts';
|
|
5
5
|
export { type SignatureViewModel, parameterSpan, signatureViewOf } from './signature-model.ts';
|
|
6
6
|
export { wordRangeAt, type RenameTarget, renameTargetOf, type Occurrences, occurrencesOf, type RenameRow, type RenameFile, renameRowsOf, renamePreviewOf } from './rename-model.ts';
|
|
@@ -15,7 +15,7 @@ export { resourceOperationsOf, type ResourceOperationView } from './workspace-ed
|
|
|
15
15
|
export { MAX_DECLARATIONS, type CodeVisionDeclaration, type DeclarationSource, startAfterComments, declarationsOf, usagesText } from './code-vision-model.ts';
|
|
16
16
|
export { UNCOMMITTED, mapBlame, type CodeAuthor, type CodeAuthorship, shortName, authorshipOf, authorsText } from './code-authors.ts';
|
|
17
17
|
export { type SnippetTransform, type SnippetStop, type SnippetRange, type SnippetField, type SnippetVariableResolver, type SnippetTemplate, compileSnippet, type ParsedSnippet, parseSnippet, tabOrder } from './snippet.ts';
|
|
18
|
-
export { type LineSpan, lineSpanOf, isEmptyRange, inlineRangeOf, type InlineProblem, problemsOnLines, type InlineAnswer, parseAnswer, fitReplacement,
|
|
18
|
+
export { type LineSpan, lineSpanOf, isEmptyRange, inlineRangeOf, type InlineProblem, problemsOnLines, type InlineAnswer, parseAnswer, fitReplacement, type DiffSegment, diffSegments, emphasisOf, offsetOf, textInRange, replaceRange, locateSelection } from './proposal-model.ts';
|
|
19
19
|
export { type LineReplacement, replaceLines, replaceAllLines } from './line-edits.ts';
|
|
20
20
|
export { replacedWords } from './word-diff.ts';
|
|
21
21
|
export { type FindOptions, type FindQuery, EMPTY_FIND_QUERY, type TextMatch, type CompiledFind, MATCH_LIMIT, compileFind, matchesIn, stepIndex } from './find-query.ts';
|
package/dist/models.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { isIdentifierCharacter, identifierPrefix, matchDetail, matchScore, editRangeOf, itemsOf, prefixFor, rankCompletions, matchedCharacters, qualifierOf, qualifiersOf, snippetToText, METHOD_KIND, FUNCTION_KIND, CONSTRUCTOR_KIND, CLASS_KIND, SNIPPET_FORMAT, insertionOf, mirroredInsertions, documentationText, completionDocsOf, kindLetterOf, kindToneOf, rowWindow } from './completion-model.js';
|
|
2
2
|
export { PARAMETER_HINTS_COMMAND, isCallItem, hasParameters, planCall, withParentheses } from './completion-call.js';
|
|
3
|
-
export { severityOf, markerOf, comparePositions, shiftPosition, shiftRange, rangeHolds, problemsAt, neighborProblem, codeLabelOf } from './diagnostics-model.js';
|
|
3
|
+
export { severityOf, markerOf, comparePositions, shiftPosition, endOfInsertion, shiftRange, rangeHolds, problemsAt, neighborProblem, codeLabelOf } from './diagnostics-model.js';
|
|
4
4
|
export { splitSignatures, hoverTextOf, isEmptyHover, locationsOf, sameRange, splitDocTags, docblockMarkdown, markdownParts, hoverSectionsOf } from './hover-content.js';
|
|
5
5
|
export { parameterSpan, signatureViewOf } from './signature-model.js';
|
|
6
6
|
export { wordRangeAt, renameTargetOf, occurrencesOf, renameRowsOf, renamePreviewOf } from './rename-model.js';
|
|
@@ -15,7 +15,7 @@ export { resourceOperationsOf } from './workspace-edit.js';
|
|
|
15
15
|
export { MAX_DECLARATIONS, startAfterComments, declarationsOf, usagesText } from './code-vision-model.js';
|
|
16
16
|
export { UNCOMMITTED, mapBlame, shortName, authorshipOf, authorsText } from './code-authors.js';
|
|
17
17
|
export { compileSnippet, parseSnippet, tabOrder } from './snippet.js';
|
|
18
|
-
export { lineSpanOf, isEmptyRange, inlineRangeOf, problemsOnLines, parseAnswer, fitReplacement,
|
|
18
|
+
export { lineSpanOf, isEmptyRange, inlineRangeOf, problemsOnLines, parseAnswer, fitReplacement, diffSegments, emphasisOf, offsetOf, textInRange, replaceRange, locateSelection } from './proposal-model.js';
|
|
19
19
|
export { replaceLines, replaceAllLines } from './line-edits.js';
|
|
20
20
|
export { replacedWords } from './word-diff.js';
|
|
21
21
|
export { EMPTY_FIND_QUERY, MATCH_LIMIT, compileFind, matchesIn, stepIndex } from './find-query.js';
|
package/dist/navigation.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { StaleResultError, fileUriToPath } from '@adecore/lsp';
|
|
2
|
+
import { KEY_PRIORITY } from './key-priority.js';
|
|
2
3
|
import { basenameOf } from './paths.js';
|
|
3
4
|
import { rangeHolds } from './diagnostics-model.js';
|
|
4
5
|
import { placesOfName } from './symbol-links.js';
|
|
@@ -62,14 +63,14 @@ export class NavigationFeature {
|
|
|
62
63
|
void this.go('definition', click.position);
|
|
63
64
|
return true;
|
|
64
65
|
}),
|
|
65
|
-
|
|
66
|
+
language.onKey((event) => {
|
|
66
67
|
const found = SHORTCUT_KINDS.find(([, name]) => isShortcut(this.language.shortcuts[name], event));
|
|
67
68
|
if (found === undefined) {
|
|
68
69
|
return false;
|
|
69
70
|
}
|
|
70
71
|
void this.go(found[0]);
|
|
71
72
|
return true;
|
|
72
|
-
})
|
|
73
|
+
}, KEY_PRIORITY.navigation)
|
|
73
74
|
];
|
|
74
75
|
language.onDispose(() => {
|
|
75
76
|
for (const off of offs) {
|
package/dist/peek.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { StaleResultError } from '@adecore/lsp';
|
|
2
|
+
import { KEY_PRIORITY } from './key-priority.js';
|
|
2
3
|
import { uniquePlaces } from './navigation.js';
|
|
3
4
|
import { PEEK_READ_FILES, definitionSnippetOf, peekFilesOf, snippetOf } from './peek-model.js';
|
|
4
5
|
import { isShortcut } from './shortcut-keys.js';
|
|
@@ -35,7 +36,7 @@ export class PeekFeature {
|
|
|
35
36
|
this.timers = timers;
|
|
36
37
|
const { editor } = language;
|
|
37
38
|
const offs = [
|
|
38
|
-
|
|
39
|
+
language.onKey((event) => {
|
|
39
40
|
if (isShortcut(this.language.shortcuts.peekReferences, event)) {
|
|
40
41
|
void this.open();
|
|
41
42
|
return true;
|
|
@@ -45,7 +46,7 @@ export class PeekFeature {
|
|
|
45
46
|
return true;
|
|
46
47
|
}
|
|
47
48
|
return this.key(event);
|
|
48
|
-
}),
|
|
49
|
+
}, KEY_PRIORITY.peek),
|
|
49
50
|
editor.onTextChange(() => this.close())
|
|
50
51
|
];
|
|
51
52
|
language.onDispose(() => {
|
package/dist/pick.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { KEY_PRIORITY } from './key-priority.js';
|
|
1
2
|
import { realTimers } from './timers.js';
|
|
2
3
|
const PREVIEW_DELAY_MS = 120;
|
|
3
4
|
/*
|
|
@@ -21,7 +22,7 @@ export class PickFeature {
|
|
|
21
22
|
this.timers = timers;
|
|
22
23
|
const { editor } = language;
|
|
23
24
|
const offs = [
|
|
24
|
-
|
|
25
|
+
language.onKey((event) => this.key(event), KEY_PRIORITY.pick),
|
|
25
26
|
editor.onTextChange(() => this.close()),
|
|
26
27
|
editor.onCaret(() => this.close()),
|
|
27
28
|
editor.onBlur(() => this.close())
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The handlers for a popup list whose rows the keyboard never enters: the text it belongs to keeps the
|
|
3
|
+
* focus, and the active row is only `aria-activedescendant` or a highlight. Chromium reports that row as
|
|
4
|
+
* the focused element, so a tool that focuses it before it types would otherwise pull the keys out of the
|
|
5
|
+
* text. A press on the list moves no focus, and a row that gets it anyway hands it straight back.
|
|
6
|
+
*/
|
|
7
|
+
export function keepFocusOutOfList(focusBack) {
|
|
8
|
+
return {
|
|
9
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
10
|
+
onFocus: () => focusBack()
|
|
11
|
+
};
|
|
12
|
+
}
|
package/dist/popups.d.ts
CHANGED
|
@@ -141,7 +141,7 @@ export interface PopupState {
|
|
|
141
141
|
readonly pick: PickView | null;
|
|
142
142
|
readonly rename: RenameView | null;
|
|
143
143
|
readonly peek: PeekView | null;
|
|
144
|
-
readonly callHierarchy
|
|
144
|
+
readonly callHierarchy: CallHierarchyView | null;
|
|
145
145
|
readonly symbols: SymbolsView | null;
|
|
146
146
|
readonly menu: MenuView | null;
|
|
147
147
|
readonly authors: AuthorsView | null;
|
package/dist/project-language.js
CHANGED
|
@@ -2,7 +2,7 @@ import { disposeSnippetTransforms } from './snippet-transform-queue.js';
|
|
|
2
2
|
import i18next, {} from 'i18next';
|
|
3
3
|
import { fileUriToPath, pathToFileUri } from '@adecore/lsp';
|
|
4
4
|
import { NavigationHistory } from './navigation-history.js';
|
|
5
|
-
import { ProjectProblems } from './project-problems.js';
|
|
5
|
+
import { ProjectProblems, serviceProblems } from './project-problems.js';
|
|
6
6
|
import { applyWorkspaceEdit } from './workspace-edit.js';
|
|
7
7
|
import { relativeTo } from './paths.js';
|
|
8
8
|
import { PANEL_BODY_HEIGHT } from './panel-size.js';
|
|
@@ -85,7 +85,7 @@ export class ProjectLanguage {
|
|
|
85
85
|
this.folder = host.folder ?? '';
|
|
86
86
|
this.files = host.files ?? null;
|
|
87
87
|
this.panelBodyHeight = host.panelBodyHeight ?? PANEL_BODY_HEIGHT;
|
|
88
|
-
this.problems = new ProjectProblems(service, (uri) => this.pathOfLocation(uri) ?? uri);
|
|
88
|
+
this.problems = new ProjectProblems(host.problemSource ?? serviceProblems(service, (uri) => this.pathOfLocation(uri) ?? uri));
|
|
89
89
|
}
|
|
90
90
|
/* Open panels of other editors of the project follow a resize. */
|
|
91
91
|
onPanelBodyChange(listener) {
|
|
@@ -211,9 +211,10 @@ export class ProjectLanguage {
|
|
|
211
211
|
void holder.sync.ready
|
|
212
212
|
.catch(() => undefined)
|
|
213
213
|
.then(() => {
|
|
214
|
-
if (
|
|
215
|
-
return
|
|
214
|
+
if (this.holders.has(uri)) {
|
|
215
|
+
return undefined;
|
|
216
216
|
}
|
|
217
|
+
return this.service.closeDocument(uri);
|
|
217
218
|
})
|
|
218
219
|
.catch(() => undefined);
|
|
219
220
|
}
|
|
@@ -9,12 +9,21 @@ export interface ProblemFile {
|
|
|
9
9
|
readonly rows: readonly ProblemRow[];
|
|
10
10
|
}
|
|
11
11
|
export declare function compareRows(left: ProblemRow, right: ProblemRow): number;
|
|
12
|
+
export interface ProblemReport {
|
|
13
|
+
readonly path: string;
|
|
14
|
+
readonly server: string;
|
|
15
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
16
|
+
}
|
|
17
|
+
export type ProblemSource = (listener: (report: ProblemReport) => void) => () => void;
|
|
18
|
+
export declare function serviceProblems(service: LanguageService, pathOf?: (uri: string) => string): ProblemSource;
|
|
12
19
|
export declare class ProjectProblems {
|
|
13
20
|
private readonly reports;
|
|
21
|
+
private readonly files;
|
|
14
22
|
private readonly listeners;
|
|
15
23
|
private readonly stop;
|
|
24
|
+
private order;
|
|
16
25
|
private snapshot;
|
|
17
|
-
constructor(
|
|
26
|
+
constructor(source: ProblemSource | LanguageService, pathOf?: (uri: string) => string);
|
|
18
27
|
report(path: string, server: string, diagnostics: readonly Diagnostic[]): void;
|
|
19
28
|
getSnapshot: () => readonly ProblemFile[];
|
|
20
29
|
subscribe: (listener: () => void) => (() => void);
|
package/dist/project-problems.js
CHANGED
|
@@ -5,22 +5,38 @@ export function compareRows(left, right) {
|
|
|
5
5
|
return (SEVERITY_ORDER[severityOf(left.diagnostic)] - SEVERITY_ORDER[severityOf(right.diagnostic)] ||
|
|
6
6
|
comparePositions(left.diagnostic.range.start, right.diagnostic.range.start));
|
|
7
7
|
}
|
|
8
|
+
/* The diagnostics a service reports, by the stored path `pathOf` gives each URI. */
|
|
9
|
+
export function serviceProblems(service, pathOf = (uri) => uri) {
|
|
10
|
+
return (listener) => {
|
|
11
|
+
const subscription = service.onDiagnostics((report) => listener({ path: pathOf(report.uri), server: report.source, diagnostics: report.diagnostics }));
|
|
12
|
+
return () => subscription.dispose();
|
|
13
|
+
};
|
|
14
|
+
}
|
|
8
15
|
/*
|
|
9
16
|
* Each report replaces the previous diagnostics from that source for the file. Files with no
|
|
10
17
|
* remaining problems drop out. Hints remain editor annotations rather than listed problems.
|
|
11
18
|
*/
|
|
12
19
|
export class ProjectProblems {
|
|
13
20
|
reports = new Map();
|
|
21
|
+
files = new Map();
|
|
14
22
|
listeners = new Set();
|
|
15
23
|
stop;
|
|
24
|
+
/* The paths of `files` in order; null once a file came or went. */
|
|
25
|
+
order = [];
|
|
26
|
+
/* Made on first read after a report, so a project nobody lists does no sorting. */
|
|
16
27
|
snapshot = [];
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
28
|
+
/* A service stands for `serviceProblems(service, pathOf)`. */
|
|
29
|
+
constructor(source, pathOf) {
|
|
30
|
+
const listen = typeof source === 'function' ? source : serviceProblems(source, pathOf);
|
|
31
|
+
this.stop = listen((report) => this.report(report.path, report.server, report.diagnostics));
|
|
20
32
|
}
|
|
21
33
|
report(path, server, diagnostics) {
|
|
22
34
|
const kept = diagnostics.filter((diagnostic) => severityOf(diagnostic) !== 'hint');
|
|
23
35
|
const servers = this.reports.get(path) ?? new Map();
|
|
36
|
+
if (kept.length === 0 && !servers.has(server)) {
|
|
37
|
+
// A clean file reported clean again, as servers do after every edit.
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
24
40
|
if (kept.length === 0) {
|
|
25
41
|
servers.delete(server);
|
|
26
42
|
}
|
|
@@ -29,22 +45,30 @@ export class ProjectProblems {
|
|
|
29
45
|
}
|
|
30
46
|
if (servers.size === 0) {
|
|
31
47
|
this.reports.delete(path);
|
|
48
|
+
this.files.delete(path);
|
|
49
|
+
this.order = null;
|
|
32
50
|
}
|
|
33
51
|
else {
|
|
52
|
+
if (!this.files.has(path)) {
|
|
53
|
+
this.order = null;
|
|
54
|
+
}
|
|
34
55
|
this.reports.set(path, servers);
|
|
56
|
+
const rows = [...servers].flatMap(([name, list]) => list.map((diagnostic) => ({ diagnostic, server: name }))).sort(compareRows);
|
|
57
|
+
this.files.set(path, { path, rows });
|
|
35
58
|
}
|
|
36
|
-
this.snapshot =
|
|
37
|
-
.map(([file, byServer]) => ({
|
|
38
|
-
path: file,
|
|
39
|
-
rows: [...byServer].flatMap(([name, list]) => list.map((diagnostic) => ({ diagnostic, server: name }))).sort(compareRows)
|
|
40
|
-
}))
|
|
41
|
-
.sort((left, right) => left.path.localeCompare(right.path));
|
|
59
|
+
this.snapshot = null;
|
|
42
60
|
for (const listener of [...this.listeners]) {
|
|
43
61
|
listener();
|
|
44
62
|
}
|
|
45
63
|
}
|
|
46
64
|
/* The same array until the next report, which is what a store a component reads must hand out. */
|
|
47
|
-
getSnapshot = () =>
|
|
65
|
+
getSnapshot = () => {
|
|
66
|
+
if (this.snapshot === null) {
|
|
67
|
+
this.order ??= [...this.files.keys()].sort((left, right) => left.localeCompare(right));
|
|
68
|
+
this.snapshot = this.order.map((path) => this.files.get(path));
|
|
69
|
+
}
|
|
70
|
+
return this.snapshot;
|
|
71
|
+
};
|
|
48
72
|
subscribe = (listener) => {
|
|
49
73
|
this.listeners.add(listener);
|
|
50
74
|
return () => {
|
package/dist/proposal-model.d.ts
CHANGED
|
@@ -21,7 +21,6 @@ export interface InlineAnswer {
|
|
|
21
21
|
}
|
|
22
22
|
export declare function parseAnswer(text: string): InlineAnswer;
|
|
23
23
|
export declare function fitReplacement(selected: string, replacement: string): string;
|
|
24
|
-
export declare function endOfInsertion(start: EditorPosition, text: string): EditorPosition;
|
|
25
24
|
export interface DiffSegment {
|
|
26
25
|
readonly kind: 'same' | 'added' | 'removed';
|
|
27
26
|
readonly text: string;
|
package/dist/proposal-model.js
CHANGED
|
@@ -94,14 +94,6 @@ export function fitReplacement(selected, replacement) {
|
|
|
94
94
|
}
|
|
95
95
|
return breaks === '\n' ? fitted : fitted.replace(/\n/g, breaks);
|
|
96
96
|
}
|
|
97
|
-
/* Where the caret stands after `text` was typed at `start`. */
|
|
98
|
-
export function endOfInsertion(start, text) {
|
|
99
|
-
const lines = text.split('\n');
|
|
100
|
-
if (lines.length === 1) {
|
|
101
|
-
return { line: start.line, character: start.character + text.length };
|
|
102
|
-
}
|
|
103
|
-
return { line: start.line + lines.length - 1, character: lines.at(-1).length };
|
|
104
|
-
}
|
|
105
97
|
function linesOf(text) {
|
|
106
98
|
const lines = text.replace(/\r\n/g, '\n').split('\n');
|
|
107
99
|
return lines.length > 1 && lines.at(-1) === '' ? lines.slice(0, -1) : lines;
|
package/dist/rename-model.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EditorPosition, EditorRange } from '@adecore/editor';
|
|
2
|
-
import type { Location, PrepareRenameResult, TextEdit, WorkspaceEdit } from '@adecore/lsp';
|
|
2
|
+
import type { DocumentSymbolResult, Location, PrepareRenameResult, TextEdit, WorkspaceEdit } from '@adecore/lsp';
|
|
3
3
|
export declare function wordRangeAt(lineText: string, position: EditorPosition): EditorRange | null;
|
|
4
4
|
export interface RenameTarget {
|
|
5
5
|
readonly range: EditorRange;
|
|
@@ -12,6 +12,7 @@ export interface Occurrences {
|
|
|
12
12
|
readonly files: number;
|
|
13
13
|
}
|
|
14
14
|
export declare function occurrencesOf(locations: readonly Location[], uri: string): Occurrences;
|
|
15
|
+
export declare function renameKindOf(result: DocumentSymbolResult, name: string, places: readonly EditorRange[]): string | undefined;
|
|
15
16
|
export interface RenameRow {
|
|
16
17
|
readonly line: number;
|
|
17
18
|
readonly before: string;
|
package/dist/rename-model.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isIdentifierCharacter } from './completion-model.js';
|
|
2
|
+
import { rangeHolds } from './diagnostics-model.js';
|
|
2
3
|
import { textEntriesOf } from './workspace-edit.js';
|
|
3
4
|
/* The identifier the caret is in or touches; null where there is none. */
|
|
4
5
|
export function wordRangeAt(lineText, position) {
|
|
@@ -36,6 +37,62 @@ export function occurrencesOf(locations, uri) {
|
|
|
36
37
|
files: new Set(locations.map((location) => location.uri)).size
|
|
37
38
|
};
|
|
38
39
|
}
|
|
40
|
+
/* LSP's SymbolKind in words, indexed by its number. */
|
|
41
|
+
const SYMBOL_KINDS = [
|
|
42
|
+
'',
|
|
43
|
+
'file',
|
|
44
|
+
'module',
|
|
45
|
+
'namespace',
|
|
46
|
+
'package',
|
|
47
|
+
'class',
|
|
48
|
+
'method',
|
|
49
|
+
'property',
|
|
50
|
+
'field',
|
|
51
|
+
'constructor',
|
|
52
|
+
'enum',
|
|
53
|
+
'interface',
|
|
54
|
+
'function',
|
|
55
|
+
'variable',
|
|
56
|
+
'constant',
|
|
57
|
+
'string',
|
|
58
|
+
'number',
|
|
59
|
+
'boolean',
|
|
60
|
+
'array',
|
|
61
|
+
'object',
|
|
62
|
+
'key',
|
|
63
|
+
'null',
|
|
64
|
+
'enum member',
|
|
65
|
+
'struct',
|
|
66
|
+
'event',
|
|
67
|
+
'operator',
|
|
68
|
+
'type parameter'
|
|
69
|
+
];
|
|
70
|
+
/*
|
|
71
|
+
* The kind of the symbol a rename names, in words, from the outline of the open file: the symbol whose name
|
|
72
|
+
* holds one of the places of the name there. Undefined when the outline does not list it, as with most locals.
|
|
73
|
+
*/
|
|
74
|
+
export function renameKindOf(result, name, places) {
|
|
75
|
+
if (result === null || result.length === 0) {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
const named = (range) => places.some((place) => rangeHolds(range, place.start));
|
|
79
|
+
if ('range' in result[0]) {
|
|
80
|
+
let found;
|
|
81
|
+
const walk = (symbols) => {
|
|
82
|
+
for (const symbol of symbols) {
|
|
83
|
+
if (named(symbol.selectionRange)) {
|
|
84
|
+
found = symbol;
|
|
85
|
+
}
|
|
86
|
+
walk(symbol.children ?? []);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
walk(result);
|
|
90
|
+
return found === undefined ? undefined : SYMBOL_KINDS[found.kind];
|
|
91
|
+
}
|
|
92
|
+
// A flat list only gives the whole span of a symbol, so the name has to match as well.
|
|
93
|
+
const found = result.find((symbol) => 'location' in symbol && symbol.name === name && named(symbol.location.range));
|
|
94
|
+
return found === undefined ? undefined : SYMBOL_KINDS[found.kind];
|
|
95
|
+
}
|
|
39
96
|
function lineStarts(text) {
|
|
40
97
|
const starts = [0];
|
|
41
98
|
for (let index = 0; index < text.length; index++) {
|