Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
a636ab93
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
a636ab93
编写于
4月 27, 2020
作者:
B
Benjamin Pasero
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Allow Quick Open (Ctrl-P) to Prioritize Exact Case Matches (fix #96122)
上级
949baf78
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
48 addition
and
18 deletion
+48
-18
src/vs/base/common/fuzzyScorer.ts
src/vs/base/common/fuzzyScorer.ts
+35
-18
src/vs/base/test/common/fuzzyScorer.test.ts
src/vs/base/test/common/fuzzyScorer.test.ts
+13
-0
未找到文件。
src/vs/base/common/fuzzyScorer.ts
浏览文件 @
a636ab93
...
...
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import
{
compareAnything
}
from
'
vs/base/common/comparers
'
;
import
{
matchesPrefix
,
IMatch
,
matchesCamelCase
,
isUpper
,
fuzzyScore
,
createMatches
as
createFuzzyMatches
}
from
'
vs/base/common/filters
'
;
import
{
matchesPrefix
,
IMatch
,
matchesCamelCase
,
isUpper
,
fuzzyScore
,
createMatches
as
createFuzzyMatches
,
matchesStrictPrefix
}
from
'
vs/base/common/filters
'
;
import
{
sep
}
from
'
vs/base/common/path
'
;
import
{
isWindows
,
isLinux
}
from
'
vs/base/common/platform
'
;
import
{
stripWildcards
,
equalsIgnoreCase
}
from
'
vs/base/common/strings
'
;
...
...
@@ -370,9 +370,10 @@ export interface IItemAccessor<T> {
}
const
PATH_IDENTITY_SCORE
=
1
<<
18
;
const
LABEL_PREFIX_SCORE
=
1
<<
17
;
const
LABEL_CAMELCASE_SCORE
=
1
<<
16
;
const
LABEL_SCORE_THRESHOLD
=
1
<<
15
;
const
LABEL_PREFIX_SCORE_MATCHCASE
=
1
<<
17
;
const
LABEL_PREFIX_SCORE_IGNORECASE
=
1
<<
16
;
const
LABEL_CAMELCASE_SCORE
=
1
<<
15
;
const
LABEL_SCORE_THRESHOLD
=
1
<<
14
;
export
function
scoreItemFuzzy
<
T
>
(
item
:
T
,
query
:
IPreparedQuery
,
fuzzy
:
boolean
,
accessor
:
IItemAccessor
<
T
>
,
cache
:
FuzzyScorerCache
):
IItemScore
{
if
(
!
item
||
!
query
.
normalized
)
{
...
...
@@ -458,13 +459,14 @@ function doScoreItemFuzzySingle(label: string, description: string | undefined,
// Prefer label matches if told so
if
(
preferLabelMatches
)
{
// Treat prefix matches on the label second highest
const
prefixLabelMatch
=
matchesPrefix
(
query
.
normalized
,
label
);
if
(
prefixLabelMatch
)
{
return
{
score
:
LABEL_PREFIX_SCORE
,
labelMatch
:
prefixLabelMatch
};
// Treat prefix matches on the label highest
const
prefixLabelMatchIgnoreCase
=
matchesPrefix
(
query
.
normalized
,
label
);
if
(
prefixLabelMatchIgnoreCase
)
{
const
prefixLabelMatchStrictCase
=
matchesStrictPrefix
(
query
.
normalized
,
label
);
return
{
score
:
prefixLabelMatchStrictCase
?
LABEL_PREFIX_SCORE_MATCHCASE
:
LABEL_PREFIX_SCORE_IGNORECASE
,
labelMatch
:
prefixLabelMatchStrictCase
||
prefixLabelMatchIgnoreCase
};
}
// Treat camelcase matches on the label
thir
d highest
// Treat camelcase matches on the label
secon
d highest
const
camelcaseLabelMatch
=
matchesCamelCase
(
query
.
normalized
,
label
);
if
(
camelcaseLabelMatch
)
{
return
{
score
:
LABEL_CAMELCASE_SCORE
,
labelMatch
:
camelcaseLabelMatch
};
...
...
@@ -600,10 +602,10 @@ export function compareItemsByFuzzyScore<T>(itemA: T, itemB: T, query: IPrepared
}
}
// 2.) prefer label prefix matches
if
(
scoreA
===
LABEL_PREFIX_SCORE
||
scoreB
===
LABEL_PREFIX_SCOR
E
)
{
// 2.) prefer label prefix matches
(match case)
if
(
scoreA
===
LABEL_PREFIX_SCORE
_MATCHCASE
||
scoreB
===
LABEL_PREFIX_SCORE_MATCHCAS
E
)
{
if
(
scoreA
!==
scoreB
)
{
return
scoreA
===
LABEL_PREFIX_SCORE
?
-
1
:
1
;
return
scoreA
===
LABEL_PREFIX_SCORE
_MATCHCASE
?
-
1
:
1
;
}
const
labelA
=
accessor
.
getItemLabel
(
itemA
)
||
''
;
...
...
@@ -615,7 +617,22 @@ export function compareItemsByFuzzyScore<T>(itemA: T, itemB: T, query: IPrepared
}
}
// 3.) prefer camelcase matches
// 3.) prefer label prefix matches (ignore case)
if
(
scoreA
===
LABEL_PREFIX_SCORE_IGNORECASE
||
scoreB
===
LABEL_PREFIX_SCORE_IGNORECASE
)
{
if
(
scoreA
!==
scoreB
)
{
return
scoreA
===
LABEL_PREFIX_SCORE_IGNORECASE
?
-
1
:
1
;
}
const
labelA
=
accessor
.
getItemLabel
(
itemA
)
||
''
;
const
labelB
=
accessor
.
getItemLabel
(
itemB
)
||
''
;
// prefer shorter names when both match on label prefix
if
(
labelA
.
length
!==
labelB
.
length
)
{
return
labelA
.
length
-
labelB
.
length
;
}
}
// 4.) prefer camelcase matches
if
(
scoreA
===
LABEL_CAMELCASE_SCORE
||
scoreB
===
LABEL_CAMELCASE_SCORE
)
{
if
(
scoreA
!==
scoreB
)
{
return
scoreA
===
LABEL_CAMELCASE_SCORE
?
-
1
:
1
;
...
...
@@ -636,7 +653,7 @@ export function compareItemsByFuzzyScore<T>(itemA: T, itemB: T, query: IPrepared
}
}
//
4
.) prefer label scores
//
5
.) prefer label scores
if
(
scoreA
>
LABEL_SCORE_THRESHOLD
||
scoreB
>
LABEL_SCORE_THRESHOLD
)
{
if
(
scoreB
<
LABEL_SCORE_THRESHOLD
)
{
return
-
1
;
...
...
@@ -647,12 +664,12 @@ export function compareItemsByFuzzyScore<T>(itemA: T, itemB: T, query: IPrepared
}
}
//
5
.) compare by score
//
6
.) compare by score
if
(
scoreA
!==
scoreB
)
{
return
scoreA
>
scoreB
?
-
1
:
1
;
}
//
6
.) prefer matches in label over non-label matches
//
7
.) prefer matches in label over non-label matches
const
itemAHasLabelMatches
=
Array
.
isArray
(
itemScoreA
.
labelMatch
)
&&
itemScoreA
.
labelMatch
.
length
>
0
;
const
itemBHasLabelMatches
=
Array
.
isArray
(
itemScoreB
.
labelMatch
)
&&
itemScoreB
.
labelMatch
.
length
>
0
;
if
(
itemAHasLabelMatches
&&
!
itemBHasLabelMatches
)
{
...
...
@@ -661,14 +678,14 @@ export function compareItemsByFuzzyScore<T>(itemA: T, itemB: T, query: IPrepared
return
1
;
}
//
7
.) scores are identical, prefer more compact matches (label and description)
//
8
.) scores are identical, prefer more compact matches (label and description)
const
itemAMatchDistance
=
computeLabelAndDescriptionMatchDistance
(
itemA
,
itemScoreA
,
accessor
);
const
itemBMatchDistance
=
computeLabelAndDescriptionMatchDistance
(
itemB
,
itemScoreB
,
accessor
);
if
(
itemAMatchDistance
&&
itemBMatchDistance
&&
itemAMatchDistance
!==
itemBMatchDistance
)
{
return
itemBMatchDistance
>
itemAMatchDistance
?
-
1
:
1
;
}
//
7
.) at this point, scores are identical and match compactness as well
//
9
.) at this point, scores are identical and match compactness as well
// for both items so we start to use the fallback compare
return
fallbackCompare
(
itemA
,
itemB
,
query
,
accessor
);
}
...
...
src/vs/base/test/common/fuzzyScorer.test.ts
浏览文件 @
a636ab93
...
...
@@ -912,6 +912,19 @@ suite('Fuzzy Scorer', () => {
assert
.
equal
(
res
[
0
],
resourceB
);
});
test
(
'
compareFilesByScore - prefer case match (bug #96122)
'
,
function
()
{
const
resourceA
=
URI
.
file
(
'
lists.php
'
);
const
resourceB
=
URI
.
file
(
'
lib/Lists.php
'
);
let
query
=
'
Lists.php
'
;
let
res
=
[
resourceA
,
resourceB
].
sort
((
r1
,
r2
)
=>
compareItemsByScore
(
r1
,
r2
,
query
,
true
,
ResourceAccessor
));
assert
.
equal
(
res
[
0
],
resourceB
);
res
=
[
resourceB
,
resourceA
].
sort
((
r1
,
r2
)
=>
compareItemsByScore
(
r1
,
r2
,
query
,
true
,
ResourceAccessor
));
assert
.
equal
(
res
[
0
],
resourceB
);
});
test
(
'
prepareQuery
'
,
()
=>
{
assert
.
equal
(
scorer
.
prepareQuery
(
'
f*a
'
).
normalized
,
'
fa
'
);
assert
.
equal
(
scorer
.
prepareQuery
(
'
model Tester.ts
'
).
original
,
'
model Tester.ts
'
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录