forked from microsoft/vscode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscorer.ts
More file actions
134 lines (112 loc) · 3.01 KB
/
Copy pathscorer.ts
File metadata and controls
134 lines (112 loc) · 3.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
// Based on material from:
/*!
BEGIN THIRD PARTY
*/
/*!
* string_score.js: String Scoring Algorithm 0.1.22
*
* http://joshaven.com/string_score
* https://github.com/joshaven/string_score
*
* Copyright (C) 2009-2014 Joshaven Potter <yourtech@gmail.com>
* Special thanks to all of the contributors listed here https://github.com/joshaven/string_score
* MIT License: http://opensource.org/licenses/MIT
*
* Date: Tue Mar 1 2011
* Updated: Tue Mar 10 2015
*/
/**
* Compute a score for the given string and the given query.
*
* Rules:
* Character score: 1
* Same case bonus: 1
* Upper case bonus: 1
* Consecutive match bonus: 5
* Start of word/path bonus: 7
* Start of string bonus: 8
*/
const wordPathBoundary = ['-', '_', ' ', '/', '\\', '.'];
export function score(target: string, query: string, cache?: { [id: string]: number }): number {
if (!target || !query) {
return 0; // return early if target or query are undefined
}
const hash = target + query;
const cached = cache && cache[hash];
if (typeof cached === 'number') {
return cached;
}
const queryLen = query.length;
const targetLower = target.toLowerCase();
const queryLower = query.toLowerCase();
let index = 0;
let startAt = 0;
let score = 0;
while (index < queryLen) {
let indexOf = targetLower.indexOf(queryLower[index], startAt);
if (indexOf < 0) {
score = 0; // This makes sure that the query is contained in the target
break;
}
// Character match bonus
score += 1;
// Consecutive match bonus
if (startAt === indexOf) {
score += 5;
}
// Same case bonus
if (target[indexOf] === query[indexOf]) {
score += 1;
}
// Start of word bonus
if (indexOf === 0) {
score += 8;
}
// After separator bonus
else if (wordPathBoundary.some(w => w === target[indexOf - 1])) {
score += 7;
}
// Inside word upper case bonus
else if (isUpper(target.charCodeAt(indexOf))) {
score += 1;
}
startAt = indexOf + 1;
index++;
}
if (cache) {
cache[hash] = score;
}
return score;
}
function isUpper(code: number): boolean {
return 65 <= code && code <= 90;
}
/**
* A fast method to check if a given string would produce a score > 0 for the given query.
*/
export function matches(target: string, queryLower: string): boolean {
if (!target || !queryLower) {
return false; // return early if target or query are undefined
}
const queryLen = queryLower.length;
const targetLower = target.toLowerCase();
let index = 0;
let lastIndexOf = -1;
while (index < queryLen) {
let indexOf = targetLower.indexOf(queryLower[index], lastIndexOf + 1);
if (indexOf < 0) {
return false;
}
lastIndexOf = indexOf;
index++;
}
return true;
}
/*!
END THIRD PARTY
*/