@adecore/editor-react 0.31.12 → 0.33.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/peek.js
CHANGED
|
@@ -9,11 +9,19 @@ const TOAST_ID = 'language-peek';
|
|
|
9
9
|
/* The block as the panel draws it: a hatched band, the header, eight lines of code and a hatched band, until the editor has measured it. */
|
|
10
10
|
export const PEEK_HEIGHT = 241;
|
|
11
11
|
const KINDS = {
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
references: {
|
|
13
|
+
method: 'textDocument/references',
|
|
14
|
+
unavailable: 'unavailable',
|
|
15
|
+
none: 'none'
|
|
16
|
+
},
|
|
17
|
+
definitions: {
|
|
18
|
+
method: 'textDocument/definition',
|
|
19
|
+
unavailable: 'unavailableDefinition',
|
|
20
|
+
none: 'noDefinition'
|
|
21
|
+
}
|
|
14
22
|
};
|
|
15
23
|
function placeKey(location) {
|
|
16
|
-
|
|
24
|
+
return `${location.uri}\0${location.range.start.line}\0${location.range.start.character}`;
|
|
17
25
|
}
|
|
18
26
|
/*
|
|
19
27
|
* The references of the name at the caret, between the lines of the file under the line it is on. The
|
|
@@ -21,208 +29,262 @@ function placeKey(location) {
|
|
|
21
29
|
* closes it too. A click on a place shows its code and a second one goes there.
|
|
22
30
|
*/
|
|
23
31
|
export class PeekFeature {
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
32
|
+
language;
|
|
33
|
+
timers;
|
|
34
|
+
kind = 'references';
|
|
35
|
+
/* The whole declaration of each place of a definition peek, where the server gave it. */
|
|
36
|
+
targets = new Map();
|
|
37
|
+
texts = new Map();
|
|
38
|
+
places = new Map();
|
|
39
|
+
order = [];
|
|
40
|
+
line = 0;
|
|
41
|
+
token = 0;
|
|
42
|
+
constructor(language, timers = realTimers) {
|
|
43
|
+
this.language = language;
|
|
44
|
+
this.timers = timers;
|
|
45
|
+
const {
|
|
46
|
+
editor
|
|
47
|
+
} = language;
|
|
48
|
+
const offs = [language.onKey(event => {
|
|
49
|
+
if (isShortcut(this.language.shortcuts.peekReferences, event)) {
|
|
50
|
+
void this.open();
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
if (isShortcut(this.language.shortcuts.peekDefinition, event)) {
|
|
54
|
+
void this.openDefinition();
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
return this.key(event);
|
|
58
|
+
}, KEY_PRIORITY.peek), editor.onTextChange(() => this.close())];
|
|
59
|
+
language.onDispose(() => {
|
|
60
|
+
for (const off of offs) {
|
|
61
|
+
off();
|
|
62
|
+
}
|
|
63
|
+
this.close();
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
get isOpen() {
|
|
67
|
+
return this.language.popups.getState().peek !== null;
|
|
68
|
+
}
|
|
69
|
+
async open(position = this.language.editor.getCaret(), kind = 'references') {
|
|
70
|
+
const {
|
|
71
|
+
editor,
|
|
72
|
+
project,
|
|
73
|
+
uri
|
|
74
|
+
} = this.language;
|
|
75
|
+
const method = KINDS[kind].method;
|
|
76
|
+
if (!project.service.supports(method, uri)) {
|
|
77
|
+
this.tell(this.say(KINDS[kind].unavailable));
|
|
78
|
+
return;
|
|
58
79
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
const token = ++this.token;
|
|
70
|
-
let found;
|
|
71
|
-
try {
|
|
72
|
-
found = await this.fetch(kind, position);
|
|
73
|
-
}
|
|
74
|
-
catch (error) {
|
|
75
|
-
if (!(error instanceof StaleResultError)) {
|
|
76
|
-
this.tell(this.say('failed', { message: messageOf(error) }));
|
|
77
|
-
}
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
if (token !== this.token) {
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
const { targets } = found;
|
|
84
|
-
const seen = new Set();
|
|
85
|
-
const unique = found.locations.filter((location) => {
|
|
86
|
-
const key = placeKey(location);
|
|
87
|
-
if (seen.has(key)) {
|
|
88
|
-
return false;
|
|
89
|
-
}
|
|
90
|
-
seen.add(key);
|
|
91
|
-
return true;
|
|
92
|
-
});
|
|
93
|
-
if (unique.length === 0) {
|
|
94
|
-
this.tell(this.say(KINDS[kind].none));
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
const uris = [...new Set(unique.map((location) => location.uri))].slice(0, PEEK_READ_FILES);
|
|
98
|
-
const texts = new Map();
|
|
99
|
-
await Promise.all(uris.map(async (target) => {
|
|
100
|
-
const text = await project.readText(target);
|
|
101
|
-
if (text !== null) {
|
|
102
|
-
texts.set(target, text);
|
|
103
|
-
}
|
|
80
|
+
const token = ++this.token;
|
|
81
|
+
let found;
|
|
82
|
+
try {
|
|
83
|
+
found = await this.fetch(kind, position);
|
|
84
|
+
} catch (error) {
|
|
85
|
+
if (!(error instanceof StaleResultError)) {
|
|
86
|
+
this.tell(this.say('failed', {
|
|
87
|
+
message: messageOf(error)
|
|
104
88
|
}));
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
this.texts = texts;
|
|
109
|
-
this.kind = kind;
|
|
110
|
-
this.targets = targets;
|
|
111
|
-
const files = peekFilesOf(unique, uri, (target) => texts.get(target) ?? null);
|
|
112
|
-
this.places = new Map(files.flatMap((file) => file.places.map((place) => [place.id, place.location])));
|
|
113
|
-
this.order = files.flatMap((file) => file.places.map((place) => place.id));
|
|
114
|
-
// The references open on the first place that is not the one the caret is on, which is what a person came to see.
|
|
115
|
-
const first = kind === 'definitions'
|
|
116
|
-
? files[0].places[0]
|
|
117
|
-
: (files.flatMap((file) => file.places).find((place) => !(place.location.uri === uri && place.line === position.line)) ?? files[0].places[0]);
|
|
118
|
-
this.line = position.line;
|
|
119
|
-
this.language.callHierarchy.close();
|
|
120
|
-
this.language.popups.setState({ peek: { kind, container: null, files, active: first.id, collapsed: [], count: unique.length, preview: null } });
|
|
121
|
-
this.select(first.id);
|
|
122
|
-
// The editor draws a row once per id, so a peek opened over another needs an id of its own to get a container.
|
|
123
|
-
editor.setWidgets([{ id: `peek-${token}`, line: this.line, height: PEEK_HEIGHT, render: (container) => this.mounted(container) }]);
|
|
124
|
-
// The keys come through the editor, which a click on the hover's link or a menu command has taken the focus from.
|
|
125
|
-
editor.focus();
|
|
89
|
+
}
|
|
90
|
+
return;
|
|
126
91
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
return this.open(position, 'definitions');
|
|
92
|
+
if (token !== this.token) {
|
|
93
|
+
return;
|
|
130
94
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
95
|
+
const {
|
|
96
|
+
targets
|
|
97
|
+
} = found;
|
|
98
|
+
const seen = new Set();
|
|
99
|
+
const unique = found.locations.filter(location => {
|
|
100
|
+
const key = placeKey(location);
|
|
101
|
+
if (seen.has(key)) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
seen.add(key);
|
|
105
|
+
return true;
|
|
106
|
+
});
|
|
107
|
+
if (unique.length === 0) {
|
|
108
|
+
this.tell(this.say(KINDS[kind].none));
|
|
109
|
+
return;
|
|
140
110
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
111
|
+
const uris = [...new Set(unique.map(location => location.uri))].slice(0, PEEK_READ_FILES);
|
|
112
|
+
const texts = new Map();
|
|
113
|
+
await Promise.all(uris.map(async target => {
|
|
114
|
+
const text = await project.readText(target);
|
|
115
|
+
if (text !== null) {
|
|
116
|
+
texts.set(target, text);
|
|
117
|
+
}
|
|
118
|
+
}));
|
|
119
|
+
if (token !== this.token) {
|
|
120
|
+
return;
|
|
149
121
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
122
|
+
this.texts = texts;
|
|
123
|
+
this.kind = kind;
|
|
124
|
+
this.targets = targets;
|
|
125
|
+
const files = peekFilesOf(unique, uri, target => texts.get(target) ?? null);
|
|
126
|
+
this.places = new Map(files.flatMap(file => file.places.map(place => [place.id, place.location])));
|
|
127
|
+
this.order = files.flatMap(file => file.places.map(place => place.id));
|
|
128
|
+
// The references open on the first place that is not the one the caret is on, which is what a person came to see.
|
|
129
|
+
const first = kind === 'definitions' ? files[0].places[0] : files.flatMap(file => file.places).find(place => !(place.location.uri === uri && place.line === position.line)) ?? files[0].places[0];
|
|
130
|
+
this.line = position.line;
|
|
131
|
+
this.language.callHierarchy.close();
|
|
132
|
+
this.language.popups.setState({
|
|
133
|
+
peek: {
|
|
134
|
+
kind,
|
|
135
|
+
container: null,
|
|
136
|
+
files,
|
|
137
|
+
active: first.id,
|
|
138
|
+
collapsed: [],
|
|
139
|
+
count: unique.length,
|
|
140
|
+
preview: null
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
this.select(first.id);
|
|
144
|
+
// The editor draws a row once per id, so a peek opened over another needs an id of its own to get a container.
|
|
145
|
+
editor.setWidgets([{
|
|
146
|
+
id: `peek-${token}`,
|
|
147
|
+
line: this.line,
|
|
148
|
+
height: PEEK_HEIGHT,
|
|
149
|
+
render: container => this.mounted(container)
|
|
150
|
+
}]);
|
|
151
|
+
// The keys come through the editor, which a click on the hover's link or a menu command has taken the focus from.
|
|
152
|
+
editor.focus();
|
|
153
|
+
}
|
|
154
|
+
/* The definition of the name at the caret, as its source between the lines of the file. */
|
|
155
|
+
openDefinition(position = this.language.editor.getCaret()) {
|
|
156
|
+
return this.open(position, 'definitions');
|
|
157
|
+
}
|
|
158
|
+
async fetch(kind, position) {
|
|
159
|
+
const {
|
|
160
|
+
project,
|
|
161
|
+
uri
|
|
162
|
+
} = this.language;
|
|
163
|
+
if (kind === 'references') {
|
|
164
|
+
// Without the declaration, so the list holds what the usages count above a declaration counts.
|
|
165
|
+
return {
|
|
166
|
+
locations: (await project.service.references(uri, position, false)) ?? [],
|
|
167
|
+
targets: new Map()
|
|
168
|
+
};
|
|
173
169
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
170
|
+
const places = uniquePlaces(await project.service.definition(uri, position));
|
|
171
|
+
const targets = new Map(places.flatMap(({
|
|
172
|
+
location,
|
|
173
|
+
target
|
|
174
|
+
}) => target === null ? [] : [[placeKey(location), target]]));
|
|
175
|
+
return {
|
|
176
|
+
locations: places.map(({
|
|
177
|
+
location
|
|
178
|
+
}) => location),
|
|
179
|
+
targets
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
close() {
|
|
183
|
+
this.token++;
|
|
184
|
+
if (this.language.popups.getState().peek === null) {
|
|
185
|
+
return;
|
|
181
186
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
187
|
+
this.language.popups.setState({
|
|
188
|
+
peek: null
|
|
189
|
+
});
|
|
190
|
+
this.language.editor.setWidgets([]);
|
|
191
|
+
this.language.editor.focus();
|
|
192
|
+
}
|
|
193
|
+
/* Shows the code around a place. */
|
|
194
|
+
select(id) {
|
|
195
|
+
const view = this.language.popups.getState().peek;
|
|
196
|
+
const location = this.places.get(id);
|
|
197
|
+
if (view === null || location === undefined) {
|
|
198
|
+
return;
|
|
188
199
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
200
|
+
const text = this.texts.get(location.uri);
|
|
201
|
+
const line = location.range.start.line;
|
|
202
|
+
const snippet = text === undefined ? null : this.kind === 'definitions' ? definitionSnippetOf(text, line, this.targets.get(placeKey(location)) ?? null, location.range) : snippetOf(text, line, location.range);
|
|
203
|
+
this.language.popups.setState({
|
|
204
|
+
peek: {
|
|
205
|
+
...view,
|
|
206
|
+
active: id,
|
|
207
|
+
preview: snippet === null ? null : {
|
|
208
|
+
...snippet,
|
|
209
|
+
uri: location.uri
|
|
193
210
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
return true;
|
|
207
|
-
default:
|
|
208
|
-
return false;
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
/* Folds the places of a file away from the list, or brings them back. */
|
|
215
|
+
toggleFile(uri) {
|
|
216
|
+
const view = this.language.popups.getState().peek;
|
|
217
|
+
if (view !== null) {
|
|
218
|
+
const collapsed = view.collapsed.includes(uri) ? view.collapsed.filter(other => other !== uri) : [...view.collapsed, uri];
|
|
219
|
+
this.language.popups.setState({
|
|
220
|
+
peek: {
|
|
221
|
+
...view,
|
|
222
|
+
collapsed
|
|
209
223
|
}
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/* Goes to a place and closes the peek. */
|
|
228
|
+
go(id) {
|
|
229
|
+
const location = this.places.get(id);
|
|
230
|
+
if (location !== undefined) {
|
|
231
|
+
this.close();
|
|
232
|
+
this.language.goTo(location);
|
|
210
233
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
}
|
|
234
|
+
}
|
|
235
|
+
mounted(container) {
|
|
236
|
+
const view = this.language.popups.getState().peek;
|
|
237
|
+
if (view !== null && view.container !== container) {
|
|
238
|
+
this.language.popups.setState({
|
|
239
|
+
peek: {
|
|
240
|
+
...view,
|
|
241
|
+
container
|
|
220
242
|
}
|
|
243
|
+
});
|
|
244
|
+
revealRow(this.timers, container);
|
|
221
245
|
}
|
|
222
|
-
|
|
223
|
-
|
|
246
|
+
}
|
|
247
|
+
key(event) {
|
|
248
|
+
const view = this.language.popups.getState().peek;
|
|
249
|
+
if (view === null || event.metaKey || event.ctrlKey || event.altKey) {
|
|
250
|
+
return false;
|
|
224
251
|
}
|
|
225
|
-
|
|
226
|
-
|
|
252
|
+
switch (event.key) {
|
|
253
|
+
case 'ArrowDown':
|
|
254
|
+
this.step(view, 1);
|
|
255
|
+
return true;
|
|
256
|
+
case 'ArrowUp':
|
|
257
|
+
this.step(view, -1);
|
|
258
|
+
return true;
|
|
259
|
+
case 'Enter':
|
|
260
|
+
this.go(view.active);
|
|
261
|
+
return true;
|
|
262
|
+
case 'Escape':
|
|
263
|
+
this.close();
|
|
264
|
+
return true;
|
|
265
|
+
default:
|
|
266
|
+
return false;
|
|
227
267
|
}
|
|
228
|
-
}
|
|
268
|
+
}
|
|
269
|
+
/* The next place in the list a person can see, which a folded file has none of. */
|
|
270
|
+
step(view, direction) {
|
|
271
|
+
const index = this.order.indexOf(view.active);
|
|
272
|
+
for (let next = index + direction; next >= 0 && next < this.order.length; next += direction) {
|
|
273
|
+
const id = this.order[next];
|
|
274
|
+
if (!view.collapsed.includes(this.places.get(id).uri)) {
|
|
275
|
+
this.select(id);
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
tell(title) {
|
|
281
|
+
this.language.project.host.notify?.({
|
|
282
|
+
id: TOAST_ID,
|
|
283
|
+
kind: 'error',
|
|
284
|
+
title
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
say(key, options) {
|
|
288
|
+
return this.language.project.i18n.t(`editor:language.peek.${key}`, options);
|
|
289
|
+
}
|
|
290
|
+
}
|