提交 c1c90f8e 编写于 作者: B Benjamin Pasero

quick access - allow to match on multiple inputs (fix #30404)

上级 fb11f140
......@@ -9,6 +9,7 @@ import { sep } from 'vs/base/common/path';
import { isWindows, isLinux } from 'vs/base/common/platform';
import { stripWildcards, equalsIgnoreCase } from 'vs/base/common/strings';
import { CharCode } from 'vs/base/common/charCode';
import { distinctES6 } from 'vs/base/common/arrays';
export type Score = [number /* score */, number[] /* match positions */];
export type ScorerCache = { [key: string]: IItemScore };
......@@ -19,7 +20,40 @@ const NO_SCORE: Score = [NO_MATCH, []];
// const DEBUG = false;
// const DEBUG_MATRIX = false;
export function score(target: string, query: string, queryLower: string, fuzzy: boolean): Score {
export function score(target: string, query: IPreparedQuery, fuzzy: boolean): Score {
if (query.values && query.values.length > 1) {
return scoreMultiple(target, query.values, fuzzy);
}
return scoreSingle(target, query.value, query.valueLowercase, fuzzy);
}
function scoreMultiple(target: string, query: IPreparedQueryPiece[], fuzzy: boolean): Score {
let totalScore = NO_MATCH;
const totalPositions: number[] = [];
for (const { value, valueLowercase } of query) {
const [scoreValue, positions] = scoreSingle(target, value, valueLowercase, fuzzy);
if (scoreValue === NO_MATCH) {
// if a single query value does not match, return with
// no score entirely, we require all queries to match
return NO_SCORE;
}
totalScore += scoreValue;
totalPositions.push(...positions);
}
if (totalScore === NO_MATCH) {
return NO_SCORE;
}
// if we have a score, ensure that the positions are
// sorted in ascending order and distinct
return [totalScore, distinctES6(totalPositions).sort((a, b) => a - b)];
}
function scoreSingle(target: string, query: string, queryLower: string, fuzzy: boolean): Score {
if (!target || !query) {
return NO_SCORE; // return early if target or query are undefined
}
......@@ -303,21 +337,62 @@ const LABEL_PREFIX_SCORE = 1 << 17;
const LABEL_CAMELCASE_SCORE = 1 << 16;
const LABEL_SCORE_THRESHOLD = 1 << 15;
export interface IPreparedQuery {
export interface IPreparedQueryPiece {
original: string;
originalLowercase: string;
value: string;
lowercase: string;
valueLowercase: string;
}
export interface IPreparedQuery extends IPreparedQueryPiece {
// Split by spaces
values: IPreparedQueryPiece[] | undefined;
containsPathSeparator: boolean;
}
/**
* Helper function to prepare a search value for scoring by removing unwanted characters.
* Helper function to prepare a search value for scoring by removing unwanted characters
* and allowing to score on multiple pieces separated by whitespace character.
*/
const MULTIPL_QUERY_VALUES_SEPARATOR = ' ';
export function prepareQuery(original: string): IPreparedQuery {
if (!original) {
if (typeof original !== 'string') {
original = '';
}
const originalLowercase = original.toLowerCase();
const value = prepareQueryValue(original);
const valueLowercase = value.toLowerCase();
const containsPathSeparator = value.indexOf(sep) >= 0;
let values: IPreparedQueryPiece[] | undefined = undefined;
const originalSplit = original.split(MULTIPL_QUERY_VALUES_SEPARATOR);
if (originalSplit.length > 1) {
for (const originalPiece of originalSplit) {
const valuePiece = prepareQueryValue(originalPiece);
if (valuePiece) {
if (!values) {
values = [];
}
values.push({
original: originalPiece,
originalLowercase: originalPiece.toLowerCase(),
value: valuePiece,
valueLowercase: valuePiece.toLowerCase()
});
}
}
}
return { original, originalLowercase, value, valueLowercase, values, containsPathSeparator };
}
function prepareQueryValue(original: string): string {
let value = stripWildcards(original).replace(/\s/g, ''); // get rid of all wildcards and whitespace
if (isWindows) {
value = value.replace(/\//g, sep); // Help Windows users to search for paths when using slash
......@@ -325,10 +400,7 @@ export function prepareQuery(original: string): IPreparedQuery {
value = value.replace(/\\/g, sep); // Help macOS/Linux users to search for paths when using backslash
}
const lowercase = value.toLowerCase();
const containsPathSeparator = value.indexOf(sep) >= 0;
return { original, value, lowercase, containsPathSeparator };
return value;
}
export function scoreItem<T>(item: T, query: IPreparedQuery, fuzzy: boolean, accessor: IItemAccessor<T>, cache: ScorerCache): IItemScore {
......@@ -404,7 +476,7 @@ function doScoreItem(label: string, description: string | undefined, path: strin
}
// 4.) prefer scores on the label if any
const [labelScore, labelPositions] = score(label, query.value, query.lowercase, fuzzy);
const [labelScore, labelPositions] = score(label, query, fuzzy);
if (labelScore) {
return { score: labelScore + LABEL_SCORE_THRESHOLD, labelMatch: createMatches(labelPositions) };
}
......@@ -420,7 +492,7 @@ function doScoreItem(label: string, description: string | undefined, path: strin
const descriptionPrefixLength = descriptionPrefix.length;
const descriptionAndLabel = `${descriptionPrefix}${label}`;
const [labelDescriptionScore, labelDescriptionPositions] = score(descriptionAndLabel, query.value, query.lowercase, fuzzy);
const [labelDescriptionScore, labelDescriptionPositions] = score(descriptionAndLabel, query, fuzzy);
if (labelDescriptionScore) {
const labelDescriptionMatches = createMatches(labelDescriptionPositions);
const labelMatch: IMatch[] = [];
......
......@@ -43,7 +43,7 @@ class NullAccessorClass implements scorer.IItemAccessor<URI> {
}
function _doScore(target: string, query: string, fuzzy: boolean): scorer.Score {
return scorer.score(target, query, query.toLowerCase(), fuzzy);
return scorer.score(target, scorer.prepareQuery(query), fuzzy);
}
function scoreItem<T>(item: T, query: string, fuzzy: boolean, accessor: scorer.IItemAccessor<T>, cache: scorer.ScorerCache): scorer.IItemScore {
......@@ -109,6 +109,42 @@ suite('Fuzzy Scorer', () => {
assert.equal(_doScore(target, 'eo', false)[0], 0);
});
test('score (fuzzy, multiple)', function () {
const target = 'HeLlo-World';
const [firstSingleScore, firstSinglePositions] = _doScore(target, 'HelLo', true);
const [secondSingleScore, secondSinglePositions] = _doScore(target, 'World', true);
const firstAndSecondSinglePositions = [...firstSinglePositions, ...secondSinglePositions];
let [multiScore, multiPositions] = _doScore(target, 'HelLo World', true);
function assertScore() {
assert.ok(multiScore >= firstSingleScore + secondSingleScore);
for (let i = 0; i < multiPositions.length; i++) {
assert.equal(multiPositions[i], firstAndSecondSinglePositions[i]);
}
}
function assertNoScore() {
assert.equal(multiScore, 0);
assert.equal(multiPositions.length, 0);
}
assertScore();
[multiScore, multiPositions] = _doScore(target, 'World HelLo', true);
assertScore();
[multiScore, multiPositions] = _doScore(target, 'World HelLo World', true);
assertScore();
[multiScore, multiPositions] = _doScore(target, 'World HelLo Nothing', true);
assertNoScore();
[multiScore, multiPositions] = _doScore(target, 'More Nothing', true);
assertNoScore();
});
test('scoreItem - matches are proper', function () {
let res = scoreItem(null, 'something', true, ResourceAccessor, cache);
assert.ok(!res.score);
......@@ -820,11 +856,42 @@ suite('Fuzzy Scorer', () => {
assert.equal(res[0], resourceB);
});
test('prepareSearchForScoring', () => {
test('prepareQuery', () => {
assert.equal(scorer.prepareQuery(' f*a ').value, 'fa');
assert.equal(scorer.prepareQuery('model Tester.ts').original, 'model Tester.ts');
assert.equal(scorer.prepareQuery('model Tester.ts').originalLowercase, 'model Tester.ts'.toLowerCase());
assert.equal(scorer.prepareQuery('model Tester.ts').value, 'modelTester.ts');
assert.equal(scorer.prepareQuery('Model Tester.ts').lowercase, 'modeltester.ts');
assert.equal(scorer.prepareQuery('Model Tester.ts').valueLowercase, 'modeltester.ts');
assert.equal(scorer.prepareQuery('ModelTester.ts').containsPathSeparator, false);
assert.equal(scorer.prepareQuery('Model' + sep + 'Tester.ts').containsPathSeparator, true);
// with spaces
let query = scorer.prepareQuery('He*llo World');
assert.equal(query.original, 'He*llo World');
assert.equal(query.value, 'HelloWorld');
assert.equal(query.valueLowercase, 'HelloWorld'.toLowerCase());
assert.equal(query.values?.length, 2);
assert.equal(query.values?.[0].original, 'He*llo');
assert.equal(query.values?.[0].value, 'Hello');
assert.equal(query.values?.[0].valueLowercase, 'Hello'.toLowerCase());
assert.equal(query.values?.[1].original, 'World');
assert.equal(query.values?.[1].value, 'World');
assert.equal(query.values?.[1].valueLowercase, 'World'.toLowerCase());
// with spaces that are empty
query = scorer.prepareQuery(' Hello World ');
assert.equal(query.original, ' Hello World ');
assert.equal(query.originalLowercase, ' Hello World '.toLowerCase());
assert.equal(query.value, 'HelloWorld');
assert.equal(query.valueLowercase, 'HelloWorld'.toLowerCase());
assert.equal(query.values?.length, 2);
assert.equal(query.values?.[0].original, 'Hello');
assert.equal(query.values?.[0].originalLowercase, 'Hello'.toLowerCase());
assert.equal(query.values?.[0].value, 'Hello');
assert.equal(query.values?.[0].valueLowercase, 'Hello'.toLowerCase());
assert.equal(query.values?.[1].original, 'World');
assert.equal(query.values?.[1].originalLowercase, 'World'.toLowerCase());
assert.equal(query.values?.[1].value, 'World');
assert.equal(query.values?.[1].valueLowercase, 'World'.toLowerCase());
});
});
......@@ -17,6 +17,7 @@ import { values } from 'vs/base/common/collections';
import { trim, format } from 'vs/base/common/strings';
import { fuzzyScore, FuzzyScore, createMatches } from 'vs/base/common/filters';
import { assign } from 'vs/base/common/objects';
import { prepareQuery, IPreparedQuery } from 'vs/base/common/fuzzyScorer';
export interface IGotoSymbolQuickPickItem extends IQuickPickItem {
kind: SymbolKind,
......@@ -155,7 +156,7 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit
// Collect symbol picks
picker.busy = true;
try {
const items = await this.doGetSymbolPicks(symbolsPromise, picker.value.substr(AbstractGotoSymbolQuickAccessProvider.PREFIX.length).trim(), picksCts.token);
const items = await this.doGetSymbolPicks(symbolsPromise, prepareQuery(picker.value.substr(AbstractGotoSymbolQuickAccessProvider.PREFIX.length).trim()), picksCts.token);
if (token.isCancellationRequested) {
return;
}
......@@ -194,18 +195,24 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit
return disposables;
}
protected async doGetSymbolPicks(symbolsPromise: Promise<DocumentSymbol[]>, filter: string, token: CancellationToken): Promise<Array<IGotoSymbolQuickPickItem | IQuickPickSeparator>> {
protected async doGetSymbolPicks(symbolsPromise: Promise<DocumentSymbol[]>, query: IPreparedQuery, token: CancellationToken): Promise<Array<IGotoSymbolQuickPickItem | IQuickPickSeparator>> {
const symbols = await symbolsPromise;
if (token.isCancellationRequested) {
return [];
}
// Normalize filter
const filterBySymbolKind = filter.indexOf(AbstractGotoSymbolQuickAccessProvider.SCOPE_PREFIX) === 0;
const filterBySymbolKind = query.original.indexOf(AbstractGotoSymbolQuickAccessProvider.SCOPE_PREFIX) === 0;
const filterPos = filterBySymbolKind ? 1 : 0;
const [symbolFilter, containerFilter] = filter.split(' ') as [string, string | undefined];
const symbolFilterLow = symbolFilter.toLowerCase();
const containerFilterLow = containerFilter?.toLowerCase();
// Split between symbol and container query if separated by space
let symbolQuery: IPreparedQuery;
let containerQuery: IPreparedQuery | undefined;
if (query.values && query.values.length > 1) {
symbolQuery = prepareQuery(query.values[0].original);
containerQuery = prepareQuery(query.values[1].original);
} else {
symbolQuery = query;
}
// Convert to symbol picks and apply filtering
const filteredSymbolPicks: IGotoSymbolQuickPickItem[] = [];
......@@ -219,16 +226,16 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit
let containerScore: FuzzyScore | undefined = undefined;
let includeSymbol = true;
if (filter.length > filterPos) {
if (query.original.length > filterPos) {
// Score by symbol
symbolScore = fuzzyScore(symbolFilter, symbolFilterLow, filterPos, symbolLabel, symbolLabel.toLowerCase(), 0, true);
symbolScore = fuzzyScore(symbolQuery.original, symbolQuery.originalLowercase, filterPos, symbolLabel, symbolLabel.toLowerCase(), 0, true);
includeSymbol = !!symbolScore;
// Score by container if specified
if (includeSymbol && containerFilter && containerFilterLow) {
if (includeSymbol && containerQuery) {
if (containerLabel) {
containerScore = fuzzyScore(containerFilter, containerFilterLow, filterPos, containerLabel, containerLabel.toLowerCase(), 0, true);
containerScore = fuzzyScore(containerQuery.original, containerQuery.originalLowercase, filterPos, containerLabel, containerLabel.toLowerCase(), 0, true);
}
includeSymbol = !!containerScore;
......
......@@ -21,6 +21,7 @@ import { Action } from 'vs/base/common/actions';
import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
import { prepareQuery } from 'vs/base/common/fuzzyScorer';
export class GotoSymbolQuickAccessProvider extends AbstractGotoSymbolQuickAccessProvider {
......@@ -85,7 +86,7 @@ export class GotoSymbolQuickAccessProvider extends AbstractGotoSymbolQuickAccess
return [];
}
return this.doGetSymbolPicks(this.getDocumentSymbols(model, true, token), filter, token);
return this.doGetSymbolPicks(this.getDocumentSymbols(model, true, token), prepareQuery(filter), token);
}
addDecorations(editor: IEditor, range: IRange): void {
......
......@@ -357,28 +357,30 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
return [];
}
// Sort top 512 items by score
// Perform sorting (top results by score)
const sortedAnythingPicks = top(
[...filePicks, ...symbolPicks],
(anyPickA, anyPickB) => compareItemsByScore(anyPickA, anyPickB, query, true, quickPickItemScorerAccessor, this.pickState.scorerCache),
AnythingQuickAccessProvider.MAX_RESULTS
);
// Adjust highlights
// Perform filtering
const filteredAnythingPicks: IAnythingQuickPickItem[] = [];
for (const anythingPick of sortedAnythingPicks) {
if (anythingPick.highlights) {
continue; // preserve any highlights we got already (e.g. symbols)
const { score, labelMatch, descriptionMatch } = scoreItem(anythingPick, query, true, quickPickItemScorerAccessor, this.pickState.scorerCache);
if (!score) {
continue; // exclude files/symbols not matching query
}
const { labelMatch, descriptionMatch } = scoreItem(anythingPick, query, true, quickPickItemScorerAccessor, this.pickState.scorerCache);
anythingPick.highlights = {
label: labelMatch,
description: descriptionMatch
};
filteredAnythingPicks.push(anythingPick);
}
return sortedAnythingPicks;
return filteredAnythingPicks;
}
......@@ -398,10 +400,8 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
return []; // disabled when searching
}
// Only match on label of the editor unless the search includes path separators
const editorHistoryScorerAccessor = query.containsPathSeparator ? quickPickItemScorerAccessor : this.labelOnlyEditorHistoryPickAccessor;
// Otherwise filter and sort by query
// Perform filtering
const editorHistoryScorerAccessor = query.containsPathSeparator ? quickPickItemScorerAccessor : this.labelOnlyEditorHistoryPickAccessor; // Only match on label of the editor unless the search includes path separators
const editorHistoryPicks: Array<IAnythingQuickPickItem> = [];
for (const editor of this.historyService.getHistory()) {
const resource = editor.resource;
......@@ -429,6 +429,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
return editorHistoryPicks;
}
// Perform sorting
return editorHistoryPicks.sort((editorA, editorB) => compareItemsByScore(editorA, editorB, query, false, editorHistoryScorerAccessor, this.pickState.scorerCache));
}
......@@ -501,7 +502,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
this.fileQueryBuilder.file(
this.contextService.getWorkspace().folders,
this.getFileQueryOptions({
filePattern: query.original,
query,
cacheKey: this.pickState.fileQueryCache?.cacheKey,
maxResults: AnythingQuickAccessProvider.MAX_RESULTS
})
......@@ -536,17 +537,32 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
];
}
private getFileQueryOptions(input: { filePattern?: string, cacheKey?: string, maxResults?: number }): IFileQueryBuilderOptions {
const fileQueryOptions: IFileQueryBuilderOptions = {
private getFileQueryOptions(input: { query?: IPreparedQuery, cacheKey?: string, maxResults?: number }): IFileQueryBuilderOptions {
// filePattern for search depends on the number of queries in input:
// - with multiple: only take the first one and let the filter later drop non-matching results
// - with single: just take the original in full
//
// This enables to e.g. search for "someFile someFolder" by only returning
// search results for "someFile" and not both that would normally not match.
//
let filePattern = '';
if (input.query) {
if (input.query.values && input.query.values.length > 1) {
filePattern = input.query.values[0].original;
} else {
filePattern = input.query.original;
}
}
return {
_reason: 'openFileHandler', // used for telemetry - do not change
extraFileResources: this.instantiationService.invokeFunction(getOutOfWorkspaceEditorResources),
filePattern: input.filePattern || '',
filePattern,
cacheKey: input.cacheKey,
maxResults: input.maxResults || 0,
sortByScore: true
};
return fileQueryOptions;
}
private async getAbsolutePathFileResult(query: IPreparedQuery, token: CancellationToken): Promise<URI | undefined> {
......@@ -638,11 +654,25 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider<IAnyt
return [];
}
// symbolPattern for search depends on the number of queries in input:
// - with multiple: only take the first one and let the filter later drop non-matching results
// - with single: just take the original in full
//
// This enables to e.g. search for "someFile someFolder" by only returning
// symbol results for "someFile" and not both that would normally not match.
//
let symbolPattern = '';
if (query.values && query.values.length > 1) {
symbolPattern = query.values[0].original;
} else {
symbolPattern = query.original;
}
// Delegate to the existing symbols quick access
// but skip local results and also do not sort
return this.workspaceSymbolsQuickAccess.getSymbolPicks(query.value, {
// but skip local results and also do not score
return this.workspaceSymbolsQuickAccess.getSymbolPicks(symbolPattern, {
skipLocal: true,
skipSorting: true,
skipScoring: true,
delay: AnythingQuickAccessProvider.TYPING_SEARCH_DELAY
}, token);
}
......
......@@ -6,7 +6,6 @@
import { localize } from 'vs/nls';
import { IPickerQuickAccessItem, PickerQuickAccessProvider, TriggerAction } from 'vs/platform/quickinput/browser/pickerQuickAccess';
import { fuzzyScore, createMatches, FuzzyScore } from 'vs/base/common/filters';
import { stripWildcards } from 'vs/base/common/strings';
import { CancellationToken } from 'vs/base/common/cancellation';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { ThrottledDelayer } from 'vs/base/common/async';
......@@ -27,6 +26,7 @@ import { URI } from 'vs/base/common/uri';
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
import { getSelectionSearchString } from 'vs/editor/contrib/find/findController';
import { withNullAsUndefined } from 'vs/base/common/types';
import { prepareQuery, IPreparedQuery } from 'vs/base/common/fuzzyScorer';
interface ISymbolQuickPickItem extends IPickerQuickAccessItem {
resource: URI | undefined;
......@@ -89,28 +89,33 @@ export class SymbolsQuickAccessProvider extends PickerQuickAccessProvider<ISymbo
return this.getSymbolPicks(filter, undefined, token);
}
async getSymbolPicks(filter: string, options: { skipLocal?: boolean, skipSorting?: boolean, delay?: number } | undefined, token: CancellationToken): Promise<Array<ISymbolQuickPickItem>> {
async getSymbolPicks(filter: string, options: { skipLocal?: boolean, skipScoring?: boolean, delay?: number } | undefined, token: CancellationToken): Promise<Array<ISymbolQuickPickItem>> {
return this.delayer.trigger(async () => {
if (token.isCancellationRequested) {
return [];
}
return this.doGetSymbolPicks(filter, options, token);
return this.doGetSymbolPicks(prepareQuery(filter), options, token);
}, options?.delay);
}
private async doGetSymbolPicks(filter: string, options: { skipLocal?: boolean, skipSorting?: boolean } | undefined, token: CancellationToken): Promise<Array<ISymbolQuickPickItem>> {
const workspaceSymbols = await getWorkspaceSymbols(filter, token);
private async doGetSymbolPicks(query: IPreparedQuery, options: { skipLocal?: boolean, skipScoring?: boolean } | undefined, token: CancellationToken): Promise<Array<ISymbolQuickPickItem>> {
const workspaceSymbols = await getWorkspaceSymbols(query.original, token);
if (token.isCancellationRequested) {
return [];
}
const symbolPicks: Array<ISymbolQuickPickItem> = [];
// Normalize filter
const [symbolFilter, containerFilter] = stripWildcards(filter).split(' ') as [string, string | undefined];
const symbolFilterLow = symbolFilter.toLowerCase();
const containerFilterLow = containerFilter?.toLowerCase();
// Split between symbol and container query
let symbolQuery: IPreparedQuery;
let containerQuery: IPreparedQuery | undefined;
if (query.values && query.values.length > 1) {
symbolQuery = prepareQuery(query.values[0].original);
containerQuery = prepareQuery(query.values[1].original);
} else {
symbolQuery = query;
}
// Convert to symbol picks and apply filtering
const openSideBySideDirection = this.configuration.openSideBySideDirection;
......@@ -125,9 +130,9 @@ export class SymbolsQuickAccessProvider extends PickerQuickAccessProvider<ISymbo
continue;
}
// Score by symbol label
// Score by symbol label (unless disabled)
const symbolLabel = symbol.name;
const symbolScore = fuzzyScore(symbolFilter, symbolFilterLow, 0, symbolLabel, symbolLabel.toLowerCase(), 0, true);
const symbolScore = options?.skipScoring ? FuzzyScore.Default : fuzzyScore(symbolQuery.original, symbolQuery.originalLowercase, 0, symbolLabel, symbolLabel.toLowerCase(), 0, true);
if (!symbolScore) {
continue;
}
......@@ -143,11 +148,13 @@ export class SymbolsQuickAccessProvider extends PickerQuickAccessProvider<ISymbo
}
}
// Score by container if specified
// Score by container if specified (unless disabled)
let containerScore: FuzzyScore | undefined = undefined;
if (containerFilter && containerFilterLow) {
if (options?.skipScoring) {
containerScore = FuzzyScore.Default;
} else if (containerQuery) {
if (containerLabel) {
containerScore = fuzzyScore(containerFilter, containerFilterLow, 0, containerLabel, containerLabel.toLowerCase(), 0, true);
containerScore = fuzzyScore(containerQuery.original, containerQuery.originalLowercase, 0, containerLabel, containerLabel.toLowerCase(), 0, true);
}
if (!containerScore) {
......@@ -177,7 +184,7 @@ export class SymbolsQuickAccessProvider extends PickerQuickAccessProvider<ISymbo
score: symbolScore,
label: symbolLabelWithIcon,
ariaLabel: localize('symbolAriaLabel', "{0}, symbols picker", symbolLabel),
highlights: deprecated ? undefined : {
highlights: (deprecated || options?.skipScoring) ? undefined : {
label: createMatches(symbolScore, symbolLabelWithIcon.length - symbolLabel.length /* Readjust matches to account for codicons in label */),
description: createMatches(containerScore)
},
......@@ -200,7 +207,7 @@ export class SymbolsQuickAccessProvider extends PickerQuickAccessProvider<ISymbo
}
// Sort picks (unless disabled)
if (!options?.skipSorting) {
if (!options?.skipScoring) {
symbolPicks.sort((symbolA, symbolB) => this.compareSymbols(symbolA, symbolB));
}
......
......@@ -77,7 +77,7 @@ export class FileWalker {
this.errors = [];
if (this.filePattern) {
this.normalizedFilePatternLowercase = prepareQuery(this.filePattern).lowercase;
this.normalizedFilePatternLowercase = prepareQuery(this.filePattern).valueLowercase;
}
this.globalExcludePattern = config.excludePattern && glob.parse(config.excludePattern);
......
......@@ -312,7 +312,7 @@ export class SearchService implements IRawSearchService {
// Pattern match on results
const results: IRawFileMatch[] = [];
const normalizedSearchValueLowercase = prepareQuery(searchValue).lowercase;
const normalizedSearchValueLowercase = prepareQuery(searchValue).valueLowercase;
for (const entry of cachedEntries) {
// Check if this entry is a match for the search value
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册