mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-08 17:19:48 +01:00
move compareResourcesByScore
This commit is contained in:
@@ -4,8 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import scorer = require('vs/base/common/scorer');
|
||||
import strings = require('vs/base/common/strings');
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import * as paths from 'vs/base/common/paths';
|
||||
|
||||
let intlFileNameCollator: Intl.Collator;
|
||||
@@ -186,56 +185,4 @@ export function compareByPrefix(one: string, other: string, lookFor: string): nu
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
export interface IScorableResourceAccessor<T> {
|
||||
getLabel(t: T): string;
|
||||
getResourcePath(t: T): string;
|
||||
}
|
||||
|
||||
export function compareByScore<T>(elementA: T, elementB: T, accessor: IScorableResourceAccessor<T>, lookFor: string, lookForNormalizedLower: string, scorerCache?: { [key: string]: number }): number {
|
||||
const labelA = accessor.getLabel(elementA);
|
||||
const labelB = accessor.getLabel(elementB);
|
||||
|
||||
// treat prefix matches highest in any case
|
||||
const prefixCompare = compareByPrefix(labelA, labelB, lookFor);
|
||||
if (prefixCompare) {
|
||||
return prefixCompare;
|
||||
}
|
||||
|
||||
// Give higher importance to label score
|
||||
const labelAScore = scorer.score(labelA, lookFor, scorerCache);
|
||||
const labelBScore = scorer.score(labelB, lookFor, scorerCache);
|
||||
|
||||
if (labelAScore !== labelBScore) {
|
||||
return labelAScore > labelBScore ? -1 : 1;
|
||||
}
|
||||
|
||||
// Score on full resource path comes next (if available)
|
||||
let resourcePathA = accessor.getResourcePath(elementA);
|
||||
let resourcePathB = accessor.getResourcePath(elementB);
|
||||
if (resourcePathA && resourcePathB) {
|
||||
const resourceAScore = scorer.score(resourcePathA, lookFor, scorerCache);
|
||||
const resourceBScore = scorer.score(resourcePathB, lookFor, scorerCache);
|
||||
|
||||
if (resourceAScore !== resourceBScore) {
|
||||
return resourceAScore > resourceBScore ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
// At this place, the scores are identical so we check for string lengths and favor shorter ones
|
||||
if (labelA.length !== labelB.length) {
|
||||
return labelA.length < labelB.length ? -1 : 1;
|
||||
}
|
||||
|
||||
if (resourcePathA && resourcePathB && resourcePathA.length !== resourcePathB.length) {
|
||||
return resourcePathA.length < resourcePathB.length ? -1 : 1;
|
||||
}
|
||||
|
||||
// Finally compare by label or resource path
|
||||
if (labelA === labelB && resourcePathA && resourcePathB) {
|
||||
return compareAnything(resourcePathA, resourcePathB, lookForNormalizedLower);
|
||||
}
|
||||
|
||||
return compareAnything(labelA, labelB, lookForNormalizedLower);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import { compareByPrefix, compareAnything } from 'vs/base/common/comparers';
|
||||
|
||||
// Based on material from:
|
||||
/*!
|
||||
BEGIN THIRD PARTY
|
||||
@@ -151,4 +153,56 @@ function isUpper(code: number): boolean {
|
||||
}
|
||||
/*!
|
||||
END THIRD PARTY
|
||||
*/
|
||||
*/
|
||||
|
||||
export interface IScorableResourceAccessor<T> {
|
||||
getResourceLabel(t: T): string;
|
||||
getResourcePath(t: T): string;
|
||||
}
|
||||
|
||||
export function compareResourcesByScore<T>(resourceA: T, resourceB: T, accessor: IScorableResourceAccessor<T>, lookFor: string, lookForNormalizedLower: string, scorerCache?: { [key: string]: number }): number {
|
||||
const resourceLabelA = accessor.getResourceLabel(resourceA);
|
||||
const resourceLabelB = accessor.getResourceLabel(resourceB);
|
||||
|
||||
// treat prefix matches highest in any case
|
||||
const prefixCompare = compareByPrefix(resourceLabelA, resourceLabelB, lookFor);
|
||||
if (prefixCompare) {
|
||||
return prefixCompare;
|
||||
}
|
||||
|
||||
// Give higher importance to label score
|
||||
const resourceLabelScoreA = score(resourceLabelA, lookFor, scorerCache);
|
||||
const resourceLabelScoreB = score(resourceLabelB, lookFor, scorerCache);
|
||||
|
||||
if (resourceLabelScoreA !== resourceLabelScoreB) {
|
||||
return resourceLabelScoreA > resourceLabelScoreB ? -1 : 1;
|
||||
}
|
||||
|
||||
// Score on full resource path comes next (if available)
|
||||
let resourcePathA = accessor.getResourcePath(resourceA);
|
||||
let resourcePathB = accessor.getResourcePath(resourceB);
|
||||
if (resourcePathA && resourcePathB) {
|
||||
const resourceAScore = score(resourcePathA, lookFor, scorerCache);
|
||||
const resourceBScore = score(resourcePathB, lookFor, scorerCache);
|
||||
|
||||
if (resourceAScore !== resourceBScore) {
|
||||
return resourceAScore > resourceBScore ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
// At this place, the scores are identical so we check for string lengths and favor shorter ones
|
||||
if (resourceLabelA.length !== resourceLabelB.length) {
|
||||
return resourceLabelA.length < resourceLabelB.length ? -1 : 1;
|
||||
}
|
||||
|
||||
if (resourcePathA && resourcePathB && resourcePathA.length !== resourcePathB.length) {
|
||||
return resourcePathA.length < resourcePathB.length ? -1 : 1;
|
||||
}
|
||||
|
||||
// Finally compare by label or resource path
|
||||
if (resourceLabelA === resourceLabelB && resourcePathA && resourcePathB) {
|
||||
return compareAnything(resourcePathA, resourcePathB, lookForNormalizedLower);
|
||||
}
|
||||
|
||||
return compareAnything(resourceLabelA, resourceLabelB, lookForNormalizedLower);
|
||||
}
|
||||
@@ -37,14 +37,15 @@ export interface IHighlight {
|
||||
|
||||
let IDS = 0;
|
||||
|
||||
export class EntryAccessor {
|
||||
export class ResourceAccessor {
|
||||
|
||||
public static getLabel(entry: QuickOpenEntry) {
|
||||
public static getResourceLabel(entry: QuickOpenEntry) {
|
||||
return entry.getLabel();
|
||||
}
|
||||
|
||||
public static getResourcePath(entry: QuickOpenEntry) {
|
||||
const resource = entry.getResource();
|
||||
|
||||
return resource && resource.fsPath;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import URI from 'vs/base/common/uri';
|
||||
import errors = require('vs/base/common/errors');
|
||||
import { IIconLabelOptions } from 'vs/base/browser/ui/iconLabel/iconLabel';
|
||||
import { IAutoFocus, Mode, IEntryRunContext, IQuickNavigateConfiguration, IModel } from 'vs/base/parts/quickopen/common/quickOpen';
|
||||
import { QuickOpenModel, QuickOpenEntry, QuickOpenEntryGroup, EntryAccessor } from 'vs/base/parts/quickopen/browser/quickOpenModel';
|
||||
import { QuickOpenModel, QuickOpenEntry, QuickOpenEntryGroup, ResourceAccessor } from 'vs/base/parts/quickopen/browser/quickOpenModel';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { getIconClasses } from 'vs/workbench/browser/labels';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
@@ -23,8 +23,8 @@ import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/edi
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { EditorInput, toResource, IEditorGroup, IEditorStacksModel } from 'vs/workbench/common/editor';
|
||||
import { compareByScore } from 'vs/base/common/comparers';
|
||||
import { stripWildcards, fuzzyContains } from 'vs/base/common/strings';
|
||||
import { compareResourcesByScore } from 'vs/base/common/scorer';
|
||||
|
||||
export class EditorPickerEntry extends QuickOpenEntryGroup {
|
||||
private stacks: IEditorStacksModel;
|
||||
@@ -137,7 +137,7 @@ export abstract class BaseEditorPicker extends QuickOpenHandler {
|
||||
return stacks.positionOfGroup(e1.group) - stacks.positionOfGroup(e2.group);
|
||||
}
|
||||
|
||||
return compareByScore(e1, e2, EntryAccessor, searchValue, normalizedSearchValueLowercase, this.scorerCache);
|
||||
return compareResourcesByScore(e1, e2, ResourceAccessor, searchValue, normalizedSearchValueLowercase, this.scorerCache);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import types = require('vs/base/common/types');
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
import strings = require('vs/base/common/strings');
|
||||
import { IAutoFocus } from 'vs/base/parts/quickopen/common/quickOpen';
|
||||
import { QuickOpenEntry, QuickOpenModel, EntryAccessor } from 'vs/base/parts/quickopen/browser/quickOpenModel';
|
||||
import { QuickOpenEntry, QuickOpenModel, ResourceAccessor } from 'vs/base/parts/quickopen/browser/quickOpenModel';
|
||||
import { QuickOpenHandler } from 'vs/workbench/browser/quickopen';
|
||||
import { FileEntry, OpenFileHandler, FileQuickOpenModel } from 'vs/workbench/parts/search/browser/openFileHandler';
|
||||
import * as openSymbolHandler from 'vs/workbench/parts/search/browser/openSymbolHandler';
|
||||
@@ -24,10 +24,10 @@ import { ISearchStats, ICachedSearchStats, IUncachedSearchStats } from 'vs/platf
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IWorkbenchSearchConfiguration } from 'vs/workbench/parts/search/common/search';
|
||||
// OpenSymbolHandler is used from an extension and must be in the main bundle file so it can load
|
||||
export import OpenSymbolHandler = openSymbolHandler.OpenSymbolHandler;
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
import { compareByScore } from 'vs/base/common/comparers';
|
||||
import { compareResourcesByScore } from 'vs/base/common/scorer';
|
||||
|
||||
export import OpenSymbolHandler = openSymbolHandler.OpenSymbolHandler; // OpenSymbolHandler is used from an extension and must be in the main bundle file so it can load
|
||||
|
||||
const objects_assign: <T, U>(destination: T, source: U) => T & U = objects.assign;
|
||||
|
||||
@@ -216,7 +216,7 @@ export class OpenAnythingHandler extends QuickOpenHandler {
|
||||
// Sort
|
||||
const unsortedResultTime = Date.now();
|
||||
const normalizedSearchValue = strings.stripWildcards(searchValue).toLowerCase();
|
||||
const compare = (elementA: QuickOpenEntry, elementB: QuickOpenEntry) => compareByScore(elementA, elementB, EntryAccessor, searchValue, normalizedSearchValue, this.scorerCache);
|
||||
const compare = (elementA: QuickOpenEntry, elementB: QuickOpenEntry) => compareResourcesByScore(elementA, elementB, ResourceAccessor, searchValue, normalizedSearchValue, this.scorerCache);
|
||||
const viewResults = arrays.top(mergedResults, compare, OpenAnythingHandler.MAX_DISPLAYED_RESULTS);
|
||||
const sortedResultTime = Date.now();
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ import gracefulFs = require('graceful-fs');
|
||||
gracefulFs.gracefulify(fs);
|
||||
|
||||
import arrays = require('vs/base/common/arrays');
|
||||
import { compareByScore } from 'vs/base/common/comparers';
|
||||
import objects = require('vs/base/common/objects');
|
||||
import strings = require('vs/base/common/strings');
|
||||
import { PPromise, TPromise } from 'vs/base/common/winjs.base';
|
||||
@@ -24,6 +23,7 @@ import { TextSearchWorkerProvider } from 'vs/workbench/services/search/node/text
|
||||
import { IRawSearchService, IRawSearch, IRawFileMatch, ISerializedFileMatch, ISerializedSearchProgressItem, ISerializedSearchComplete, ISearchEngine, IFileSearchProgressItem, ITelemetryEvent } from './search';
|
||||
import { ICachedSearchStats, IProgress } from 'vs/platform/search/common/search';
|
||||
import { fuzzyContains } from 'vs/base/common/strings';
|
||||
import { compareResourcesByScore } from 'vs/base/common/scorer';
|
||||
|
||||
export class SearchService implements IRawSearchService {
|
||||
|
||||
@@ -246,7 +246,7 @@ export class SearchService implements IRawSearchService {
|
||||
private sortResults(config: IRawSearch, results: IRawFileMatch[], scorerCache: ScorerCache): IRawFileMatch[] {
|
||||
const filePattern = config.filePattern;
|
||||
const normalizedSearchValue = strings.stripWildcards(filePattern).toLowerCase();
|
||||
const compare = (elementA: IRawFileMatch, elementB: IRawFileMatch) => compareByScore(elementA, elementB, FileMatchAccessor, filePattern, normalizedSearchValue, scorerCache);
|
||||
const compare = (elementA: IRawFileMatch, elementB: IRawFileMatch) => compareResourcesByScore(elementA, elementB, FileMatchResourceAccessor, filePattern, normalizedSearchValue, scorerCache);
|
||||
return arrays.top(results, compare, config.maxResults);
|
||||
}
|
||||
|
||||
@@ -409,9 +409,9 @@ interface ScorerCache {
|
||||
[key: string]: number;
|
||||
}
|
||||
|
||||
class FileMatchAccessor {
|
||||
class FileMatchResourceAccessor {
|
||||
|
||||
public static getLabel(match: IRawFileMatch): string {
|
||||
public static getResourceLabel(match: IRawFileMatch): string {
|
||||
return match.basename;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user