in patched-vscode/src/vs/platform/quickinput/browser/commandsQuickAccess.ts [69:246]
protected async _getPicks(filter: string, _disposables: DisposableStore, token: CancellationToken, runOptions?: IQuickAccessProviderRunOptions): Promise<Picks<ICommandQuickPick> | FastAndSlowPicks<ICommandQuickPick>> {
// Ask subclass for all command picks
const allCommandPicks = await this.getCommandPicks(token);
if (token.isCancellationRequested) {
return [];
}
const runTfidf = createSingleCallFunction(() => {
const tfidf = new TfIdfCalculator();
tfidf.updateDocuments(allCommandPicks.map(commandPick => ({
key: commandPick.commandId,
textChunks: [this.getTfIdfChunk(commandPick)]
})));
const result = tfidf.calculateScores(filter, token);
return normalizeTfIdfScores(result)
.filter(score => score.score > AbstractCommandsQuickAccessProvider.TFIDF_THRESHOLD)
.slice(0, AbstractCommandsQuickAccessProvider.TFIDF_MAX_RESULTS);
});
// Filter
const filteredCommandPicks: ICommandQuickPick[] = [];
for (const commandPick of allCommandPicks) {
const labelHighlights = AbstractCommandsQuickAccessProvider.WORD_FILTER(filter, commandPick.label) ?? undefined;
const aliasHighlights = commandPick.commandAlias ? AbstractCommandsQuickAccessProvider.WORD_FILTER(filter, commandPick.commandAlias) ?? undefined : undefined;
// Add if matching in label or alias
if (labelHighlights || aliasHighlights) {
commandPick.highlights = {
label: labelHighlights,
detail: this.options.showAlias ? aliasHighlights : undefined
};
filteredCommandPicks.push(commandPick);
}
// Also add if we have a 100% command ID match
else if (filter === commandPick.commandId) {
filteredCommandPicks.push(commandPick);
}
// Handle tf-idf scoring for the rest if there's a filter
else if (filter.length >= 3) {
const tfidf = runTfidf();
if (token.isCancellationRequested) {
return [];
}
// Add if we have a tf-idf score
const tfidfScore = tfidf.find(score => score.key === commandPick.commandId);
if (tfidfScore) {
commandPick.tfIdfScore = tfidfScore.score;
filteredCommandPicks.push(commandPick);
}
}
}
// Add description to commands that have duplicate labels
const mapLabelToCommand = new Map<string, ICommandQuickPick>();
for (const commandPick of filteredCommandPicks) {
const existingCommandForLabel = mapLabelToCommand.get(commandPick.label);
if (existingCommandForLabel) {
commandPick.description = commandPick.commandId;
existingCommandForLabel.description = existingCommandForLabel.commandId;
} else {
mapLabelToCommand.set(commandPick.label, commandPick);
}
}
// Sort by MRU order and fallback to name otherwise
filteredCommandPicks.sort((commandPickA, commandPickB) => {
// If a result came from tf-idf, we want to put that towards the bottom
if (commandPickA.tfIdfScore && commandPickB.tfIdfScore) {
if (commandPickA.tfIdfScore === commandPickB.tfIdfScore) {
return commandPickA.label.localeCompare(commandPickB.label); // prefer lexicographically smaller command
}
return commandPickB.tfIdfScore - commandPickA.tfIdfScore; // prefer higher tf-idf score
} else if (commandPickA.tfIdfScore) {
return 1; // first command has a score but other doesn't so other wins
} else if (commandPickB.tfIdfScore) {
return -1; // other command has a score but first doesn't so first wins
}
const commandACounter = this.commandsHistory.peek(commandPickA.commandId);
const commandBCounter = this.commandsHistory.peek(commandPickB.commandId);
if (commandACounter && commandBCounter) {
return commandACounter > commandBCounter ? -1 : 1; // use more recently used command before older
}
if (commandACounter) {
return -1; // first command was used, so it wins over the non used one
}
if (commandBCounter) {
return 1; // other command was used so it wins over the command
}
if (this.options.suggestedCommandIds) {
const commandASuggestion = this.options.suggestedCommandIds.has(commandPickA.commandId);
const commandBSuggestion = this.options.suggestedCommandIds.has(commandPickB.commandId);
if (commandASuggestion && commandBSuggestion) {
return 0; // honor the order of the array
}
if (commandASuggestion) {
return -1; // first command was suggested, so it wins over the non suggested one
}
if (commandBSuggestion) {
return 1; // other command was suggested so it wins over the command
}
}
// both commands were never used, so we sort by name
return commandPickA.label.localeCompare(commandPickB.label);
});
const commandPicks: Array<ICommandQuickPick | IQuickPickSeparator> = [];
let addOtherSeparator = false;
let addSuggestedSeparator = true;
let addCommonlyUsedSeparator = !!this.options.suggestedCommandIds;
for (let i = 0; i < filteredCommandPicks.length; i++) {
const commandPick = filteredCommandPicks[i];
// Separator: recently used
if (i === 0 && this.commandsHistory.peek(commandPick.commandId)) {
commandPicks.push({ type: 'separator', label: localize('recentlyUsed', "recently used") });
addOtherSeparator = true;
}
if (addSuggestedSeparator && commandPick.tfIdfScore !== undefined) {
commandPicks.push({ type: 'separator', label: localize('suggested', "similar commands") });
addSuggestedSeparator = false;
}
// Separator: commonly used
if (addCommonlyUsedSeparator && commandPick.tfIdfScore === undefined && !this.commandsHistory.peek(commandPick.commandId) && this.options.suggestedCommandIds?.has(commandPick.commandId)) {
commandPicks.push({ type: 'separator', label: localize('commonlyUsed', "commonly used") });
addOtherSeparator = true;
addCommonlyUsedSeparator = false;
}
// Separator: other commands
if (addOtherSeparator && commandPick.tfIdfScore === undefined && !this.commandsHistory.peek(commandPick.commandId) && !this.options.suggestedCommandIds?.has(commandPick.commandId)) {
commandPicks.push({ type: 'separator', label: localize('morecCommands', "other commands") });
addOtherSeparator = false;
}
// Command
commandPicks.push(this.toCommandPick(commandPick, runOptions));
}
if (!this.hasAdditionalCommandPicks(filter, token)) {
return commandPicks;
}
return {
picks: commandPicks,
additionalPicks: (async (): Promise<Picks<ICommandQuickPick>> => {
const additionalCommandPicks = await this.getAdditionalCommandPicks(allCommandPicks, filteredCommandPicks, filter, token);
if (token.isCancellationRequested) {
return [];
}
const commandPicks: Array<ICommandQuickPick | IQuickPickSeparator> = additionalCommandPicks.map(commandPick => this.toCommandPick(commandPick, runOptions));
// Basically, if we haven't already added a separator, we add one before the additional picks so long
// as one hasn't been added to the start of the array.
if (addSuggestedSeparator && commandPicks[0]?.type !== 'separator') {
commandPicks.unshift({ type: 'separator', label: localize('suggested', "similar commands") });
}
return commandPicks;
})()
};
}