mirror of
https://github.com/Microsoft/vscode
synced 2024-10-05 19:02:54 +00:00
quick access - allow a Promise<FastAndSlowPicks<T>>
and adopt for commands (#180664)
* quick access - allow a `Promise<FastAndSlowPicks<T>>` and adopt for commands * fix telemetry
This commit is contained in:
parent
25da7d524f
commit
3a69e153f6
|
@ -169,7 +169,7 @@ export class AzureActiveDirectoryService {
|
|||
"login" : {
|
||||
"owner": "TylerLeonhardt",
|
||||
"comment": "Used to determine the usage of the Microsoft Auth Provider.",
|
||||
"scopes": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight", "comment": "Used to determine what scope combinations are being requested." }
|
||||
"scopes": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight", "comment": "Used to determine what scope combinations are being requested." },
|
||||
"accountType": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight", "comment": "Used to determine what account types are being used." }
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -19,8 +19,8 @@ import { themeColorFromId } from 'vs/platform/theme/common/themeService';
|
|||
import { alert } from 'vs/base/browser/ui/aria/aria';
|
||||
|
||||
interface IEditorLineDecoration {
|
||||
rangeHighlightId: string;
|
||||
overviewRulerDecorationId: string;
|
||||
readonly rangeHighlightId: string;
|
||||
readonly overviewRulerDecorationId: string;
|
||||
}
|
||||
|
||||
export interface IEditorNavigationQuickAccessOptions {
|
||||
|
|
|
@ -37,10 +37,14 @@ export class StandaloneCommandsQuickAccessProvider extends AbstractEditorCommand
|
|||
super({ showAlias: false }, instantiationService, keybindingService, commandService, telemetryService, dialogService);
|
||||
}
|
||||
|
||||
protected getCommandPicks(): Array<ICommandQuickPick> {
|
||||
protected async getCommandPicks(): Promise<Array<ICommandQuickPick>> {
|
||||
return this.getCodeEditorCommandPicks();
|
||||
}
|
||||
|
||||
protected hasAdditionalCommandPicks(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected async getAdditionalCommandPicks(): Promise<ICommandQuickPick[]> {
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -24,12 +24,12 @@ import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storag
|
|||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
|
||||
export interface ICommandQuickPick extends IPickerQuickAccessItem {
|
||||
commandId: string;
|
||||
commandAlias?: string;
|
||||
readonly commandId: string;
|
||||
readonly commandAlias?: string;
|
||||
}
|
||||
|
||||
export interface ICommandsQuickAccessOptions extends IPickerQuickAccessProviderOptions<ICommandQuickPick> {
|
||||
showAlias: boolean;
|
||||
readonly showAlias: boolean;
|
||||
suggestedCommandIds?: Set<string>;
|
||||
}
|
||||
|
||||
|
@ -56,10 +56,10 @@ export abstract class AbstractCommandsQuickAccessProvider extends PickerQuickAcc
|
|||
this.options = options;
|
||||
}
|
||||
|
||||
protected _getPicks(filter: string, _disposables: DisposableStore, token: CancellationToken, runOptions?: IQuickAccessProviderRunOptions): Picks<ICommandQuickPick> | FastAndSlowPicks<ICommandQuickPick> {
|
||||
protected async _getPicks(filter: string, _disposables: DisposableStore, token: CancellationToken, runOptions?: IQuickAccessProviderRunOptions): Promise<Picks<ICommandQuickPick> | FastAndSlowPicks<ICommandQuickPick>> {
|
||||
|
||||
// Ask subclass for all command picks
|
||||
const allCommandPicks = this.getCommandPicks(token);
|
||||
const allCommandPicks = await this.getCommandPicks(token);
|
||||
|
||||
if (token.isCancellationRequested) {
|
||||
return [];
|
||||
|
@ -166,10 +166,20 @@ export abstract class AbstractCommandsQuickAccessProvider extends PickerQuickAcc
|
|||
commandPicks.push(this.toCommandPick(commandPick, runOptions));
|
||||
}
|
||||
|
||||
if (!this.hasAdditionalCommandPicks(filter, token)) {
|
||||
return commandPicks;
|
||||
}
|
||||
|
||||
return {
|
||||
picks: commandPicks,
|
||||
additionalPicks: this.getAdditionalCommandPicks(allCommandPicks, filteredCommandPicks, filter, token)
|
||||
.then(additionalCommandPicks => additionalCommandPicks.map(commandPick => this.toCommandPick(commandPick, runOptions)))
|
||||
additionalPicks: (async (): Promise<Picks<ICommandQuickPick>> => {
|
||||
const additionalCommandPicks = await this.getAdditionalCommandPicks(allCommandPicks, filteredCommandPicks, filter, token);
|
||||
if (token.isCancellationRequested) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return additionalCommandPicks.map(commandPick => this.toCommandPick(commandPick, runOptions));
|
||||
})()
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -177,6 +187,7 @@ export abstract class AbstractCommandsQuickAccessProvider extends PickerQuickAcc
|
|||
if (commandPick.type === 'separator') {
|
||||
return commandPick;
|
||||
}
|
||||
|
||||
const keybinding = this.keybindingService.lookupKeybinding(commandPick.commandId);
|
||||
const ariaLabel = keybinding ?
|
||||
localize('commandPickAriaLabelWithKeybinding', "{0}, {1}", commandPick.label, keybinding.getAriaLabel()) :
|
||||
|
@ -210,27 +221,22 @@ export abstract class AbstractCommandsQuickAccessProvider extends PickerQuickAcc
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses to provide the actual command entries.
|
||||
*/
|
||||
protected abstract getCommandPicks(token: CancellationToken): Array<ICommandQuickPick>;
|
||||
protected abstract getCommandPicks(token: CancellationToken): Promise<Array<ICommandQuickPick>>;
|
||||
|
||||
/**
|
||||
* Subclasses to provide the actual command entries.
|
||||
*/
|
||||
protected abstract hasAdditionalCommandPicks(filter: string, token: CancellationToken): boolean;
|
||||
protected abstract getAdditionalCommandPicks(allPicks: ICommandQuickPick[], picksSoFar: ICommandQuickPick[], filter: string, token: CancellationToken): Promise<Array<ICommandQuickPick | IQuickPickSeparator>>;
|
||||
}
|
||||
|
||||
interface ISerializedCommandHistory {
|
||||
usesLRU?: boolean;
|
||||
entries: { key: string; value: number }[];
|
||||
readonly usesLRU?: boolean;
|
||||
readonly entries: { key: string; value: number }[];
|
||||
}
|
||||
|
||||
interface ICommandsQuickAccessConfiguration {
|
||||
workbench: {
|
||||
commandPalette: {
|
||||
history: number;
|
||||
preserveInput: boolean;
|
||||
readonly workbench: {
|
||||
readonly commandPalette: {
|
||||
readonly history: number;
|
||||
readonly preserveInput: boolean;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import { Extensions, IQuickAccessProvider, IQuickAccessProviderDescriptor, IQuic
|
|||
import { IQuickInputService, IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
|
||||
|
||||
interface IHelpQuickAccessPickItem extends IQuickPickItem {
|
||||
prefix: string;
|
||||
readonly prefix: string;
|
||||
}
|
||||
|
||||
export class HelpQuickAccessProvider implements IQuickAccessProvider {
|
||||
|
@ -75,4 +75,3 @@ export class HelpQuickAccessProvider implements IQuickAccessProvider {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -64,18 +64,37 @@ export interface IPickerQuickAccessProviderOptions<T extends IPickerQuickAccessI
|
|||
/**
|
||||
* Enables support for opening picks in the background via gesture.
|
||||
*/
|
||||
canAcceptInBackground?: boolean;
|
||||
readonly canAcceptInBackground?: boolean;
|
||||
|
||||
/**
|
||||
* Enables to show a pick entry when no results are returned from a search.
|
||||
*/
|
||||
noResultsPick?: T | ((filter: string) => T);
|
||||
readonly noResultsPick?: T | ((filter: string) => T);
|
||||
}
|
||||
|
||||
export type Pick<T> = T | IQuickPickSeparator;
|
||||
export type PicksWithActive<T> = { items: readonly Pick<T>[]; active?: T };
|
||||
export type Picks<T> = readonly Pick<T>[] | PicksWithActive<T>;
|
||||
export type FastAndSlowPicks<T> = { picks: Picks<T>; additionalPicks: Promise<Picks<T>> };
|
||||
export type FastAndSlowPicks<T> = {
|
||||
|
||||
/**
|
||||
* Picks that will show instantly or after a short delay
|
||||
* based on the `mergeDelay` property to reduce flicker.
|
||||
*/
|
||||
readonly picks: Picks<T>;
|
||||
|
||||
/**
|
||||
* Picks that will show after they have been resolved.
|
||||
*/
|
||||
readonly additionalPicks: Promise<Picks<T>>;
|
||||
|
||||
/**
|
||||
* A delay in milliseconds to wait before showing the
|
||||
* `picks` to give a chance to merge with `additionalPicks`
|
||||
* for reduced flicker.
|
||||
*/
|
||||
readonly mergeDelay?: number;
|
||||
};
|
||||
|
||||
function isPicksWithActive<T>(obj: unknown): obj is PicksWithActive<T> {
|
||||
const candidate = obj as PicksWithActive<T>;
|
||||
|
@ -91,8 +110,6 @@ function isFastAndSlowPicks<T>(obj: unknown): obj is FastAndSlowPicks<T> {
|
|||
|
||||
export abstract class PickerQuickAccessProvider<T extends IPickerQuickAccessItem> extends Disposable implements IQuickAccessProvider {
|
||||
|
||||
private static FAST_PICKS_RACE_DELAY = 200; // timeout before we accept fast results before slow results are present
|
||||
|
||||
constructor(private prefix: string, protected options?: IPickerQuickAccessProviderOptions<T>) {
|
||||
super();
|
||||
}
|
||||
|
@ -158,51 +175,50 @@ export abstract class PickerQuickAccessProvider<T extends IPickerQuickAccessItem
|
|||
return true;
|
||||
};
|
||||
|
||||
// No Picks
|
||||
if (providedPicks === null) {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
// Fast and Slow Picks
|
||||
else if (isFastAndSlowPicks(providedPicks)) {
|
||||
const applyFastAndSlowPicks = async (fastAndSlowPicks: FastAndSlowPicks<T>): Promise<void> => {
|
||||
let fastPicksApplied = false;
|
||||
let slowPicksApplied = false;
|
||||
|
||||
await Promise.all([
|
||||
|
||||
// Fast Picks: to reduce amount of flicker, we race against
|
||||
// the slow picks over 500ms and then set the fast picks.
|
||||
// If the slow picks are faster, we reduce the flicker by
|
||||
// only setting the items once.
|
||||
// Fast Picks: if `mergeDelay` is configured, in order to reduce
|
||||
// amount of flicker, we race against the slow picks over some delay
|
||||
// and then set the fast picks.
|
||||
// If the slow picks are faster, we reduce the flicker by only
|
||||
// setting the items once.
|
||||
|
||||
(async () => {
|
||||
await timeout(PickerQuickAccessProvider.FAST_PICKS_RACE_DELAY);
|
||||
if (picksToken.isCancellationRequested) {
|
||||
return;
|
||||
if (typeof fastAndSlowPicks.mergeDelay === 'number') {
|
||||
await timeout(fastAndSlowPicks.mergeDelay);
|
||||
if (picksToken.isCancellationRequested) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!slowPicksApplied) {
|
||||
fastPicksApplied = applyPicks(providedPicks.picks, true /* skip over empty to reduce flicker */);
|
||||
fastPicksApplied = applyPicks(fastAndSlowPicks.picks, true /* skip over empty to reduce flicker */);
|
||||
}
|
||||
})(),
|
||||
|
||||
// Slow Picks: we await the slow picks and then set them at
|
||||
// once together with the fast picks, but only if we actually
|
||||
// have additional results.
|
||||
|
||||
(async () => {
|
||||
picker.busy = true;
|
||||
try {
|
||||
const awaitedAdditionalPicks = await providedPicks.additionalPicks;
|
||||
const awaitedAdditionalPicks = await fastAndSlowPicks.additionalPicks;
|
||||
if (picksToken.isCancellationRequested) {
|
||||
return;
|
||||
}
|
||||
|
||||
let picks: readonly Pick<T>[];
|
||||
let activePick: Pick<T> | undefined = undefined;
|
||||
if (isPicksWithActive(providedPicks.picks)) {
|
||||
picks = providedPicks.picks.items;
|
||||
activePick = providedPicks.picks.active;
|
||||
if (isPicksWithActive(fastAndSlowPicks.picks)) {
|
||||
picks = fastAndSlowPicks.picks.items;
|
||||
activePick = fastAndSlowPicks.picks.active;
|
||||
} else {
|
||||
picks = providedPicks.picks;
|
||||
picks = fastAndSlowPicks.picks;
|
||||
}
|
||||
|
||||
let additionalPicks: readonly Pick<T>[];
|
||||
|
@ -243,6 +259,16 @@ export abstract class PickerQuickAccessProvider<T extends IPickerQuickAccessItem
|
|||
}
|
||||
})()
|
||||
]);
|
||||
};
|
||||
|
||||
// No Picks
|
||||
if (providedPicks === null) {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
// Fast and Slow Picks
|
||||
else if (isFastAndSlowPicks(providedPicks)) {
|
||||
await applyFastAndSlowPicks(providedPicks);
|
||||
}
|
||||
|
||||
// Fast Picks
|
||||
|
@ -259,7 +285,11 @@ export abstract class PickerQuickAccessProvider<T extends IPickerQuickAccessItem
|
|||
return;
|
||||
}
|
||||
|
||||
applyPicks(awaitedPicks);
|
||||
if (isFastAndSlowPicks(awaitedPicks)) {
|
||||
await applyFastAndSlowPicks(awaitedPicks);
|
||||
} else {
|
||||
applyPicks(awaitedPicks);
|
||||
}
|
||||
} finally {
|
||||
if (!picksToken.isCancellationRequested) {
|
||||
picker.busy = false;
|
||||
|
@ -343,5 +373,5 @@ export abstract class PickerQuickAccessProvider<T extends IPickerQuickAccessItem
|
|||
* @returns the picks either directly, as promise or combined fast and slow results.
|
||||
* Pickers can return `null` to signal that no change in picks is needed.
|
||||
*/
|
||||
protected abstract _getPicks(filter: string, disposables: DisposableStore, token: CancellationToken, runOptions?: IQuickAccessProviderRunOptions): Picks<T> | Promise<Picks<T>> | FastAndSlowPicks<T> | null;
|
||||
protected abstract _getPicks(filter: string, disposables: DisposableStore, token: CancellationToken, runOptions?: IQuickAccessProviderRunOptions): Picks<T> | Promise<Picks<T> | FastAndSlowPicks<T>> | FastAndSlowPicks<T> | null;
|
||||
}
|
||||
|
|
|
@ -20,9 +20,9 @@ export class QuickAccessController extends Disposable implements IQuickAccessCon
|
|||
private readonly lastAcceptedPickerValues = new Map<IQuickAccessProviderDescriptor, string>();
|
||||
|
||||
private visibleQuickAccess: {
|
||||
picker: IQuickPick<IQuickPickItem>;
|
||||
descriptor: IQuickAccessProviderDescriptor | undefined;
|
||||
value: string;
|
||||
readonly picker: IQuickPick<IQuickPickItem>;
|
||||
readonly descriptor: IQuickAccessProviderDescriptor | undefined;
|
||||
readonly value: string;
|
||||
} | undefined = undefined;
|
||||
|
||||
constructor(
|
||||
|
|
|
@ -14,14 +14,14 @@ import { Registry } from 'vs/platform/registry/common/platform';
|
|||
* quick access.
|
||||
*/
|
||||
export interface IQuickAccessProviderRunOptions {
|
||||
from?: string;
|
||||
readonly from?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* The specific options for the AnythingQuickAccessProvider. Put here to share between layers.
|
||||
*/
|
||||
export interface AnythingQuickAccessProviderRunOptions extends IQuickAccessProviderRunOptions {
|
||||
includeHelp?: boolean;
|
||||
readonly includeHelp?: boolean;
|
||||
}
|
||||
|
||||
export interface IQuickAccessOptions {
|
||||
|
@ -29,25 +29,25 @@ export interface IQuickAccessOptions {
|
|||
/**
|
||||
* Allows to enable quick navigate support in quick input.
|
||||
*/
|
||||
quickNavigateConfiguration?: IQuickNavigateConfiguration;
|
||||
readonly quickNavigateConfiguration?: IQuickNavigateConfiguration;
|
||||
|
||||
/**
|
||||
* Allows to configure a different item activation strategy.
|
||||
* By default the first item in the list will get activated.
|
||||
*/
|
||||
itemActivation?: ItemActivation;
|
||||
readonly itemActivation?: ItemActivation;
|
||||
|
||||
/**
|
||||
* Whether to take the input value as is and not restore it
|
||||
* from any existing value if quick access is visible.
|
||||
*/
|
||||
preserveValue?: boolean;
|
||||
readonly preserveValue?: boolean;
|
||||
|
||||
/**
|
||||
* Provider specific options for this particular showing of the
|
||||
* quick access.
|
||||
*/
|
||||
providerOptions?: IQuickAccessProviderRunOptions;
|
||||
readonly providerOptions?: IQuickAccessProviderRunOptions;
|
||||
}
|
||||
|
||||
export interface IQuickAccessController {
|
||||
|
@ -114,12 +114,12 @@ export interface IQuickAccessProviderHelp {
|
|||
* The prefix to show for the help entry. If not provided,
|
||||
* the prefix used for registration will be taken.
|
||||
*/
|
||||
prefix?: string;
|
||||
readonly prefix?: string;
|
||||
|
||||
/**
|
||||
* A description text to help understand the intent of the provider.
|
||||
*/
|
||||
description: string;
|
||||
readonly description: string;
|
||||
|
||||
/**
|
||||
* The command to bring up this quick access provider.
|
||||
|
@ -181,6 +181,7 @@ export interface IQuickAccessRegistry {
|
|||
}
|
||||
|
||||
export class QuickAccessRegistry implements IQuickAccessRegistry {
|
||||
|
||||
private providers: IQuickAccessProviderDescriptor[] = [];
|
||||
private defaultProvider: IQuickAccessProviderDescriptor | undefined = undefined;
|
||||
|
||||
|
|
|
@ -17,18 +17,18 @@ export const defaultQuickAccessContextKeyValue = 'inFilesPicker';
|
|||
export const defaultQuickAccessContext = ContextKeyExpr.and(inQuickPickContext, ContextKeyExpr.has(defaultQuickAccessContextKeyValue));
|
||||
|
||||
export interface IWorkbenchQuickAccessConfiguration {
|
||||
workbench: {
|
||||
commandPalette: {
|
||||
history: number;
|
||||
preserveInput: boolean;
|
||||
experimental: {
|
||||
suggestCommands: boolean;
|
||||
useSemanticSimilarity: boolean;
|
||||
readonly workbench: {
|
||||
readonly commandPalette: {
|
||||
readonly history: number;
|
||||
readonly preserveInput: boolean;
|
||||
readonly experimental: {
|
||||
readonly suggestCommands: boolean;
|
||||
readonly useSemanticSimilarity: boolean;
|
||||
};
|
||||
};
|
||||
quickOpen: {
|
||||
enableExperimentalNewVersion: boolean;
|
||||
preserveInput: boolean;
|
||||
readonly quickOpen: {
|
||||
readonly enableExperimentalNewVersion: boolean;
|
||||
readonly preserveInput: boolean;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -7,9 +7,9 @@ import { localize } from 'vs/nls';
|
|||
import { ICommandQuickPick, CommandsHistory } from 'vs/platform/quickinput/browser/commandsQuickAccess';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IMenuService, MenuId, MenuItemAction, SubmenuItemAction, Action2 } from 'vs/platform/actions/common/actions';
|
||||
// import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
// import { timeout } from 'vs/base/common/async';
|
||||
import { raceTimeout, timeout } from 'vs/base/common/async';
|
||||
import { AbstractEditorCommandsQuickAccessProvider } from 'vs/editor/contrib/quickAccess/browser/commandsQuickAccess';
|
||||
import { IEditor } from 'vs/editor/common/editorCommon';
|
||||
import { Language } from 'vs/base/common/platform';
|
||||
|
@ -34,25 +34,21 @@ import { stripIcons } from 'vs/base/common/iconLabels';
|
|||
import { isFirefox } from 'vs/base/browser/browser';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { ISemanticSimilarityService } from 'vs/workbench/services/semanticSimilarity/common/semanticSimilarityService';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
import { IInteractiveSessionService } from 'vs/workbench/contrib/interactiveSession/common/interactiveSessionService';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IInteractiveSessionWidgetService } from 'vs/workbench/contrib/interactiveSession/browser/interactiveSessionWidget';
|
||||
|
||||
export class CommandsQuickAccessProvider extends AbstractEditorCommandsQuickAccessProvider {
|
||||
|
||||
private static SEMANTIC_SIMILARITY_MAX_PICKS = 3;
|
||||
private static SEMANTIC_SIMILARITY_THRESHOLD = 0.8;
|
||||
private static SEMANTIC_SIMILARITY_DEBOUNCE = 200;
|
||||
|
||||
// TODO: bring this back once we have a chosen strategy for FastAndSlowPicks where Fast is also Promise based
|
||||
// If extensions are not yet registered, we wait for a little moment to give them
|
||||
// a chance to register so that the complete set of commands shows up as result
|
||||
// We do not want to delay functionality beyond that time though to keep the commands
|
||||
// functional.
|
||||
// private readonly extensionRegistrationRace = Promise.race([
|
||||
// timeout(800),
|
||||
// this.extensionService.whenInstalledExtensionsRegistered()
|
||||
// ]);
|
||||
private readonly extensionRegistrationRace = raceTimeout(this.extensionService.whenInstalledExtensionsRegistered(), 800);
|
||||
|
||||
private useSemanticSimilarity = false;
|
||||
|
||||
|
@ -69,7 +65,7 @@ export class CommandsQuickAccessProvider extends AbstractEditorCommandsQuickAcce
|
|||
constructor(
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IMenuService private readonly menuService: IMenuService,
|
||||
// @IExtensionService private readonly extensionService: IExtensionService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IKeybindingService keybindingService: IKeybindingService,
|
||||
@ICommandService commandService: ICommandService,
|
||||
|
@ -125,11 +121,10 @@ export class CommandsQuickAccessProvider extends AbstractEditorCommandsQuickAcce
|
|||
this.useSemanticSimilarity = config.experimental.useSemanticSimilarity;
|
||||
}
|
||||
|
||||
protected getCommandPicks(token: CancellationToken): Array<ICommandQuickPick> {
|
||||
protected async getCommandPicks(token: CancellationToken): Promise<Array<ICommandQuickPick>> {
|
||||
|
||||
// TODO: bring this back once we have a chosen strategy for FastAndSlowPicks where Fast is also Promise based
|
||||
// wait for extensions registration or 800ms once
|
||||
// await this.extensionRegistrationRace;
|
||||
await this.extensionRegistrationRace;
|
||||
|
||||
if (token.isCancellationRequested) {
|
||||
return [];
|
||||
|
@ -138,23 +133,32 @@ export class CommandsQuickAccessProvider extends AbstractEditorCommandsQuickAcce
|
|||
return [
|
||||
...this.getCodeEditorCommandPicks(),
|
||||
...this.getGlobalCommandPicks()
|
||||
].map(c => ({
|
||||
...c,
|
||||
].map(picks => ({
|
||||
...picks,
|
||||
buttons: [{
|
||||
iconClass: ThemeIcon.asClassName(Codicon.gear),
|
||||
tooltip: localize('configure keybinding', "Configure Keybinding"),
|
||||
}],
|
||||
trigger: (): TriggerAction => {
|
||||
this.preferencesService.openGlobalKeybindingSettings(false, { query: `@command:${c.commandId}` });
|
||||
this.preferencesService.openGlobalKeybindingSettings(false, { query: `@command:${picks.commandId}` });
|
||||
return TriggerAction.CLOSE_PICKER;
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
||||
protected async getAdditionalCommandPicks(allPicks: ICommandQuickPick[], picksSoFar: ICommandQuickPick[], filter: string, token: CancellationToken): Promise<Array<ICommandQuickPick | IQuickPickSeparator>> {
|
||||
protected hasAdditionalCommandPicks(filter: string, token: CancellationToken): boolean {
|
||||
if (!this.useSemanticSimilarity || filter === '' || token.isCancellationRequested || !this.semanticSimilarityService.isEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected async getAdditionalCommandPicks(allPicks: ICommandQuickPick[], picksSoFar: ICommandQuickPick[], filter: string, token: CancellationToken): Promise<Array<ICommandQuickPick | IQuickPickSeparator>> {
|
||||
if (!this.hasAdditionalCommandPicks(filter, token)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const format = allPicks.map(p => p.commandId);
|
||||
let scores: number[];
|
||||
try {
|
||||
|
@ -164,6 +168,11 @@ export class CommandsQuickAccessProvider extends AbstractEditorCommandsQuickAcce
|
|||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (token.isCancellationRequested) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const sortedIndices = scores.map((_, i) => i).sort((a, b) => scores[b] - scores[a]);
|
||||
const setOfPicksSoFar = new Set(picksSoFar.map(p => p.commandId));
|
||||
const additionalPicks: Array<ICommandQuickPick | IQuickPickSeparator> = picksSoFar.length > 0
|
||||
|
@ -179,12 +188,14 @@ export class CommandsQuickAccessProvider extends AbstractEditorCommandsQuickAcce
|
|||
if (score < CommandsQuickAccessProvider.SEMANTIC_SIMILARITY_THRESHOLD || numOfSmartPicks === CommandsQuickAccessProvider.SEMANTIC_SIMILARITY_MAX_PICKS) {
|
||||
break;
|
||||
}
|
||||
|
||||
const pick = allPicks[i];
|
||||
if (!setOfPicksSoFar.has(pick.commandId)) {
|
||||
additionalPicks.push(pick);
|
||||
numOfSmartPicks++;
|
||||
}
|
||||
}
|
||||
|
||||
return additionalPicks;
|
||||
}
|
||||
|
||||
|
|
|
@ -84,6 +84,8 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
|
|||
|
||||
private static readonly TYPING_SEARCH_DELAY = 200; // this delay accommodates for the user typing a word and then stops typing to start searching
|
||||
|
||||
private static SYMBOL_PICKS_MERGE_DELAY = 200; // allow some time to merge fast and slow picks to reduce flickering
|
||||
|
||||
private readonly pickState = new class {
|
||||
|
||||
picker: IQuickPick<IAnythingQuickPickItem> | undefined = undefined;
|
||||
|
@ -394,7 +396,10 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
|
|||
{ type: 'separator', label: this.configuration.includeSymbols ? localize('fileAndSymbolResultsSeparator', "file and symbol results") : localize('fileResultsSeparator', "file results") },
|
||||
...additionalPicks
|
||||
] : [];
|
||||
})()
|
||||
})(),
|
||||
|
||||
// allow some time to merge files and symbols to reduce flickering
|
||||
mergeDelay: AnythingQuickAccessProvider.SYMBOL_PICKS_MERGE_DELAY
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue