@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/code-vision.js
CHANGED
|
@@ -17,223 +17,241 @@ export const MAX_LINES = 20_000;
|
|
|
17
17
|
* stays on its row until the new one is in.
|
|
18
18
|
*/
|
|
19
19
|
export class CodeVisionFeature {
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
20
|
+
language;
|
|
21
|
+
timers;
|
|
22
|
+
settings = {
|
|
23
|
+
usages: false,
|
|
24
|
+
authors: false
|
|
25
|
+
};
|
|
26
|
+
declarations = [];
|
|
27
|
+
/* What the declarations were read from, so a count never outlives the text it was asked for. */
|
|
28
|
+
epoch = 0;
|
|
29
|
+
edited = false;
|
|
30
|
+
counts = new Map();
|
|
31
|
+
queue = [];
|
|
32
|
+
/* Scrolling changes the pending queue but keeps requests already in flight. */
|
|
33
|
+
running = new Map();
|
|
34
|
+
/* Declarations a server could not count for this text, which are not asked again until it says it can. */
|
|
35
|
+
failed = new Set();
|
|
36
|
+
blame = null;
|
|
37
|
+
/* The text the declarations were read from, which the lines of their authors are counted in. */
|
|
38
|
+
lines = [];
|
|
39
|
+
mapped = null;
|
|
40
|
+
authorships = new Map();
|
|
41
|
+
scrollTimer;
|
|
42
|
+
publishing = false;
|
|
43
|
+
disposed = false;
|
|
44
|
+
constructor(language, onSymbols, timers = realTimers) {
|
|
45
|
+
this.language = language;
|
|
46
|
+
this.timers = timers;
|
|
47
|
+
const {
|
|
48
|
+
editor
|
|
49
|
+
} = language;
|
|
50
|
+
const offs = [onSymbols(result => this.read(result)), editor.onTextChange(() => {
|
|
51
|
+
this.edited = true;
|
|
52
|
+
this.closeAuthors();
|
|
53
|
+
}), editor.onViewChange(() => {
|
|
54
|
+
this.timers.clear(this.scrollTimer);
|
|
55
|
+
this.scrollTimer = this.timers.set(() => this.plan(), SCROLL_PAUSE_MS);
|
|
56
|
+
})];
|
|
57
|
+
const providers = language.onProvidersChanged(() => {
|
|
58
|
+
this.failed.clear();
|
|
59
|
+
this.publish();
|
|
60
|
+
this.plan();
|
|
61
|
+
});
|
|
62
|
+
language.onDispose(() => {
|
|
63
|
+
this.disposed = true;
|
|
64
|
+
for (const off of offs) {
|
|
65
|
+
off();
|
|
66
|
+
}
|
|
67
|
+
providers();
|
|
68
|
+
this.timers.clear(this.scrollTimer);
|
|
69
|
+
for (const controller of this.running.values()) {
|
|
70
|
+
controller.abort();
|
|
71
|
+
}
|
|
72
|
+
this.closeAuthors();
|
|
73
|
+
editor.setCodeVision([]);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
/* Which rows to draw, from the settings of the client. */
|
|
77
|
+
configure(settings) {
|
|
78
|
+
if (settings.usages === this.settings.usages && settings.authors === this.settings.authors) {
|
|
79
|
+
return;
|
|
74
80
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
this.settings = settings;
|
|
82
|
+
this.publish();
|
|
83
|
+
this.plan();
|
|
84
|
+
}
|
|
85
|
+
/* What git says about the file, from the client that asked it. */
|
|
86
|
+
setBlame(blame) {
|
|
87
|
+
this.blame = blame;
|
|
88
|
+
this.mapped = null;
|
|
89
|
+
this.authorships.clear();
|
|
90
|
+
this.publish();
|
|
91
|
+
}
|
|
92
|
+
read(result) {
|
|
93
|
+
const {
|
|
94
|
+
editor,
|
|
95
|
+
languageId
|
|
96
|
+
} = this.language;
|
|
97
|
+
const lines = splitLines(editor.getText());
|
|
98
|
+
this.lines = lines;
|
|
99
|
+
this.mapped = null;
|
|
100
|
+
this.authorships.clear();
|
|
101
|
+
this.edited = false;
|
|
102
|
+
this.declarations = lines.length > MAX_LINES ? [] : declarationsOf(result, {
|
|
103
|
+
lineCount: lines.length,
|
|
104
|
+
lineAt: line => lines[line] ?? '',
|
|
105
|
+
languageId
|
|
106
|
+
});
|
|
107
|
+
this.epoch++;
|
|
108
|
+
this.failed.clear();
|
|
109
|
+
this.publish();
|
|
110
|
+
this.plan();
|
|
111
|
+
}
|
|
112
|
+
get canCount() {
|
|
113
|
+
return this.settings.usages && this.language.project.service.supports(REFERENCES, this.language.uri);
|
|
114
|
+
}
|
|
115
|
+
/* Queues the declarations in view whose count is not from the current text, nearest the top of the view first. */
|
|
116
|
+
plan() {
|
|
117
|
+
if (this.disposed || this.edited || !this.canCount) {
|
|
118
|
+
return;
|
|
83
119
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
120
|
+
const view = this.language.editor.getVisibleRange();
|
|
121
|
+
const first = view.start.line - MARGIN_LINES;
|
|
122
|
+
const last = view.end.line + MARGIN_LINES;
|
|
123
|
+
this.queue = this.declarations.filter(declaration => declaration.usages && declaration.line >= first && declaration.line <= last && this.counts.get(declaration.id)?.epoch !== this.epoch && !this.running.has(declaration.id) && !this.failed.has(declaration.id)).sort((left, right) => Math.abs(left.line - view.start.line) - Math.abs(right.line - view.start.line));
|
|
124
|
+
while (this.running.size < MAX_PARALLEL && this.queue.length > 0) {
|
|
125
|
+
void this.count(this.queue.shift());
|
|
90
126
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
127
|
+
}
|
|
128
|
+
async count(declaration) {
|
|
129
|
+
const {
|
|
130
|
+
project,
|
|
131
|
+
uri
|
|
132
|
+
} = this.language;
|
|
133
|
+
const controller = new AbortController();
|
|
134
|
+
this.running.set(declaration.id, controller);
|
|
135
|
+
const epoch = this.epoch;
|
|
136
|
+
try {
|
|
137
|
+
const locations = await project.service.references(uri, declaration.position, false, {
|
|
138
|
+
signal: controller.signal,
|
|
139
|
+
parallel: true
|
|
140
|
+
});
|
|
141
|
+
if (!this.disposed && epoch === this.epoch) {
|
|
142
|
+
this.counts.set(declaration.id, {
|
|
143
|
+
count: distinctPlaces(locations ?? []),
|
|
144
|
+
epoch
|
|
145
|
+
});
|
|
102
146
|
this.publish();
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
|
|
147
|
+
}
|
|
148
|
+
} catch {
|
|
149
|
+
// A text that moved on is counted again from its own symbols; for a server that is not up the declaration waits for it to say so.
|
|
150
|
+
if (epoch === this.epoch) {
|
|
151
|
+
this.failed.add(declaration.id);
|
|
152
|
+
}
|
|
153
|
+
} finally {
|
|
154
|
+
this.running.delete(declaration.id);
|
|
155
|
+
this.plan();
|
|
107
156
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const view = this.language.editor.getVisibleRange();
|
|
114
|
-
const first = view.start.line - MARGIN_LINES;
|
|
115
|
-
const last = view.end.line + MARGIN_LINES;
|
|
116
|
-
this.queue = this.declarations
|
|
117
|
-
.filter((declaration) => declaration.usages &&
|
|
118
|
-
declaration.line >= first &&
|
|
119
|
-
declaration.line <= last &&
|
|
120
|
-
this.counts.get(declaration.id)?.epoch !== this.epoch &&
|
|
121
|
-
!this.running.has(declaration.id) &&
|
|
122
|
-
!this.failed.has(declaration.id))
|
|
123
|
-
.sort((left, right) => Math.abs(left.line - view.start.line) - Math.abs(right.line - view.start.line));
|
|
124
|
-
while (this.running.size < MAX_PARALLEL && this.queue.length > 0) {
|
|
125
|
-
void this.count(this.queue.shift());
|
|
126
|
-
}
|
|
157
|
+
}
|
|
158
|
+
/* Said once for every change that lands in the same turn, since each is a pass over the rows of the layout. */
|
|
159
|
+
publish() {
|
|
160
|
+
if (this.publishing) {
|
|
161
|
+
return;
|
|
127
162
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
this.publishing = true;
|
|
157
|
-
queueMicrotask(() => {
|
|
158
|
-
this.publishing = false;
|
|
159
|
-
if (!this.disposed) {
|
|
160
|
-
this.language.editor.setCodeVision(this.rows());
|
|
161
|
-
}
|
|
163
|
+
this.publishing = true;
|
|
164
|
+
queueMicrotask(() => {
|
|
165
|
+
this.publishing = false;
|
|
166
|
+
if (!this.disposed) {
|
|
167
|
+
this.language.editor.setCodeVision(this.rows());
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
rows() {
|
|
172
|
+
const rows = [];
|
|
173
|
+
const taken = new Set();
|
|
174
|
+
const counted = this.canCount;
|
|
175
|
+
const withAuthors = this.settings.authors && this.blame !== null;
|
|
176
|
+
const commits = this.blame?.kind === 'ready' ? this.blame.blame.commits : [];
|
|
177
|
+
const mapped = this.blame?.kind === 'ready' && this.settings.authors ? this.mapOfBlame(this.blame) : null;
|
|
178
|
+
for (const declaration of this.declarations) {
|
|
179
|
+
const reserved = counted && declaration.usages || withAuthors && declaration.authors;
|
|
180
|
+
if (!reserved || taken.has(declaration.line)) {
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
taken.add(declaration.line);
|
|
184
|
+
const entries = [];
|
|
185
|
+
const known = this.counts.get(declaration.id);
|
|
186
|
+
if (counted && declaration.usages && known !== undefined) {
|
|
187
|
+
entries.push({
|
|
188
|
+
id: 'usages',
|
|
189
|
+
text: usagesText(known.count, this.language.project.i18n),
|
|
190
|
+
activate: () => void this.language.peek.open(declaration.position)
|
|
162
191
|
});
|
|
192
|
+
}
|
|
193
|
+
if (mapped !== null && declaration.authors) {
|
|
194
|
+
const authorship = this.authorshipOf(declaration, commits, mapped);
|
|
195
|
+
entries.push({
|
|
196
|
+
id: 'authors',
|
|
197
|
+
text: authorsText(authorship, this.language.project.i18n),
|
|
198
|
+
...(authorship.authors.length > 0 ? {
|
|
199
|
+
icon: authorship.authors.length > 1 ? 'users' : 'user'
|
|
200
|
+
} : {}),
|
|
201
|
+
activate: anchor => this.showAuthors(declaration, authorship, anchor)
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
rows.push({
|
|
205
|
+
id: declaration.id,
|
|
206
|
+
line: declaration.line,
|
|
207
|
+
entries
|
|
208
|
+
});
|
|
163
209
|
}
|
|
164
|
-
rows
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
const mapped = this.blame?.kind === 'ready' && this.settings.authors ? this.mapOfBlame(this.blame) : null;
|
|
171
|
-
for (const declaration of this.declarations) {
|
|
172
|
-
const reserved = (counted && declaration.usages) || (withAuthors && declaration.authors);
|
|
173
|
-
if (!reserved || taken.has(declaration.line)) {
|
|
174
|
-
continue;
|
|
175
|
-
}
|
|
176
|
-
taken.add(declaration.line);
|
|
177
|
-
const entries = [];
|
|
178
|
-
const known = this.counts.get(declaration.id);
|
|
179
|
-
if (counted && declaration.usages && known !== undefined) {
|
|
180
|
-
entries.push({
|
|
181
|
-
id: 'usages',
|
|
182
|
-
text: usagesText(known.count, this.language.project.i18n),
|
|
183
|
-
activate: () => void this.language.peek.open(declaration.position)
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
if (mapped !== null && declaration.authors) {
|
|
187
|
-
const authorship = this.authorshipOf(declaration, commits, mapped);
|
|
188
|
-
entries.push({
|
|
189
|
-
id: 'authors',
|
|
190
|
-
text: authorsText(authorship, this.language.project.i18n),
|
|
191
|
-
...(authorship.authors.length > 0 ? { icon: authorship.authors.length > 1 ? 'users' : 'user' } : {}),
|
|
192
|
-
activate: (anchor) => this.showAuthors(declaration, authorship, anchor)
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
rows.push({ id: declaration.id, line: declaration.line, entries });
|
|
196
|
-
}
|
|
197
|
-
return rows;
|
|
198
|
-
}
|
|
199
|
-
authorshipOf(declaration, commits, mapped) {
|
|
200
|
-
const known = this.authorships.get(declaration.id);
|
|
201
|
-
if (known !== undefined) {
|
|
202
|
-
return known;
|
|
203
|
-
}
|
|
204
|
-
const authorship = authorshipOf(commits, mapped, this.lines, declaration.authorFrom, declaration.authorTo);
|
|
205
|
-
this.authorships.set(declaration.id, authorship);
|
|
206
|
-
return authorship;
|
|
207
|
-
}
|
|
208
|
-
mapOfBlame(source) {
|
|
209
|
-
if (this.mapped?.blame !== source.blame) {
|
|
210
|
-
this.mapped = { blame: source.blame, lines: mapBlame(source.blame, source.base, this.lines) };
|
|
211
|
-
}
|
|
212
|
-
return this.mapped.lines;
|
|
210
|
+
return rows;
|
|
211
|
+
}
|
|
212
|
+
authorshipOf(declaration, commits, mapped) {
|
|
213
|
+
const known = this.authorships.get(declaration.id);
|
|
214
|
+
if (known !== undefined) {
|
|
215
|
+
return known;
|
|
213
216
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
});
|
|
217
|
+
const authorship = authorshipOf(commits, mapped, this.lines, declaration.authorFrom, declaration.authorTo);
|
|
218
|
+
this.authorships.set(declaration.id, authorship);
|
|
219
|
+
return authorship;
|
|
220
|
+
}
|
|
221
|
+
mapOfBlame(source) {
|
|
222
|
+
if (this.mapped?.blame !== source.blame) {
|
|
223
|
+
this.mapped = {
|
|
224
|
+
blame: source.blame,
|
|
225
|
+
lines: mapBlame(source.blame, source.base, this.lines)
|
|
226
|
+
};
|
|
225
227
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
228
|
+
return this.mapped.lines;
|
|
229
|
+
}
|
|
230
|
+
showAuthors(declaration, authorship, anchor) {
|
|
231
|
+
const source = this.blame;
|
|
232
|
+
const openCommit = source?.kind === 'ready' ? source.openCommit : undefined;
|
|
233
|
+
this.language.popups.setState({
|
|
234
|
+
authors: {
|
|
235
|
+
anchor,
|
|
236
|
+
name: declaration.name,
|
|
237
|
+
authorship,
|
|
238
|
+
openCommit: openCommit === undefined || authorship.latest === null ? null : () => openCommit(authorship.latest.hash)
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
/* Closes the card of the authors; `restoreFocus` is for a close that came from the keyboard, which gives the editor its keys back. */
|
|
243
|
+
closeAuthors(restoreFocus = false) {
|
|
244
|
+
if (this.language.popups.getState().authors !== null) {
|
|
245
|
+
this.language.popups.setState({
|
|
246
|
+
authors: null
|
|
247
|
+
});
|
|
248
|
+
if (restoreFocus) {
|
|
249
|
+
this.language.editor.focus();
|
|
250
|
+
}
|
|
234
251
|
}
|
|
252
|
+
}
|
|
235
253
|
}
|
|
236
254
|
/* The places a server named, each counted once however many ways it was reached. */
|
|
237
255
|
function distinctPlaces(locations) {
|
|
238
|
-
|
|
239
|
-
}
|
|
256
|
+
return new Set(locations.map(location => `${location.uri}\0${location.range.start.line}\0${location.range.start.character}`)).size;
|
|
257
|
+
}
|
package/dist/completion-call.js
CHANGED
|
@@ -11,68 +11,66 @@ const EXISTING_CALL = /^\s*\(/;
|
|
|
11
11
|
const SIGNATURE_KIND_PREFIX = /^\([a-z]+(?: [a-z]+)*\)\s+(?!=>)/;
|
|
12
12
|
/* Whether the item is something that is called where it stands: a function, a method, a constructor, or a class after `new`. */
|
|
13
13
|
export function isCallItem(item, lineBefore) {
|
|
14
|
-
|
|
14
|
+
return isCallableKind(item.kind) || item.kind === CLASS_KIND && AFTER_NEW.test(lineBefore);
|
|
15
15
|
}
|
|
16
16
|
/* Whether the parameter list in a signature has anything in it; null when the text names no list. */
|
|
17
17
|
function listedParameters(signature) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
let depth = 0;
|
|
24
|
-
for (let i = open; i < text.length; i++) {
|
|
25
|
-
if (text[i] === '(') {
|
|
26
|
-
depth++;
|
|
27
|
-
}
|
|
28
|
-
else if (text[i] === ')' && --depth === 0) {
|
|
29
|
-
return text.slice(open + 1, i).trim() !== '';
|
|
30
|
-
}
|
|
31
|
-
}
|
|
18
|
+
const text = signature.replace(SIGNATURE_KIND_PREFIX, '');
|
|
19
|
+
const open = text.indexOf('(');
|
|
20
|
+
if (open < 0) {
|
|
32
21
|
return null;
|
|
22
|
+
}
|
|
23
|
+
let depth = 0;
|
|
24
|
+
for (let i = open; i < text.length; i++) {
|
|
25
|
+
if (text[i] === '(') {
|
|
26
|
+
depth++;
|
|
27
|
+
} else if (text[i] === ')' && --depth === 0) {
|
|
28
|
+
return text.slice(open + 1, i).trim() !== '';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
33
32
|
}
|
|
34
33
|
/* From what the server says of the item: `(method) Box.open(flag: boolean): void` has parameters and `(): void` has none. Null when it says nothing about them. */
|
|
35
34
|
export function hasParameters(item) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
35
|
+
const lines = (item.detail ?? '').split('\n').filter(line => !SOURCE_LINE.test(line.trim()));
|
|
36
|
+
for (const signature of [item.labelDetails?.detail ?? '', ...lines]) {
|
|
37
|
+
const listed = listedParameters(signature);
|
|
38
|
+
if (listed !== null) {
|
|
39
|
+
return listed;
|
|
42
40
|
}
|
|
43
|
-
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
44
43
|
}
|
|
45
44
|
/* The text before the innermost brace that is still open, which says whether the caret is in an import or export list. */
|
|
46
45
|
function beforeOpenBrace(before) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return before.slice(0, i);
|
|
54
|
-
}
|
|
46
|
+
let depth = 0;
|
|
47
|
+
for (let i = before.length - 1; i >= 0; i--) {
|
|
48
|
+
if (before[i] === '}') {
|
|
49
|
+
depth++;
|
|
50
|
+
} else if (before[i] === '{' && depth-- === 0) {
|
|
51
|
+
return before.slice(0, i);
|
|
55
52
|
}
|
|
56
|
-
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
57
55
|
}
|
|
58
56
|
/* Where a name is not called: in an import or export list, a `use`, a type operator's operand, an attribute or a tag. */
|
|
59
57
|
function isNameOnly(languageId, before) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
58
|
+
const lineBefore = before.slice(before.lastIndexOf('\n') + 1);
|
|
59
|
+
const brace = beforeOpenBrace(before);
|
|
60
|
+
if (brace !== null && (IMPORT_BRACE.test(brace) || languageId === 'php' && PHP_USE_BRACE.test(brace))) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
if (TYPE_OPERATOR.test(lineBefore) || /^\s*export\s+default\s+[\w$]*$/.test(lineBefore)) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
switch (languageId) {
|
|
67
|
+
case 'php':
|
|
68
|
+
return /^\s*use\s/.test(lineBefore) || /#\[[^\]]*$/.test(lineBefore);
|
|
69
|
+
case 'python':
|
|
70
|
+
return /^\s*(?:from\s+\S+\s+)?import\b/.test(lineBefore);
|
|
71
|
+
default:
|
|
72
|
+
return /^\s*import\b/.test(lineBefore) || MARKUP_LANGUAGES.has(languageId) && /<\/?[\w$.:-]*$/.test(lineBefore);
|
|
73
|
+
}
|
|
76
74
|
}
|
|
77
75
|
/*
|
|
78
76
|
* Decides what accepting `item` does about a call, as the platform's parentheses handler does: a callable
|
|
@@ -81,26 +79,55 @@ function isNameOnly(languageId, before) {
|
|
|
81
79
|
* parenthesis, carries its own call and wins.
|
|
82
80
|
*/
|
|
83
81
|
export function planCall(site) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
return {
|
|
82
|
+
const {
|
|
83
|
+
item,
|
|
84
|
+
languageId,
|
|
85
|
+
insertion,
|
|
86
|
+
before,
|
|
87
|
+
rest,
|
|
88
|
+
replace
|
|
89
|
+
} = site;
|
|
90
|
+
const lineBefore = before.slice(before.lastIndexOf('\n') + 1);
|
|
91
|
+
if (!CALL_LANGUAGES.has(languageId) || !isCallItem(item, lineBefore) || item.insertTextFormat === SNIPPET_FORMAT || insertion.text.includes('(')) {
|
|
92
|
+
return {
|
|
93
|
+
action: 'none'
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
if (isNameOnly(languageId, before)) {
|
|
97
|
+
return {
|
|
98
|
+
action: 'none'
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
const existing = EXISTING_CALL.exec(rest);
|
|
102
|
+
if (existing !== null) {
|
|
103
|
+
return replace ? {
|
|
104
|
+
action: 'enter',
|
|
105
|
+
shift: existing[0].length
|
|
106
|
+
} : {
|
|
107
|
+
action: 'none'
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
if (rest.startsWith('<')) {
|
|
111
|
+
return {
|
|
112
|
+
action: 'none'
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
action: 'add',
|
|
117
|
+
inside: hasParameters(item) !== false
|
|
118
|
+
};
|
|
100
119
|
}
|
|
101
120
|
/* The insertion with its parentheses, and the one tab stop that puts the caret where the plan says. */
|
|
102
121
|
export function withParentheses(insertion, inside) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
122
|
+
const text = `${insertion.text}()`;
|
|
123
|
+
const caret = inside ? text.length - 1 : text.length;
|
|
124
|
+
return {
|
|
125
|
+
range: insertion.range,
|
|
126
|
+
text,
|
|
127
|
+
stops: [{
|
|
128
|
+
index: 0,
|
|
129
|
+
start: caret,
|
|
130
|
+
end: caret
|
|
131
|
+
}]
|
|
132
|
+
};
|
|
133
|
+
}
|