@adecore/editor-react 0.31.12 → 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/rename.js
CHANGED
|
@@ -17,256 +17,344 @@ const CONTEXT_LINES = 3;
|
|
|
17
17
|
* Edits to other files land as unsaved drafts (`applyWorkspaceEdit`), so nothing is written to disk here.
|
|
18
18
|
*/
|
|
19
19
|
export class RenameFeature {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
20
|
+
language;
|
|
21
|
+
session = null;
|
|
22
|
+
constructor(language) {
|
|
23
|
+
this.language = language;
|
|
24
|
+
const {
|
|
25
|
+
editor
|
|
26
|
+
} = language;
|
|
27
|
+
const offs = [language.onKey(event => {
|
|
28
|
+
if (!isShortcut(this.language.shortcuts.rename, event)) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
void this.start();
|
|
32
|
+
return true;
|
|
33
|
+
}, KEY_PRIORITY.rename), editor.onTextChange(() => this.cancel())];
|
|
34
|
+
language.onDispose(() => {
|
|
35
|
+
for (const off of offs) {
|
|
36
|
+
off();
|
|
37
|
+
}
|
|
38
|
+
this.cancel();
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
get isOpen() {
|
|
42
|
+
return this.session !== null;
|
|
43
|
+
}
|
|
44
|
+
async start() {
|
|
45
|
+
const {
|
|
46
|
+
editor,
|
|
47
|
+
project,
|
|
48
|
+
uri
|
|
49
|
+
} = this.language;
|
|
50
|
+
if (!project.service.supports(METHOD, uri)) {
|
|
51
|
+
this.tell('error', this.say('unavailable'));
|
|
52
|
+
return;
|
|
41
53
|
}
|
|
42
|
-
|
|
43
|
-
|
|
54
|
+
this.cancel();
|
|
55
|
+
const caret = editor.getCaret();
|
|
56
|
+
const prepare = project.service.providerOptions(METHOD, uri)?.prepareProvider === true;
|
|
57
|
+
let answer;
|
|
58
|
+
try {
|
|
59
|
+
answer = prepare ? await project.service.prepareRename(uri, caret) : {
|
|
60
|
+
defaultBehavior: true
|
|
61
|
+
};
|
|
62
|
+
} catch (error) {
|
|
63
|
+
if (!(error instanceof StaleResultError)) {
|
|
64
|
+
this.tell('error', this.say('nothing'));
|
|
65
|
+
}
|
|
66
|
+
return;
|
|
44
67
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
this.cancel();
|
|
52
|
-
const caret = editor.getCaret();
|
|
53
|
-
const prepare = project.service.providerOptions(METHOD, uri)?.prepareProvider === true;
|
|
54
|
-
let answer;
|
|
55
|
-
try {
|
|
56
|
-
answer = prepare ? await project.service.prepareRename(uri, caret) : { defaultBehavior: true };
|
|
57
|
-
}
|
|
58
|
-
catch (error) {
|
|
59
|
-
if (!(error instanceof StaleResultError)) {
|
|
60
|
-
this.tell('error', this.say('nothing'));
|
|
61
|
-
}
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
const target = renameTargetOf(answer, (range) => editor.textInRange(range), () => wordRangeAt(lineTextOf(editor, caret.line), caret));
|
|
65
|
-
if (target === null) {
|
|
66
|
-
this.tell('error', this.say('nothing'));
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
const session = { target, original: editor.textInRange(target.range), edit: null, names: new AbortController() };
|
|
70
|
-
this.session = session;
|
|
71
|
-
this.publish({ phase: 'input', busy: false, name: target.placeholder, files: [], operations: [], occurrences: null, suggestions: [] });
|
|
72
|
-
void this.light(session).then((locations) => this.suggest(session, locations));
|
|
68
|
+
const target = renameTargetOf(answer, range => editor.textInRange(range), () => wordRangeAt(lineTextOf(editor, caret.line), caret));
|
|
69
|
+
if (target === null) {
|
|
70
|
+
this.tell('error', this.say('nothing'));
|
|
71
|
+
return;
|
|
73
72
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
await this.apply(session);
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
const files = await renamePreviewOf(edit, (target) => project.readText(target));
|
|
102
|
-
if (this.session !== session) {
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
this.publish({ phase: 'preview', busy: false, name: next, files, operations: resourceOperationsOf(edit) });
|
|
106
|
-
}
|
|
107
|
-
catch (error) {
|
|
108
|
-
if (this.session === session) {
|
|
109
|
-
this.fail(error instanceof StaleResultError ? this.say('stale') : messageOf(error));
|
|
110
|
-
}
|
|
111
|
-
}
|
|
73
|
+
const session = {
|
|
74
|
+
target,
|
|
75
|
+
original: editor.textInRange(target.range),
|
|
76
|
+
edit: null,
|
|
77
|
+
names: new AbortController()
|
|
78
|
+
};
|
|
79
|
+
this.session = session;
|
|
80
|
+
this.publish({
|
|
81
|
+
phase: 'input',
|
|
82
|
+
busy: false,
|
|
83
|
+
name: target.placeholder,
|
|
84
|
+
files: [],
|
|
85
|
+
operations: [],
|
|
86
|
+
occurrences: null,
|
|
87
|
+
suggestions: []
|
|
88
|
+
});
|
|
89
|
+
void this.light(session).then(locations => this.suggest(session, locations));
|
|
90
|
+
}
|
|
91
|
+
/* The name was typed: Enter applies it, Shift+Enter lists what it would change first. */
|
|
92
|
+
async submit(name, preview) {
|
|
93
|
+
const session = this.session;
|
|
94
|
+
const next = name.trim();
|
|
95
|
+
if (session === null) {
|
|
96
|
+
return;
|
|
112
97
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if (session?.edit) {
|
|
117
|
-
await this.apply(session);
|
|
118
|
-
}
|
|
98
|
+
if (next === '' || next === session.original) {
|
|
99
|
+
this.finish();
|
|
100
|
+
return;
|
|
119
101
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
102
|
+
this.publish({
|
|
103
|
+
phase: 'input',
|
|
104
|
+
busy: true,
|
|
105
|
+
name: next,
|
|
106
|
+
error: null
|
|
107
|
+
});
|
|
108
|
+
const {
|
|
109
|
+
project,
|
|
110
|
+
uri
|
|
111
|
+
} = this.language;
|
|
112
|
+
try {
|
|
113
|
+
const edit = await project.service.rename(uri, session.target.range.start, next);
|
|
114
|
+
if (this.session !== session) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (edit === null) {
|
|
118
|
+
this.fail(this.say('refused'));
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
session.edit = edit;
|
|
122
|
+
if (!preview) {
|
|
123
|
+
await this.apply(session);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const files = await renamePreviewOf(edit, target => project.readText(target));
|
|
127
|
+
if (this.session !== session) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
this.publish({
|
|
131
|
+
phase: 'preview',
|
|
132
|
+
busy: false,
|
|
133
|
+
name: next,
|
|
134
|
+
files,
|
|
135
|
+
operations: resourceOperationsOf(edit)
|
|
136
|
+
});
|
|
137
|
+
} catch (error) {
|
|
138
|
+
if (this.session === session) {
|
|
139
|
+
this.fail(error instanceof StaleResultError ? this.say('stale') : messageOf(error));
|
|
140
|
+
}
|
|
125
141
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
142
|
+
}
|
|
143
|
+
/* Applies the edit the preview showed. */
|
|
144
|
+
async confirm() {
|
|
145
|
+
const session = this.session;
|
|
146
|
+
if (session?.edit) {
|
|
147
|
+
await this.apply(session);
|
|
131
148
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
if (result.applied) {
|
|
138
|
-
this.finish();
|
|
139
|
-
}
|
|
140
|
-
else {
|
|
141
|
-
this.fail(result.failureReason ?? this.say('refused'));
|
|
142
|
-
}
|
|
149
|
+
}
|
|
150
|
+
cancel() {
|
|
151
|
+
if (this.session === null) {
|
|
152
|
+
return;
|
|
143
153
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
154
|
+
this.finish();
|
|
155
|
+
}
|
|
156
|
+
/* The name was changed, which answers the failure under it. */
|
|
157
|
+
edited() {
|
|
158
|
+
if (this.language.popups.getState().rename?.error != null) {
|
|
159
|
+
this.publish({
|
|
160
|
+
error: null
|
|
161
|
+
});
|
|
150
162
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
editor.setHighlights([]);
|
|
157
|
-
editor.focus();
|
|
163
|
+
}
|
|
164
|
+
async apply(session) {
|
|
165
|
+
const result = await this.language.project.applyWorkspaceEdit(session.edit);
|
|
166
|
+
if (this.session !== session) {
|
|
167
|
+
return;
|
|
158
168
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
return null;
|
|
164
|
-
}
|
|
165
|
-
try {
|
|
166
|
-
const locations = await project.service.references(uri, session.target.range.start, true);
|
|
167
|
-
if (this.session !== session || locations === null) {
|
|
168
|
-
return null;
|
|
169
|
-
}
|
|
170
|
-
const found = occurrencesOf(locations, uri);
|
|
171
|
-
editor.setHighlights(found.inFile.map((range) => ({ range, kind: 'write' })));
|
|
172
|
-
this.publish({ occurrences: { count: found.count, files: found.files } });
|
|
173
|
-
return locations;
|
|
174
|
-
}
|
|
175
|
-
catch {
|
|
176
|
-
// The count is a courtesy; renaming does not wait for it.
|
|
177
|
-
return null;
|
|
178
|
-
}
|
|
169
|
+
if (result.applied) {
|
|
170
|
+
this.finish();
|
|
171
|
+
} else {
|
|
172
|
+
this.fail(result.failureReason ?? this.say('refused'));
|
|
179
173
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
end: { line: line + CONTEXT_LINES, character: Number.MAX_SAFE_INTEGER }
|
|
195
|
-
});
|
|
196
|
-
const [uses, kind] = await Promise.all([this.linesOf(locations ?? []), this.kindOf(session, locations ?? [])]);
|
|
197
|
-
const request = { uri, languageId, name: session.original, ...(kind === undefined ? {} : { kind }), context, uses };
|
|
198
|
-
const names = await suggestNames(request, session.names.signal);
|
|
199
|
-
if (this.session === session && names.length > 0) {
|
|
200
|
-
this.publish({ suggestions: names });
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
catch {
|
|
204
|
-
// Suggestions do not prevent a manual rename.
|
|
205
|
-
}
|
|
174
|
+
}
|
|
175
|
+
/* The input stays, with the reason under it, so the name can be changed and tried again. */
|
|
176
|
+
fail(message) {
|
|
177
|
+
if (this.session !== null) {
|
|
178
|
+
this.session.edit = null;
|
|
179
|
+
this.publish({
|
|
180
|
+
phase: 'input',
|
|
181
|
+
busy: false,
|
|
182
|
+
files: [],
|
|
183
|
+
operations: [],
|
|
184
|
+
error: this.say('failed', {
|
|
185
|
+
message
|
|
186
|
+
})
|
|
187
|
+
});
|
|
206
188
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
189
|
+
}
|
|
190
|
+
finish() {
|
|
191
|
+
this.session?.names.abort();
|
|
192
|
+
this.session = null;
|
|
193
|
+
const {
|
|
194
|
+
editor,
|
|
195
|
+
popups
|
|
196
|
+
} = this.language;
|
|
197
|
+
popups.setState({
|
|
198
|
+
rename: null
|
|
199
|
+
});
|
|
200
|
+
editor.setHighlights([]);
|
|
201
|
+
editor.focus();
|
|
202
|
+
}
|
|
203
|
+
/* Lights up the places the name has in this file, and counts them all; what the servers listed, or null when they did not. */
|
|
204
|
+
async light(session) {
|
|
205
|
+
const {
|
|
206
|
+
editor,
|
|
207
|
+
project,
|
|
208
|
+
uri
|
|
209
|
+
} = this.language;
|
|
210
|
+
if (!project.service.supports('textDocument/references', uri)) {
|
|
211
|
+
return null;
|
|
220
212
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
if (text !== undefined && text.trim() !== '' && !lines.includes(text)) {
|
|
236
|
-
lines.push(text);
|
|
237
|
-
}
|
|
213
|
+
try {
|
|
214
|
+
const locations = await project.service.references(uri, session.target.range.start, true);
|
|
215
|
+
if (this.session !== session || locations === null) {
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
const found = occurrencesOf(locations, uri);
|
|
219
|
+
editor.setHighlights(found.inFile.map(range => ({
|
|
220
|
+
range,
|
|
221
|
+
kind: 'write'
|
|
222
|
+
})));
|
|
223
|
+
this.publish({
|
|
224
|
+
occurrences: {
|
|
225
|
+
count: found.count,
|
|
226
|
+
files: found.files
|
|
238
227
|
}
|
|
239
|
-
|
|
228
|
+
});
|
|
229
|
+
return locations;
|
|
230
|
+
} catch {
|
|
231
|
+
// The count is a courtesy; renaming does not wait for it.
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/*
|
|
236
|
+
* Names from the host suggestion provider, using the lines around the symbol and a sample of the lines that
|
|
237
|
+
* use it. They only appear under the input: the name that is typed stays the one that is applied.
|
|
238
|
+
*/
|
|
239
|
+
async suggest(session, locations) {
|
|
240
|
+
const suggestNames = this.language.project.host.suggestNames;
|
|
241
|
+
if (suggestNames === undefined || this.session !== session) {
|
|
242
|
+
return;
|
|
240
243
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
244
|
+
const {
|
|
245
|
+
editor,
|
|
246
|
+
languageId,
|
|
247
|
+
uri
|
|
248
|
+
} = this.language;
|
|
249
|
+
try {
|
|
250
|
+
const line = session.target.range.start.line;
|
|
251
|
+
const context = editor.textInRange({
|
|
252
|
+
start: {
|
|
253
|
+
line: Math.max(0, line - CONTEXT_LINES),
|
|
254
|
+
character: 0
|
|
255
|
+
},
|
|
256
|
+
end: {
|
|
257
|
+
line: line + CONTEXT_LINES,
|
|
258
|
+
character: Number.MAX_SAFE_INTEGER
|
|
245
259
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
...patch
|
|
263
|
-
}
|
|
260
|
+
});
|
|
261
|
+
const [uses, kind] = await Promise.all([this.linesOf(locations ?? []), this.kindOf(session, locations ?? [])]);
|
|
262
|
+
const request = {
|
|
263
|
+
uri,
|
|
264
|
+
languageId,
|
|
265
|
+
name: session.original,
|
|
266
|
+
...(kind === undefined ? {} : {
|
|
267
|
+
kind
|
|
268
|
+
}),
|
|
269
|
+
context,
|
|
270
|
+
uses
|
|
271
|
+
};
|
|
272
|
+
const names = await suggestNames(request, session.names.signal);
|
|
273
|
+
if (this.session === session && names.length > 0) {
|
|
274
|
+
this.publish({
|
|
275
|
+
suggestions: names
|
|
264
276
|
});
|
|
277
|
+
}
|
|
278
|
+
} catch {
|
|
279
|
+
// Suggestions do not prevent a manual rename.
|
|
265
280
|
}
|
|
266
|
-
|
|
267
|
-
|
|
281
|
+
}
|
|
282
|
+
/* So a suggester knows a function from a variable; a rename on a use finds the kind through the declaration's place in this file. */
|
|
283
|
+
async kindOf(session, locations) {
|
|
284
|
+
const {
|
|
285
|
+
project,
|
|
286
|
+
uri
|
|
287
|
+
} = this.language;
|
|
288
|
+
if (!project.service.supports('textDocument/documentSymbol', uri)) {
|
|
289
|
+
return undefined;
|
|
290
|
+
}
|
|
291
|
+
try {
|
|
292
|
+
const symbols = await project.service.documentSymbols(uri, {
|
|
293
|
+
signal: session.names.signal,
|
|
294
|
+
parallel: true
|
|
295
|
+
});
|
|
296
|
+
return renameKindOf(symbols, session.original, [session.target.range, ...occurrencesOf(locations, uri).inFile]);
|
|
297
|
+
} catch {
|
|
298
|
+
return undefined;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
/* The text of the first lines that name the symbol, in the order the servers listed them, reading at most a few other files. */
|
|
302
|
+
async linesOf(locations) {
|
|
303
|
+
const {
|
|
304
|
+
project
|
|
305
|
+
} = this.language;
|
|
306
|
+
const texts = new Map();
|
|
307
|
+
const lines = [];
|
|
308
|
+
let others = 0;
|
|
309
|
+
for (const location of locations.slice(0, SAMPLE_LOCATIONS)) {
|
|
310
|
+
if (!texts.has(location.uri)) {
|
|
311
|
+
if (location.uri !== this.language.uri && others++ >= SAMPLE_OTHER_FILES) {
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
texts.set(location.uri, (await project.readText(location.uri))?.split('\n') ?? null);
|
|
315
|
+
}
|
|
316
|
+
const text = texts.get(location.uri)?.[location.range.start.line];
|
|
317
|
+
if (text !== undefined && text.trim() !== '' && !lines.includes(text)) {
|
|
318
|
+
lines.push(text);
|
|
319
|
+
}
|
|
268
320
|
}
|
|
269
|
-
|
|
270
|
-
|
|
321
|
+
return lines;
|
|
322
|
+
}
|
|
323
|
+
publish(patch) {
|
|
324
|
+
const session = this.session;
|
|
325
|
+
if (session === null) {
|
|
326
|
+
return;
|
|
271
327
|
}
|
|
272
|
-
|
|
328
|
+
const {
|
|
329
|
+
popups
|
|
330
|
+
} = this.language;
|
|
331
|
+
const current = popups.getState().rename;
|
|
332
|
+
popups.setState({
|
|
333
|
+
rename: {
|
|
334
|
+
phase: 'input',
|
|
335
|
+
range: session.target.range,
|
|
336
|
+
original: session.original,
|
|
337
|
+
placeholder: session.target.placeholder,
|
|
338
|
+
occurrences: null,
|
|
339
|
+
busy: false,
|
|
340
|
+
error: null,
|
|
341
|
+
name: session.target.placeholder,
|
|
342
|
+
files: [],
|
|
343
|
+
operations: [],
|
|
344
|
+
suggestions: [],
|
|
345
|
+
...current,
|
|
346
|
+
...patch
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
tell(kind, title) {
|
|
351
|
+
this.language.project.host.notify?.({
|
|
352
|
+
id: TOAST_ID,
|
|
353
|
+
kind,
|
|
354
|
+
title
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
say(key, options) {
|
|
358
|
+
return this.language.project.i18n.t(`editor:language.rename.${key}`, options);
|
|
359
|
+
}
|
|
360
|
+
}
|
package/dist/rendered-docs.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export declare class RenderedDocsFeature {
|
|
|
26
26
|
private readonly revealed;
|
|
27
27
|
private readonly listeners;
|
|
28
28
|
private version;
|
|
29
|
+
private shown;
|
|
29
30
|
private settleTimer;
|
|
30
31
|
private caretTimer;
|
|
31
32
|
private drawn;
|
|
@@ -39,8 +40,9 @@ export declare class RenderedDocsFeature {
|
|
|
39
40
|
toggle(): boolean;
|
|
40
41
|
toggleAt(startLine: number): boolean;
|
|
41
42
|
entries(): readonly RenderedDocEntry[];
|
|
42
|
-
getVersion
|
|
43
|
-
|
|
43
|
+
getVersion(): number;
|
|
44
|
+
getEntries(): readonly RenderedDocEntry[];
|
|
45
|
+
subscribe(listener: () => void): () => void;
|
|
44
46
|
get canFollow(): boolean;
|
|
45
47
|
follow(name: string, comment: DocComment): void;
|
|
46
48
|
private idOf;
|