Skip to content

Commit 3c18886

Browse files
author
Benjamin Pasero
committed
quick access - some cleanup in symbols support
1 parent d9d90a0 commit 3c18886

3 files changed

Lines changed: 72 additions & 49 deletions

File tree

src/vs/editor/contrib/quickAccess/gotoSymbolQuickAccess.ts

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { trim, format } from 'vs/base/common/strings';
1818
import { fuzzyScore, FuzzyScore, createMatches } from 'vs/base/common/filters';
1919
import { assign } from 'vs/base/common/objects';
2020

21-
interface IGotoSymbolQuickPickItem extends IQuickPickItem {
21+
export interface IGotoSymbolQuickPickItem extends IQuickPickItem {
2222
kind: SymbolKind,
2323
index: number,
2424
score?: FuzzyScore;
@@ -90,7 +90,7 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit
9090
return disposables;
9191
}
9292

93-
private async waitForLanguageSymbolRegistry(model: ITextModel, disposables: DisposableStore): Promise<boolean> {
93+
protected async waitForLanguageSymbolRegistry(model: ITextModel, disposables: DisposableStore): Promise<boolean> {
9494
if (DocumentSymbolProviderRegistry.has(model)) {
9595
return true;
9696
}
@@ -194,7 +194,7 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit
194194
return disposables;
195195
}
196196

197-
private async doGetSymbolPicks(symbolsPromise: Promise<DocumentSymbol[]>, filter: string, token: CancellationToken): Promise<Array<IGotoSymbolQuickPickItem | IQuickPickSeparator>> {
197+
protected async doGetSymbolPicks(symbolsPromise: Promise<DocumentSymbol[]>, filter: string, token: CancellationToken): Promise<Array<IGotoSymbolQuickPickItem | IQuickPickSeparator>> {
198198
const symbols = await symbolsPromise;
199199
if (token.isCancellationRequested) {
200200
return [];
@@ -367,7 +367,7 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit
367367
return result;
368368
}
369369

370-
private async getDocumentSymbols(document: ITextModel, flatten: boolean, token: CancellationToken): Promise<DocumentSymbol[]> {
370+
protected async getDocumentSymbols(document: ITextModel, flatten: boolean, token: CancellationToken): Promise<DocumentSymbol[]> {
371371
const model = await OutlineModel.create(document, token);
372372
if (token.isCancellationRequested) {
373373
return [];
@@ -411,32 +411,6 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit
411411
}
412412
}
413413
}
414-
415-
416-
//#region public methods to use this picker from other pickers
417-
418-
async getSymbolPicks(model: ITextModel, filter: string, disposables: DisposableStore, token: CancellationToken): Promise<Array<IGotoSymbolQuickPickItem | IQuickPickSeparator>> {
419-
420-
// If the registry does not know the model, we wait for as long as
421-
// the registry knows it. This helps in cases where a language
422-
// registry was not activated yet for providing any symbols.
423-
const result = await this.waitForLanguageSymbolRegistry(model, disposables);
424-
if (!result || token.isCancellationRequested) {
425-
return [];
426-
}
427-
428-
return this.doGetSymbolPicks(this.getDocumentSymbols(model, true, token), filter, token);
429-
}
430-
431-
addDecorations(editor: IEditor, range: IRange): void {
432-
super.addDecorations(editor, range);
433-
}
434-
435-
clearDecorations(editor: IEditor): void {
436-
super.clearDecorations(editor);
437-
}
438-
439-
//#endregion
440414
}
441415

442416
// #region NLS Helpers

src/vs/workbench/contrib/codeEditor/browser/quickaccess/gotoSymbolQuickAccess.ts

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,19 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { localize } from 'vs/nls';
7-
import { IKeyMods } from 'vs/platform/quickinput/common/quickInput';
7+
import { IKeyMods, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput';
88
import { IEditor } from 'vs/editor/common/editorCommon';
99
import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
1010
import { IRange } from 'vs/editor/common/core/range';
1111
import { Registry } from 'vs/platform/registry/common/platform';
1212
import { IQuickAccessRegistry, Extensions } from 'vs/platform/quickinput/common/quickAccess';
13-
import { AbstractGotoSymbolQuickAccessProvider } from 'vs/editor/contrib/quickAccess/gotoSymbolQuickAccess';
13+
import { AbstractGotoSymbolQuickAccessProvider, IGotoSymbolQuickPickItem } from 'vs/editor/contrib/quickAccess/gotoSymbolQuickAccess';
1414
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
1515
import { IWorkbenchEditorConfiguration } from 'vs/workbench/common/editor';
16+
import { ITextModel } from 'vs/editor/common/model';
17+
import { DisposableStore } from 'vs/base/common/lifecycle';
18+
import { timeout } from 'vs/base/common/async';
19+
import { CancellationToken } from 'vs/base/common/cancellation';
1620

1721
export class GotoSymbolQuickAccessProvider extends AbstractGotoSymbolQuickAccessProvider {
1822

@@ -56,6 +60,39 @@ export class GotoSymbolQuickAccessProvider extends AbstractGotoSymbolQuickAccess
5660
super.gotoLocation(editor, options);
5761
}
5862
}
63+
64+
65+
//#region public methods to use this picker from other pickers
66+
67+
private static readonly SYMBOL_PICKS_TIMEOUT = 8000;
68+
69+
async getSymbolPicks(model: ITextModel, filter: string, disposables: DisposableStore, token: CancellationToken): Promise<Array<IGotoSymbolQuickPickItem | IQuickPickSeparator>> {
70+
71+
// If the registry does not know the model, we wait for as long as
72+
// the registry knows it. This helps in cases where a language
73+
// registry was not activated yet for providing any symbols.
74+
// To not wait forever, we eventually timeout though.
75+
const result = await Promise.race([
76+
this.waitForLanguageSymbolRegistry(model, disposables),
77+
timeout(GotoSymbolQuickAccessProvider.SYMBOL_PICKS_TIMEOUT)
78+
]);
79+
80+
if (!result || token.isCancellationRequested) {
81+
return [];
82+
}
83+
84+
return this.doGetSymbolPicks(this.getDocumentSymbols(model, true, token), filter, token);
85+
}
86+
87+
addDecorations(editor: IEditor, range: IRange): void {
88+
super.addDecorations(editor, range);
89+
}
90+
91+
clearDecorations(editor: IEditor): void {
92+
super.clearDecorations(editor);
93+
}
94+
95+
//#endregion
5996
}
6097

6198
Registry.as<IQuickAccessRegistry>(Extensions.Quickaccess).registerQuickAccessProvider({

src/vs/workbench/contrib/search/browser/anythingQuickAccess.ts

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
171171
// Add new decoration if editor symbol is active
172172
const [item] = picker.activeItems;
173173
if (isEditorSymbolQuickPickItem(item)) {
174-
editorDecorationsDisposable.value = this.decorateActiveEditorWithEditorSymbolRange(item);
174+
editorDecorationsDisposable.value = this.decorateAndRevealSymbolRange(item);
175175
}
176176
}));
177177

@@ -181,7 +181,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
181181
return disposables;
182182
}
183183

184-
private decorateActiveEditorWithEditorSymbolRange(pick: IEditorSymbolAnythingQuickPickItem): IDisposable {
184+
private decorateAndRevealSymbolRange(pick: IEditorSymbolAnythingQuickPickItem): IDisposable {
185185
const activeEditor = this.editorService.activeEditor;
186186
if (!isEqual(pick.resource, activeEditor?.resource)) {
187187
return Disposable.None; // active editor needs to be for resource
@@ -236,6 +236,10 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
236236
this.pickState.lastActiveGlobalPick = activePick;
237237
}
238238

239+
return this.doGetPicks(filter, disposables, token);
240+
}
241+
242+
private doGetPicks(filter: string, disposables: DisposableStore, token: CancellationToken): Promise<Array<IAnythingQuickPickItem | IQuickPickSeparator>> | FastAndSlowPicksType<IAnythingQuickPickItem> | null {
239243
const query = prepareQuery(filter);
240244

241245
// Return early if we have editor symbol picks. We support this by:
@@ -610,27 +614,35 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
610614

611615
private async doGetEditorSymbolPicks(activeGlobalPick: IAnythingQuickPickItem, activeGlobalResource: URI, filter: string, disposables: DisposableStore, token: CancellationToken): Promise<Array<IAnythingQuickPickItem | IQuickPickSeparator>> {
612616

613-
// Obtain model from resource
614-
let model = this.modelService.getModel(activeGlobalResource);
615-
if (!model) {
616-
const modelReference = disposables.add(await this.textModelService.createModelReference(activeGlobalResource));
617-
if (token.isCancellationRequested) {
618-
return [];
619-
}
620-
621-
model = modelReference.object.textEditorModel;
622-
}
623-
624617
// Bring the editor to front to review symbols to go to
625-
await this.editorService.openEditor({
626-
resource: activeGlobalResource,
627-
options: { preserveFocus: true, revealIfOpened: true }
628-
});
618+
try {
619+
await this.editorService.openEditor({
620+
resource: activeGlobalResource,
621+
options: { preserveFocus: true, revealIfOpened: true, ignoreError: true }
622+
});
623+
} catch (error) {
624+
return []; // return if resource cannot be opened
625+
}
629626

630627
if (token.isCancellationRequested) {
631628
return [];
632629
}
633630

631+
// Obtain model from resource
632+
let model = this.modelService.getModel(activeGlobalResource);
633+
if (!model) {
634+
try {
635+
const modelReference = disposables.add(await this.textModelService.createModelReference(activeGlobalResource));
636+
if (token.isCancellationRequested) {
637+
return [];
638+
}
639+
640+
model = modelReference.object.textEditorModel;
641+
} catch (error) {
642+
return []; // return if model cannot be resolved
643+
}
644+
}
645+
634646
// Ask provider for editor symbols
635647
const editorSymbolPicks = (await this.editorSymbolsQuickAccess.getSymbolPicks(model, filter, disposables, token));
636648
if (token.isCancellationRequested) {

0 commit comments

Comments
 (0)