Skip to content

Commit 52f8862

Browse files
committed
rename suggestions: cancel rename suggestion providers if user started typing
1 parent fab256d commit 52f8862

File tree

2 files changed

+21
-9
lines changed

2 files changed

+21
-9
lines changed

src/vs/editor/contrib/rename/browser/rename.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -229,19 +229,18 @@ class RenameController implements IEditorContribution {
229229

230230
const model = this.editor.getModel(); // @ulugbekna: assumes editor still has a model, otherwise, cts1 should've been cancelled
231231

232-
const renameCandidatesCts = new CancellationTokenSource(cts2.token);
233232
const newSymbolNamesProviders = this._languageFeaturesService.newSymbolNamesProvider.all(model);
234-
const newSymbolNameProvidersResults = newSymbolNamesProviders.map(p => p.provideNewSymbolNames(model, loc.range, renameCandidatesCts.token));
235-
trace(`requested new symbol names from ${newSymbolNamesProviders.length} providers`);
233+
234+
const requestRenameSuggestions = (cts: CancellationToken) => newSymbolNamesProviders.map(p => p.provideNewSymbolNames(model, loc.range, cts));
236235

237236
trace('creating rename input field and awaiting its result');
238237
const supportPreview = this._bulkEditService.hasPreviewHandler() && this._configService.getValue<boolean>(this.editor.getModel().uri, 'editor.rename.enablePreview');
239238
const inputFieldResult = await this._renameInputField.getInput(
240239
loc.range,
241240
loc.text,
242241
supportPreview,
243-
newSymbolNameProvidersResults,
244-
renameCandidatesCts
242+
requestRenameSuggestions,
243+
cts2
245244
);
246245
trace('received response from rename input field');
247246

src/vs/editor/contrib/rename/browser/renameInputField.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ interface IRenameInputField {
8989
where: IRange,
9090
currentName: string,
9191
supportPreview: boolean,
92-
candidates: ProviderResult<NewSymbolName[]>[],
92+
requestRenameSuggestions: (cts: CancellationToken) => ProviderResult<NewSymbolName[]>[],
9393
cts: CancellationTokenSource
9494
): Promise<RenameInputFieldResult | boolean>;
9595

@@ -133,6 +133,8 @@ export class RenameWidget implements IRenameInputField, IContentWidget, IDisposa
133133
*/
134134
private _timeBeforeFirstInputFieldEdit: number | undefined;
135135

136+
private _renameCandidateProvidersCts: CancellationTokenSource | undefined;
137+
136138
private readonly _visibleContextKey: IContextKey<boolean>;
137139
private readonly _disposables = new DisposableStore();
138140

@@ -200,6 +202,9 @@ export class RenameWidget implements IRenameInputField, IContentWidget, IDisposa
200202
this._isEditingRenameCandidate = true;
201203
}
202204
this._timeBeforeFirstInputFieldEdit ??= this._beforeFirstInputFieldEditSW.elapsed();
205+
if (this._renameCandidateProvidersCts?.token.isCancellationRequested === false) {
206+
this._renameCandidateProvidersCts.cancel();
207+
}
203208
this._renameCandidateListView?.clearFocus();
204209
})
205210
);
@@ -356,12 +361,16 @@ export class RenameWidget implements IRenameInputField, IContentWidget, IDisposa
356361
where: IRange,
357362
currentName: string,
358363
supportPreview: boolean,
359-
candidates: ProviderResult<NewSymbolName[]>[],
364+
requestRenameSuggestions: (cts: CancellationToken) => ProviderResult<NewSymbolName[]>[],
360365
cts: CancellationTokenSource
361366
): Promise<RenameInputFieldResult | boolean> {
362367

363368
const { start: selectionStart, end: selectionEnd } = this._getSelection(where, currentName);
364369

370+
this._renameCandidateProvidersCts = new CancellationTokenSource();
371+
const candidates = requestRenameSuggestions(this._renameCandidateProvidersCts.token);
372+
this._updateRenameCandidates(candidates, currentName, cts.token);
373+
365374
this._isEditingRenameCandidate = false;
366375

367376
this._domNode!.classList.toggle('preview', supportPreview);
@@ -379,8 +388,12 @@ export class RenameWidget implements IRenameInputField, IContentWidget, IDisposa
379388
const disposeOnDone = new DisposableStore();
380389

381390
disposeOnDone.add(toDisposable(() => cts.dispose(true))); // @ulugbekna: this may result in `this.cancelInput` being called twice, but it should be safe since we set it to undefined after 1st call
382-
383-
this._updateRenameCandidates(candidates, currentName, cts.token);
391+
disposeOnDone.add(toDisposable(() => {
392+
if (this._renameCandidateProvidersCts !== undefined) {
393+
this._renameCandidateProvidersCts.dispose(true);
394+
this._renameCandidateProvidersCts = undefined;
395+
}
396+
}));
384397

385398
const inputResult = new DeferredPromise<RenameInputFieldResult | boolean>();
386399

0 commit comments

Comments
 (0)