move compareResourcesByScore

This commit is contained in:
Benjamin Pasero
2017-10-02 14:55:28 +02:00
parent deeccfb1ff
commit 4d523de84f
6 changed files with 72 additions and 70 deletions
+2 -55
View File
@@ -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);
}
}
+55 -1
View File
@@ -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;
}