提交 3c18886a 编写于 作者: B Benjamin Pasero

quick access - some cleanup in symbols support

上级 d9d90a0d
...@@ -18,7 +18,7 @@ import { trim, format } from 'vs/base/common/strings'; ...@@ -18,7 +18,7 @@ import { trim, format } from 'vs/base/common/strings';
import { fuzzyScore, FuzzyScore, createMatches } from 'vs/base/common/filters'; import { fuzzyScore, FuzzyScore, createMatches } from 'vs/base/common/filters';
import { assign } from 'vs/base/common/objects'; import { assign } from 'vs/base/common/objects';
interface IGotoSymbolQuickPickItem extends IQuickPickItem { export interface IGotoSymbolQuickPickItem extends IQuickPickItem {
kind: SymbolKind, kind: SymbolKind,
index: number, index: number,
score?: FuzzyScore; score?: FuzzyScore;
...@@ -90,7 +90,7 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit ...@@ -90,7 +90,7 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit
return disposables; return disposables;
} }
private async waitForLanguageSymbolRegistry(model: ITextModel, disposables: DisposableStore): Promise<boolean> { protected async waitForLanguageSymbolRegistry(model: ITextModel, disposables: DisposableStore): Promise<boolean> {
if (DocumentSymbolProviderRegistry.has(model)) { if (DocumentSymbolProviderRegistry.has(model)) {
return true; return true;
} }
...@@ -194,7 +194,7 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit ...@@ -194,7 +194,7 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit
return disposables; return disposables;
} }
private async doGetSymbolPicks(symbolsPromise: Promise<DocumentSymbol[]>, filter: string, token: CancellationToken): Promise<Array<IGotoSymbolQuickPickItem | IQuickPickSeparator>> { protected async doGetSymbolPicks(symbolsPromise: Promise<DocumentSymbol[]>, filter: string, token: CancellationToken): Promise<Array<IGotoSymbolQuickPickItem | IQuickPickSeparator>> {
const symbols = await symbolsPromise; const symbols = await symbolsPromise;
if (token.isCancellationRequested) { if (token.isCancellationRequested) {
return []; return [];
...@@ -367,7 +367,7 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit ...@@ -367,7 +367,7 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit
return result; return result;
} }
private async getDocumentSymbols(document: ITextModel, flatten: boolean, token: CancellationToken): Promise<DocumentSymbol[]> { protected async getDocumentSymbols(document: ITextModel, flatten: boolean, token: CancellationToken): Promise<DocumentSymbol[]> {
const model = await OutlineModel.create(document, token); const model = await OutlineModel.create(document, token);
if (token.isCancellationRequested) { if (token.isCancellationRequested) {
return []; return [];
...@@ -411,32 +411,6 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit ...@@ -411,32 +411,6 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit
} }
} }
} }
//#region public methods to use this picker from other pickers
async getSymbolPicks(model: ITextModel, filter: string, disposables: DisposableStore, token: CancellationToken): Promise<Array<IGotoSymbolQuickPickItem | IQuickPickSeparator>> {
// If the registry does not know the model, we wait for as long as
// the registry knows it. This helps in cases where a language
// registry was not activated yet for providing any symbols.
const result = await this.waitForLanguageSymbolRegistry(model, disposables);
if (!result || token.isCancellationRequested) {
return [];
}
return this.doGetSymbolPicks(this.getDocumentSymbols(model, true, token), filter, token);
}
addDecorations(editor: IEditor, range: IRange): void {
super.addDecorations(editor, range);
}
clearDecorations(editor: IEditor): void {
super.clearDecorations(editor);
}
//#endregion
} }
// #region NLS Helpers // #region NLS Helpers
......
...@@ -4,15 +4,19 @@ ...@@ -4,15 +4,19 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
import { IKeyMods } from 'vs/platform/quickinput/common/quickInput'; import { IKeyMods, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput';
import { IEditor } from 'vs/editor/common/editorCommon'; import { IEditor } from 'vs/editor/common/editorCommon';
import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import { IRange } from 'vs/editor/common/core/range'; import { IRange } from 'vs/editor/common/core/range';
import { Registry } from 'vs/platform/registry/common/platform'; import { Registry } from 'vs/platform/registry/common/platform';
import { IQuickAccessRegistry, Extensions } from 'vs/platform/quickinput/common/quickAccess'; import { IQuickAccessRegistry, Extensions } from 'vs/platform/quickinput/common/quickAccess';
import { AbstractGotoSymbolQuickAccessProvider } from 'vs/editor/contrib/quickAccess/gotoSymbolQuickAccess'; import { AbstractGotoSymbolQuickAccessProvider, IGotoSymbolQuickPickItem } from 'vs/editor/contrib/quickAccess/gotoSymbolQuickAccess';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IWorkbenchEditorConfiguration } from 'vs/workbench/common/editor'; import { IWorkbenchEditorConfiguration } from 'vs/workbench/common/editor';
import { ITextModel } from 'vs/editor/common/model';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { timeout } from 'vs/base/common/async';
import { CancellationToken } from 'vs/base/common/cancellation';
export class GotoSymbolQuickAccessProvider extends AbstractGotoSymbolQuickAccessProvider { export class GotoSymbolQuickAccessProvider extends AbstractGotoSymbolQuickAccessProvider {
...@@ -56,6 +60,39 @@ export class GotoSymbolQuickAccessProvider extends AbstractGotoSymbolQuickAccess ...@@ -56,6 +60,39 @@ export class GotoSymbolQuickAccessProvider extends AbstractGotoSymbolQuickAccess
super.gotoLocation(editor, options); super.gotoLocation(editor, options);
} }
} }
//#region public methods to use this picker from other pickers
private static readonly SYMBOL_PICKS_TIMEOUT = 8000;
async getSymbolPicks(model: ITextModel, filter: string, disposables: DisposableStore, token: CancellationToken): Promise<Array<IGotoSymbolQuickPickItem | IQuickPickSeparator>> {
// If the registry does not know the model, we wait for as long as
// the registry knows it. This helps in cases where a language
// registry was not activated yet for providing any symbols.
// To not wait forever, we eventually timeout though.
const result = await Promise.race([
this.waitForLanguageSymbolRegistry(model, disposables),
timeout(GotoSymbolQuickAccessProvider.SYMBOL_PICKS_TIMEOUT)
]);
if (!result || token.isCancellationRequested) {
return [];
}
return this.doGetSymbolPicks(this.getDocumentSymbols(model, true, token), filter, token);
}
addDecorations(editor: IEditor, range: IRange): void {
super.addDecorations(editor, range);
}
clearDecorations(editor: IEditor): void {
super.clearDecorations(editor);
}
//#endregion
} }
Registry.as<IQuickAccessRegistry>(Extensions.Quickaccess).registerQuickAccessProvider({ Registry.as<IQuickAccessRegistry>(Extensions.Quickaccess).registerQuickAccessProvider({
......
...@@ -171,7 +171,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt ...@@ -171,7 +171,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
// Add new decoration if editor symbol is active // Add new decoration if editor symbol is active
const [item] = picker.activeItems; const [item] = picker.activeItems;
if (isEditorSymbolQuickPickItem(item)) { if (isEditorSymbolQuickPickItem(item)) {
editorDecorationsDisposable.value = this.decorateActiveEditorWithEditorSymbolRange(item); editorDecorationsDisposable.value = this.decorateAndRevealSymbolRange(item);
} }
})); }));
...@@ -181,7 +181,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt ...@@ -181,7 +181,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
return disposables; return disposables;
} }
private decorateActiveEditorWithEditorSymbolRange(pick: IEditorSymbolAnythingQuickPickItem): IDisposable { private decorateAndRevealSymbolRange(pick: IEditorSymbolAnythingQuickPickItem): IDisposable {
const activeEditor = this.editorService.activeEditor; const activeEditor = this.editorService.activeEditor;
if (!isEqual(pick.resource, activeEditor?.resource)) { if (!isEqual(pick.resource, activeEditor?.resource)) {
return Disposable.None; // active editor needs to be for resource return Disposable.None; // active editor needs to be for resource
...@@ -236,6 +236,10 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt ...@@ -236,6 +236,10 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
this.pickState.lastActiveGlobalPick = activePick; this.pickState.lastActiveGlobalPick = activePick;
} }
return this.doGetPicks(filter, disposables, token);
}
private doGetPicks(filter: string, disposables: DisposableStore, token: CancellationToken): Promise<Array<IAnythingQuickPickItem | IQuickPickSeparator>> | FastAndSlowPicksType<IAnythingQuickPickItem> | null {
const query = prepareQuery(filter); const query = prepareQuery(filter);
// Return early if we have editor symbol picks. We support this by: // Return early if we have editor symbol picks. We support this by:
...@@ -610,25 +614,33 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt ...@@ -610,25 +614,33 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
private async doGetEditorSymbolPicks(activeGlobalPick: IAnythingQuickPickItem, activeGlobalResource: URI, filter: string, disposables: DisposableStore, token: CancellationToken): Promise<Array<IAnythingQuickPickItem | IQuickPickSeparator>> { private async doGetEditorSymbolPicks(activeGlobalPick: IAnythingQuickPickItem, activeGlobalResource: URI, filter: string, disposables: DisposableStore, token: CancellationToken): Promise<Array<IAnythingQuickPickItem | IQuickPickSeparator>> {
// Bring the editor to front to review symbols to go to
try {
await this.editorService.openEditor({
resource: activeGlobalResource,
options: { preserveFocus: true, revealIfOpened: true, ignoreError: true }
});
} catch (error) {
return []; // return if resource cannot be opened
}
if (token.isCancellationRequested) {
return [];
}
// Obtain model from resource // Obtain model from resource
let model = this.modelService.getModel(activeGlobalResource); let model = this.modelService.getModel(activeGlobalResource);
if (!model) { if (!model) {
try {
const modelReference = disposables.add(await this.textModelService.createModelReference(activeGlobalResource)); const modelReference = disposables.add(await this.textModelService.createModelReference(activeGlobalResource));
if (token.isCancellationRequested) { if (token.isCancellationRequested) {
return []; return [];
} }
model = modelReference.object.textEditorModel; model = modelReference.object.textEditorModel;
} catch (error) {
return []; // return if model cannot be resolved
} }
// Bring the editor to front to review symbols to go to
await this.editorService.openEditor({
resource: activeGlobalResource,
options: { preserveFocus: true, revealIfOpened: true }
});
if (token.isCancellationRequested) {
return [];
} }
// Ask provider for editor symbols // Ask provider for editor symbols
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册