提交 08f0fe2d 编写于 作者: B Benjamin Pasero

quick access - allow to return full pick state

上级 dda6a4cd
...@@ -64,8 +64,16 @@ export interface IPickerQuickAccessProviderOptions { ...@@ -64,8 +64,16 @@ export interface IPickerQuickAccessProviderOptions {
} }
export type Pick<T> = T | IQuickPickSeparator; export type Pick<T> = T | IQuickPickSeparator;
export type Picks<T> = Array<Pick<T>> | { items: Array<Pick<T>>, active?: T }; export type PicksWithActive<T> = { items: ReadonlyArray<Pick<T>>, active?: T };
export type Picks<T> = ReadonlyArray<Pick<T>> | PicksWithActive<T>;
export type FastAndSlowPicks<T> = { picks: Picks<T>, additionalPicks: Promise<Picks<T>> }; export type FastAndSlowPicks<T> = { picks: Picks<T>, additionalPicks: Promise<Picks<T>> };
export type FastAndSlowPicksWithActive<T> = { picks: PicksWithActive<T>, additionalPicks: PicksWithActive<Picks<T>> };
function isPicksWithActive<T>(obj: unknown): obj is PicksWithActive<T> {
const candidate = obj as PicksWithActive<T>;
return Array.isArray(candidate.items);
}
function isFastAndSlowPicks<T>(obj: unknown): obj is FastAndSlowPicks<T> { function isFastAndSlowPicks<T>(obj: unknown): obj is FastAndSlowPicks<T> {
const candidate = obj as FastAndSlowPicks<T>; const candidate = obj as FastAndSlowPicks<T>;
...@@ -108,13 +116,13 @@ export abstract class PickerQuickAccessProvider<T extends IPickerQuickAccessItem ...@@ -108,13 +116,13 @@ export abstract class PickerQuickAccessProvider<T extends IPickerQuickAccessItem
const providedPicks = this.getPicks(picker.value.substr(this.prefix.length).trim(), picksDisposables, picksToken); const providedPicks = this.getPicks(picker.value.substr(this.prefix.length).trim(), picksDisposables, picksToken);
function applyPicks(picks: Picks<T>): void { function applyPicks(picks: Picks<T>): void {
if (Array.isArray(picks)) { if (isPicksWithActive(picks)) {
picker.items = picks;
} else {
picker.items = picks.items; picker.items = picks.items;
if (picks.active) { if (picks.active) {
picker.activeItems = [picks.active]; picker.activeItems = [picks.active];
} }
} else {
picker.items = picks;
} }
} }
...@@ -160,22 +168,22 @@ export abstract class PickerQuickAccessProvider<T extends IPickerQuickAccessItem ...@@ -160,22 +168,22 @@ export abstract class PickerQuickAccessProvider<T extends IPickerQuickAccessItem
return; return;
} }
let picks: Array<Pick<T>>; let picks: ReadonlyArray<Pick<T>>;
let activePick: Pick<T> | undefined = undefined; let activePick: Pick<T> | undefined = undefined;
if (Array.isArray(providedPicks.picks)) { if (isPicksWithActive(providedPicks.picks)) {
picks = providedPicks.picks;
} else {
picks = providedPicks.picks.items; picks = providedPicks.picks.items;
activePick = providedPicks.picks.active; activePick = providedPicks.picks.active;
} else {
picks = providedPicks.picks;
} }
let additionalPicks: Array<Pick<T>>; let additionalPicks: ReadonlyArray<Pick<T>>;
let additionalActivePick: Pick<T> | undefined = undefined; let additionalActivePick: Pick<T> | undefined = undefined;
if (Array.isArray(awaitedAdditionalPicks)) { if (isPicksWithActive(awaitedAdditionalPicks)) {
additionalPicks = awaitedAdditionalPicks;
} else {
additionalPicks = awaitedAdditionalPicks.items; additionalPicks = awaitedAdditionalPicks.items;
additionalActivePick = awaitedAdditionalPicks.active; additionalActivePick = awaitedAdditionalPicks.active;
} else {
additionalPicks = awaitedAdditionalPicks;
} }
if (additionalPicks.length > 0 || !fastPicksHandlerDone) { if (additionalPicks.length > 0 || !fastPicksHandlerDone) {
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
import 'vs/css!./media/anythingQuickAccess'; import 'vs/css!./media/anythingQuickAccess';
import { IQuickInputButton, IKeyMods, quickPickItemScorerAccessor, QuickPickItemScorerAccessor, IQuickPick } from 'vs/platform/quickinput/common/quickInput'; import { IQuickInputButton, IKeyMods, quickPickItemScorerAccessor, QuickPickItemScorerAccessor, IQuickPick } from 'vs/platform/quickinput/common/quickInput';
import { IPickerQuickAccessItem, PickerQuickAccessProvider, TriggerAction, FastAndSlowPicks, Picks } from 'vs/platform/quickinput/browser/pickerQuickAccess'; import { IPickerQuickAccessItem, PickerQuickAccessProvider, TriggerAction, FastAndSlowPicks, Picks, PicksWithActive } from 'vs/platform/quickinput/browser/pickerQuickAccess';
import { prepareQuery, IPreparedQuery, compareItemsByScore, scoreItem, ScorerCache } from 'vs/base/common/fuzzyScorer'; import { prepareQuery, IPreparedQuery, compareItemsByScore, scoreItem, ScorerCache } from 'vs/base/common/fuzzyScorer';
import { IFileQueryBuilderOptions, QueryBuilder } from 'vs/workbench/contrib/search/common/queryBuilder'; import { IFileQueryBuilderOptions, QueryBuilder } from 'vs/workbench/contrib/search/common/queryBuilder';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
...@@ -89,8 +89,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt ...@@ -89,8 +89,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
lastFilter: string | undefined = undefined; lastFilter: string | undefined = undefined;
lastRange: IRange | undefined = undefined; lastRange: IRange | undefined = undefined;
lastActiveGlobalPick: IAnythingQuickPickItem | undefined = undefined; lastGlobalPicks: PicksWithActive<IAnythingQuickPickItem> | undefined = undefined;
lastActiveEditorSymbolPick: IAnythingQuickPickItem | undefined = undefined;
isQuickNavigating: boolean | undefined = undefined; isQuickNavigating: boolean | undefined = undefined;
...@@ -118,8 +117,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt ...@@ -118,8 +117,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
this.lastOriginalFilter = undefined; this.lastOriginalFilter = undefined;
this.lastFilter = undefined; this.lastFilter = undefined;
this.lastRange = undefined; this.lastRange = undefined;
this.lastActiveGlobalPick = undefined; this.lastGlobalPicks = undefined;
this.lastActiveEditorSymbolPick = undefined;
this.editorViewState = undefined; this.editorViewState = undefined;
} }
...@@ -243,7 +241,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt ...@@ -243,7 +241,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
return toDisposable(() => this.clearDecorations(activeEditorControl)); return toDisposable(() => this.clearDecorations(activeEditorControl));
} }
protected getPicks(originalFilter: string, disposables: DisposableStore, token: CancellationToken): Promise<Picks<IAnythingQuickPickItem>> | FastAndSlowPicks<IAnythingQuickPickItem> | null { protected getPicks(originalFilter: string, disposables: DisposableStore, token: CancellationToken): Picks<IAnythingQuickPickItem> | Promise<Picks<IAnythingQuickPickItem>> | FastAndSlowPicks<IAnythingQuickPickItem> | null {
// Find a suitable range from the pattern looking for ":", "#" or "," // Find a suitable range from the pattern looking for ":", "#" or ","
// unless we have the `@` editor symbol character inside the filter // unless we have the `@` editor symbol character inside the filter
...@@ -272,24 +270,25 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt ...@@ -272,24 +270,25 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
this.pickState.lastOriginalFilter = originalFilter; this.pickState.lastOriginalFilter = originalFilter;
this.pickState.lastFilter = filter; this.pickState.lastFilter = filter;
// Remember last active pick (global or editor symbol) // Remember our pick state before returning new picks
// unless an editor symbol is selected. We can use this
// state to return back to the global pick when the
// user is narrowing back out of editor symbols.
const picks = this.pickState.picker?.items;
const activePick = this.pickState.picker?.activeItems[0]; const activePick = this.pickState.picker?.activeItems[0];
if (activePick) { if (picks && activePick) {
if (isEditorSymbolQuickPickItem(activePick)) { if (!isEditorSymbolQuickPickItem(activePick)) {
// remember the editor symbol pick, but do not unset the this.pickState.lastGlobalPicks = {
// global pick as we can use it later to restore it when items: picks,
// the user narrows out of the editor symbol search active: activePick
this.pickState.lastActiveEditorSymbolPick = activePick; };
} else {
this.pickState.lastActiveGlobalPick = activePick;
this.pickState.lastActiveEditorSymbolPick = undefined;
} }
} }
return this.doGetPicks(filter, disposables, token); return this.doGetPicks(filter, disposables, token);
} }
private doGetPicks(filter: string, disposables: DisposableStore, token: CancellationToken): Promise<Picks<IAnythingQuickPickItem>> | FastAndSlowPicks<IAnythingQuickPickItem> | null { private doGetPicks(filter: string, disposables: DisposableStore, token: CancellationToken): Picks<IAnythingQuickPickItem> | Promise<Picks<IAnythingQuickPickItem>> | FastAndSlowPicks<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:
...@@ -303,9 +302,9 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt ...@@ -303,9 +302,9 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
// If we have a known last active editor symbol pick, we try to restore // If we have a known last active editor symbol pick, we try to restore
// the last global pick to support the case of narrowing out from a // the last global pick to support the case of narrowing out from a
// editor symbol search back into the global search // editor symbol search back into the global search
let activeGlobalPick: IAnythingQuickPickItem | undefined = undefined; const activePick = this.pickState.picker?.activeItems[0];
if (this.pickState.lastActiveEditorSymbolPick) { if (isEditorSymbolQuickPickItem(activePick) && this.pickState.lastGlobalPicks) {
activeGlobalPick = this.pickState.lastActiveGlobalPick; return this.pickState.lastGlobalPicks;
} }
// Otherwise return normally with history and file/symbol results // Otherwise return normally with history and file/symbol results
...@@ -314,15 +313,13 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt ...@@ -314,15 +313,13 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
return { return {
// Fast picks: editor history // Fast picks: editor history
picks: { picks:
items: (this.pickState.isQuickNavigating || historyEditorPicks.length === 0) ? (this.pickState.isQuickNavigating || historyEditorPicks.length === 0) ?
historyEditorPicks : historyEditorPicks :
[ [
{ type: 'separator', label: localize('recentlyOpenedSeparator', "recently opened") }, { type: 'separator', label: localize('recentlyOpenedSeparator', "recently opened") },
...historyEditorPicks ...historyEditorPicks
], ],
active: activeGlobalPick ? this.findPick(historyEditorPicks, activeGlobalPick) : undefined
},
// Slow picks: files and symbols // Slow picks: files and symbols
additionalPicks: (async (): Promise<Picks<IAnythingQuickPickItem>> => { additionalPicks: (async (): Promise<Picks<IAnythingQuickPickItem>> => {
...@@ -340,27 +337,14 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt ...@@ -340,27 +337,14 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
return []; return [];
} }
return { return additionalPicks.length > 0 ? [
items: additionalPicks.length > 0 ? [ { type: 'separator', label: this.configuration.includeSymbols ? localize('fileAndSymbolResultsSeparator', "file and symbol results") : localize('fileResultsSeparator', "file results") },
{ type: 'separator', label: this.configuration.includeSymbols ? localize('fileAndSymbolResultsSeparator', "file and symbol results") : localize('fileResultsSeparator', "file results") }, ...additionalPicks
...additionalPicks ] : [];
] : [],
active: activeGlobalPick ? this.findPick(additionalPicks, activeGlobalPick) : undefined
};
})() })()
}; };
} }
private findPick(picks: IAnythingQuickPickItem[], candidate: IAnythingQuickPickItem): IAnythingQuickPickItem | undefined {
for (const pick of picks) {
if (isEqual(pick.resource, candidate.resource)) {
return pick;
}
}
return undefined;
}
private async getAdditionalPicks(query: IPreparedQuery, excludes: ResourceMap<boolean>, token: CancellationToken): Promise<Array<IAnythingQuickPickItem>> { private async getAdditionalPicks(query: IPreparedQuery, excludes: ResourceMap<boolean>, token: CancellationToken): Promise<Array<IAnythingQuickPickItem>> {
// Resolve file and symbol picks (if enabled) // Resolve file and symbol picks (if enabled)
...@@ -676,7 +660,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt ...@@ -676,7 +660,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
return null; // we need to be searched for editor symbols via `@` return null; // we need to be searched for editor symbols via `@`
} }
const activeGlobalPick = this.pickState.lastActiveGlobalPick; const activeGlobalPick = this.pickState.lastGlobalPicks?.active;
if (!activeGlobalPick) { if (!activeGlobalPick) {
return null; // we need an active global pick to find symbols for return null; // we need an active global pick to find symbols for
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册