Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
0ebecd5c
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,发现更多精彩内容 >>
提交
0ebecd5c
编写于
3月 20, 2017
作者:
A
Alex Dima
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' into alex/keybinding
上级
d1023963
a92ddb56
变更
23
隐藏空白更改
内联
并排
Showing
23 changed file
with
421 addition
and
215 deletion
+421
-215
src/vs/base/common/filters.ts
src/vs/base/common/filters.ts
+107
-0
src/vs/base/test/common/filters.perf.data.json
src/vs/base/test/common/filters.perf.data.json
+1
-0
src/vs/base/test/common/filters.perf.test.ts
src/vs/base/test/common/filters.perf.test.ts
+46
-0
src/vs/base/test/common/filters.test.ts
src/vs/base/test/common/filters.test.ts
+96
-1
src/vs/editor/browser/standalone/simpleServices.ts
src/vs/editor/browser/standalone/simpleServices.ts
+12
-5
src/vs/editor/contrib/suggest/browser/suggestWidget.ts
src/vs/editor/contrib/suggest/browser/suggestWidget.ts
+3
-2
src/vs/editor/contrib/suggest/common/completionModel.ts
src/vs/editor/contrib/suggest/common/completionModel.ts
+26
-90
src/vs/editor/contrib/suggest/test/common/completionModel.test.ts
...ditor/contrib/suggest/test/common/completionModel.test.ts
+5
-5
src/vs/platform/contextkey/browser/contextKeyService.ts
src/vs/platform/contextkey/browser/contextKeyService.ts
+15
-26
src/vs/platform/contextkey/common/contextkey.ts
src/vs/platform/contextkey/common/contextkey.ts
+15
-11
src/vs/platform/contextkey/test/common/contextkey.test.ts
src/vs/platform/contextkey/test/common/contextkey.test.ts
+4
-2
src/vs/platform/keybinding/common/abstractKeybindingService.ts
...s/platform/keybinding/common/abstractKeybindingService.ts
+3
-3
src/vs/platform/keybinding/common/keybinding.ts
src/vs/platform/keybinding/common/keybinding.ts
+4
-1
src/vs/platform/keybinding/common/keybindingResolver.ts
src/vs/platform/keybinding/common/keybindingResolver.ts
+4
-4
src/vs/platform/keybinding/test/common/abstractKeybindingService.test.ts
.../keybinding/test/common/abstractKeybindingService.test.ts
+18
-16
src/vs/platform/keybinding/test/common/keybindingResolver.test.ts
...latform/keybinding/test/common/keybindingResolver.test.ts
+17
-15
src/vs/platform/keybinding/test/common/mockKeybindingService.ts
.../platform/keybinding/test/common/mockKeybindingService.ts
+4
-4
src/vs/workbench/parts/extensions/browser/extensionEditor.ts
src/vs/workbench/parts/extensions/browser/extensionEditor.ts
+5
-2
src/vs/workbench/parts/preferences/browser/keybindingsEditorContribution.ts
...arts/preferences/browser/keybindingsEditorContribution.ts
+11
-10
src/vs/workbench/parts/search/browser/searchActions.ts
src/vs/workbench/parts/search/browser/searchActions.ts
+7
-4
src/vs/workbench/parts/search/test/browser/searchActions.test.ts
...workbench/parts/search/test/browser/searchActions.test.ts
+1
-1
src/vs/workbench/parts/update/electron-browser/update.ts
src/vs/workbench/parts/update/electron-browser/update.ts
+6
-2
src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts
...services/keybinding/electron-browser/keybindingService.ts
+11
-11
未找到文件。
src/vs/base/common/filters.ts
浏览文件 @
0ebecd5c
...
...
@@ -357,3 +357,110 @@ export function matchesFuzzy(word: string, wordToMatchAgainst: string, enableSep
// Default Filter
return
enableSeparateSubstringMatching
?
fuzzySeparateFilter
(
word
,
wordToMatchAgainst
)
:
fuzzyContiguousFilter
(
word
,
wordToMatchAgainst
);
}
export
function
matchesFuzzy2
(
pattern
:
string
,
word
:
string
):
number
[]
{
pattern
=
pattern
.
toLowerCase
();
word
=
word
.
toLowerCase
();
let
matches
:
number
[]
=
[];
let
patternPos
=
0
;
let
wordPos
=
0
;
while
(
patternPos
<
pattern
.
length
&&
wordPos
<
word
.
length
)
{
if
(
pattern
[
patternPos
]
===
word
[
wordPos
])
{
patternPos
+=
1
;
matches
.
push
(
wordPos
);
}
wordPos
+=
1
;
}
if
(
patternPos
!==
pattern
.
length
)
{
return
undefined
;
}
return
matches
;
}
export
function
createMatches
(
position
:
number
[]):
IMatch
[]
{
let
ret
:
IMatch
[]
=
[];
let
last
:
IMatch
;
for
(
const
pos
of
position
)
{
if
(
last
&&
last
.
end
===
pos
)
{
last
.
end
+=
1
;
}
else
{
last
=
{
start
:
pos
,
end
:
pos
+
1
};
ret
.
push
(
last
);
}
}
return
ret
;
}
export
function
fuzzyMatchAndScore
(
pattern
:
string
,
word
:
string
):
[
number
,
number
[]]
{
if
(
!
pattern
)
{
return
[
-
1
,
[]];
}
let
matches
:
number
[]
=
[];
let
score
=
_matchRecursive
(
pattern
,
pattern
.
toLowerCase
(),
pattern
.
toUpperCase
(),
0
,
word
,
word
.
toLowerCase
(),
0
,
matches
);
if
(
score
<=
0
)
{
return
undefined
;
}
score
-=
Math
.
min
(
matches
[
0
],
3
)
*
3
;
// penalty for first matching character
score
-=
(
1
+
matches
[
matches
.
length
-
1
])
-
(
pattern
.
length
);
// penalty for all non matching characters between first and last
return
[
score
,
matches
];
}
export
function
_matchRecursive
(
pattern
:
string
,
lowPattern
:
string
,
upPattern
:
string
,
patternPos
:
number
,
word
:
string
,
lowWord
:
string
,
wordPos
:
number
,
matches
:
number
[]
):
number
{
if
(
patternPos
>=
lowPattern
.
length
)
{
return
0
;
}
const
lowPatternChar
=
lowPattern
[
patternPos
];
let
idx
=
-
1
;
let
value
=
0
;
if
((
patternPos
===
wordPos
&&
lowPatternChar
===
lowWord
[
wordPos
])
&&
((
value
=
_matchRecursive
(
pattern
,
lowPattern
,
upPattern
,
patternPos
+
1
,
word
,
lowWord
,
wordPos
+
1
,
matches
))
>=
0
)
)
{
matches
.
unshift
(
wordPos
);
return
(
pattern
[
patternPos
]
===
word
[
wordPos
]
?
17
:
11
)
+
value
;
}
if
((
idx
=
lowWord
.
indexOf
(
`_
${
lowPatternChar
}
`
,
wordPos
))
>=
0
&&
((
value
=
_matchRecursive
(
pattern
,
lowPattern
,
upPattern
,
patternPos
+
1
,
word
,
lowWord
,
idx
+
2
,
matches
))
>=
0
)
)
{
matches
.
unshift
(
idx
+
1
);
return
(
pattern
[
patternPos
]
===
word
[
idx
+
1
]
?
17
:
11
)
+
value
;
}
if
((
idx
=
word
.
indexOf
(
upPattern
[
patternPos
],
wordPos
))
>=
0
&&
((
value
=
_matchRecursive
(
pattern
,
lowPattern
,
upPattern
,
patternPos
+
1
,
word
,
lowWord
,
idx
+
1
,
matches
))
>=
0
)
)
{
matches
.
unshift
(
idx
);
return
(
pattern
[
patternPos
]
===
word
[
idx
]
?
17
:
11
)
+
value
;
}
if
(
patternPos
>
0
&&
(
idx
=
lowWord
.
indexOf
(
lowPatternChar
,
wordPos
))
>=
0
&&
((
value
=
_matchRecursive
(
pattern
,
lowPattern
,
upPattern
,
patternPos
+
1
,
word
,
lowWord
,
idx
+
1
,
matches
))
>=
0
)
)
{
matches
.
unshift
(
idx
);
return
1
+
value
;
}
return
-
1
;
}
src/vs/base/test/common/filters.perf.data.json
0 → 100644
浏览文件 @
0ebecd5c
因为 它太大了无法显示 source diff 。你可以改为
查看blob
。
src/vs/base/test/common/filters.perf.test.ts
0 → 100644
浏览文件 @
0ebecd5c
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
// import * as assert from 'assert';
import
*
as
filters
from
'
vs/base/common/filters
'
;
const
data
=
<
string
[]
>
require
.
__$__nodeRequire
(
require
.
toUrl
(
'
./filters.perf.data.json
'
));
const
patterns
=
[
'
cci
'
,
'
ida
'
,
'
pos
'
,
'
CCI
'
,
'
enbled
'
,
'
callback
'
,
'
gGame
'
,
'
cons
'
];
const
_enablePerf
=
false
;
function
perfSuite
(
name
:
string
,
callback
:
(
this
:
Mocha
.
ISuiteCallbackContext
)
=>
void
)
{
if
(
_enablePerf
)
{
suite
(
name
,
callback
);
}
}
perfSuite
(
'
Performance - fuzzyMatch
'
,
function
()
{
console
.
log
(
`Matching
${
data
.
length
}
items against
${
patterns
.
length
}
patterns...`
);
function
perfTest
(
name
:
string
,
match
:
(
pattern
:
string
,
word
:
string
)
=>
any
)
{
test
(
name
,
function
()
{
const
t1
=
Date
.
now
();
let
count
=
0
;
for
(
const
pattern
of
patterns
)
{
for
(
const
item
of
data
)
{
count
+=
1
;
match
(
pattern
,
item
);
}
}
console
.
log
(
name
,
Date
.
now
()
-
t1
,
`
${(
count
/
(
Date
.
now
()
-
t1
)).
toPrecision
(
6
)}
/ms`
);
});
}
perfTest
(
'
matchesFuzzy
'
,
filters
.
matchesFuzzy
);
perfTest
(
'
fuzzyContiguousFilter
'
,
filters
.
fuzzyContiguousFilter
);
perfTest
(
'
matchesFuzzy2
'
,
filters
.
matchesFuzzy2
);
perfTest
(
'
fuzzyMatchAndScore
'
,
filters
.
fuzzyMatchAndScore
);
});
src/vs/base/test/common/filters.test.ts
浏览文件 @
0ebecd5c
...
...
@@ -5,7 +5,7 @@
'
use strict
'
;
import
*
as
assert
from
'
assert
'
;
import
{
IFilter
,
or
,
matchesPrefix
,
matchesStrictPrefix
,
matchesCamelCase
,
matchesSubString
,
matchesContiguousSubString
,
matchesWords
}
from
'
vs/base/common/filters
'
;
import
{
IFilter
,
or
,
matchesPrefix
,
matchesStrictPrefix
,
matchesCamelCase
,
matchesSubString
,
matchesContiguousSubString
,
matchesWords
,
fuzzyMatchAndScore
}
from
'
vs/base/common/filters
'
;
function
filterOk
(
filter
:
IFilter
,
word
:
string
,
wordToMatchAgainst
:
string
,
highlights
?:
{
start
:
number
;
end
:
number
;
}[])
{
let
r
=
filter
(
word
,
wordToMatchAgainst
);
...
...
@@ -192,4 +192,99 @@ suite('Filters', () => {
assert
.
ok
(
matchesWords
(
'
gipu
'
,
'
Category: Git: Pull
'
,
true
)
===
null
);
assert
.
deepEqual
(
matchesWords
(
'
pu
'
,
'
Category: Git: Pull
'
,
true
),
[{
start
:
15
,
end
:
17
}]);
});
test
(
'
fuzzyMatchAndScore
'
,
function
()
{
function
assertMatches
(
pattern
:
string
,
word
:
string
,
decoratedWord
:
string
,
filter
:
typeof
fuzzyMatchAndScore
)
{
let
r
=
filter
(
pattern
,
word
);
assert
.
ok
(
Boolean
(
r
)
===
Boolean
(
decoratedWord
));
if
(
r
)
{
const
[,
matches
]
=
r
;
let
pos
=
0
;
for
(
let
i
=
0
;
i
<
matches
.
length
;
i
++
)
{
let
actual
=
matches
[
i
];
let
expected
=
decoratedWord
.
indexOf
(
'
^
'
,
pos
)
-
i
;
assert
.
equal
(
actual
,
expected
);
pos
=
expected
+
1
+
i
;
}
}
}
assertMatches
(
'
no
'
,
'
match
'
,
undefined
,
fuzzyMatchAndScore
);
assertMatches
(
'
no
'
,
''
,
undefined
,
fuzzyMatchAndScore
);
assertMatches
(
'
BK
'
,
'
the_black_knight
'
,
'
the_^black_^knight
'
,
fuzzyMatchAndScore
);
assertMatches
(
'
bkn
'
,
'
the_black_knight
'
,
'
the_^black_^k^night
'
,
fuzzyMatchAndScore
);
assertMatches
(
'
bt
'
,
'
the_black_knight
'
,
'
the_^black_knigh^t
'
,
fuzzyMatchAndScore
);
assertMatches
(
'
bti
'
,
'
the_black_knight
'
,
undefined
,
fuzzyMatchAndScore
);
assertMatches
(
'
LLL
'
,
'
SVisualLoggerLogsList
'
,
'
SVisual^Logger^Logs^List
'
,
fuzzyMatchAndScore
);
assertMatches
(
'
LLLL
'
,
'
SVisualLoggerLogsList
'
,
undefined
,
fuzzyMatchAndScore
);
assertMatches
(
'
sllll
'
,
'
SVisualLoggerLogsList
'
,
'
^SVisua^l^Logger^Logs^List
'
,
fuzzyMatchAndScore
);
assertMatches
(
'
sl
'
,
'
SVisualLoggerLogsList
'
,
'
^SVisual^LoggerLogsList
'
,
fuzzyMatchAndScore
);
assertMatches
(
'
foobar
'
,
'
foobar
'
,
'
^f^o^o^b^a^r
'
,
fuzzyMatchAndScore
);
assertMatches
(
'
fob
'
,
'
foobar
'
,
'
^f^oo^bar
'
,
fuzzyMatchAndScore
);
assertMatches
(
'
ob
'
,
'
foobar
'
,
undefined
,
fuzzyMatchAndScore
);
assertMatches
(
'
gp
'
,
'
Git: Pull
'
,
'
^Git: ^Pull
'
,
fuzzyMatchAndScore
);
assertMatches
(
'
gp
'
,
'
Git_Git_Pull
'
,
'
^Git_Git_^Pull
'
,
fuzzyMatchAndScore
);
assertMatches
(
'
g p
'
,
'
Git: Pull
'
,
'
^Git:^ ^Pull
'
,
fuzzyMatchAndScore
);
assertMatches
(
'
gip
'
,
'
Git: Pull
'
,
'
^G^it: ^Pull
'
,
fuzzyMatchAndScore
);
assertMatches
(
'
is
'
,
'
isValid
'
,
'
^i^sValid
'
,
fuzzyMatchAndScore
);
assertMatches
(
'
is
'
,
'
ImportStatement
'
,
'
^Import^Statement
'
,
fuzzyMatchAndScore
);
assertMatches
(
'
lowrd
'
,
'
lowWord
'
,
'
^l^o^wWo^r^d
'
,
fuzzyMatchAndScore
);
assertMatches
(
'
ccm
'
,
'
cacmelCase
'
,
'
^ca^c^melCase
'
,
fuzzyMatchAndScore
);
assertMatches
(
'
ccm
'
,
'
camelCase
'
,
undefined
,
fuzzyMatchAndScore
);
assertMatches
(
'
ccm
'
,
'
camelCasecm
'
,
'
^camel^Casec^m
'
,
fuzzyMatchAndScore
);
assertMatches
(
'
myvable
'
,
'
myvariable
'
,
'
^m^y^v^aria^b^l^e
'
,
fuzzyMatchAndScore
);
assertMatches
(
'
fdm
'
,
'
findModel
'
,
'
^fin^d^Model
'
,
fuzzyMatchAndScore
);
});
test
(
'
topScore
'
,
function
()
{
function
assertTopScore
(
pattern
:
string
,
expected
:
number
,
...
words
:
string
[])
{
let
topScore
=
Number
.
MIN_VALUE
;
let
topIdx
=
0
;
for
(
let
i
=
0
;
i
<
words
.
length
;
i
++
)
{
const
word
=
words
[
i
];
const
m
=
fuzzyMatchAndScore
(
pattern
,
word
);
if
(
m
)
{
const
[
score
]
=
m
;
if
(
score
>
topScore
)
{
topScore
=
score
;
topIdx
=
i
;
}
}
}
assert
.
equal
(
topIdx
,
expected
);
}
assertTopScore
(
'
cons
'
,
2
,
'
ArrayBufferConstructor
'
,
'
Console
'
,
'
console
'
);
assertTopScore
(
'
Foo
'
,
1
,
'
foo
'
,
'
Foo
'
,
'
foo
'
);
assertTopScore
(
'
CC
'
,
1
,
'
camelCase
'
,
'
CamelCase
'
);
assertTopScore
(
'
cC
'
,
0
,
'
camelCase
'
,
'
CamelCase
'
);
assertTopScore
(
'
cC
'
,
1
,
'
ccfoo
'
,
'
camelCase
'
);
assertTopScore
(
'
cC
'
,
1
,
'
ccfoo
'
,
'
camelCase
'
,
'
foo-cC-bar
'
);
// issue #17836
assertTopScore
(
'
p
'
,
0
,
'
parse
'
,
'
posix
'
,
'
pafdsa
'
,
'
path
'
,
'
p
'
);
assertTopScore
(
'
pa
'
,
0
,
'
parse
'
,
'
pafdsa
'
,
'
path
'
);
// issue #14583
assertTopScore
(
'
log
'
,
3
,
'
HTMLOptGroupElement
'
,
'
ScrollLogicalPosition
'
,
'
SVGFEMorphologyElement
'
,
'
log
'
);
assertTopScore
(
'
e
'
,
2
,
'
AbstractWorker
'
,
'
ActiveXObject
'
,
'
else
'
);
// issue #14446
assertTopScore
(
'
workbench.sideb
'
,
1
,
'
workbench.editor.defaultSideBySideLayout
'
,
'
workbench.sideBar.location
'
);
// issue #11423
assertTopScore
(
'
editor.r
'
,
2
,
'
diffEditor.renderSideBySide
'
,
'
editor.overviewRulerlanes
'
,
'
editor.renderControlCharacter
'
,
'
editor.renderWhitespace
'
);
// assertTopScore('editor.R', 1, 'diffEditor.renderSideBySide', 'editor.overviewRulerlanes', 'editor.renderControlCharacter', 'editor.renderWhitespace');
// assertTopScore('Editor.r', 0, 'diffEditor.renderSideBySide', 'editor.overviewRulerlanes', 'editor.renderControlCharacter', 'editor.renderWhitespace');
assertTopScore
(
'
-mo
'
,
1
,
'
-ms-ime-mode
'
,
'
-moz-columns
'
);
// // dupe, issue #14861
assertTopScore
(
'
convertModelPosition
'
,
0
,
'
convertModelPositionToViewPosition
'
,
'
convertViewToModelPosition
'
);
// // dupe, issue #14942
assertTopScore
(
'
is
'
,
0
,
'
isValidViewletId
'
,
'
import statement
'
);
});
});
src/vs/editor/browser/standalone/simpleServices.ts
浏览文件 @
0ebecd5c
...
...
@@ -387,16 +387,23 @@ export class StandaloneKeybindingService extends AbstractKeybindingService {
const
item
=
items
[
i
];
const
when
=
(
item
.
when
?
item
.
when
.
normalize
()
:
null
);
const
keybinding
=
item
.
keybinding
;
const
resolvedKeybinding
=
(
keybinding
?
this
.
resolveKeybinding
(
keybinding
)
:
null
);
result
[
resultLen
++
]
=
new
ResolvedKeybindingItem
(
resolvedKeybinding
,
item
.
command
,
item
.
commandArgs
,
when
,
isDefault
);
if
(
!
keybinding
)
{
// This might be a removal keybinding item in user settings => accept it
result
[
resultLen
++
]
=
new
ResolvedKeybindingItem
(
null
,
item
.
command
,
item
.
commandArgs
,
when
,
isDefault
);
}
else
{
const
resolvedKeybindings
=
this
.
resolveKeybinding
(
keybinding
);
for
(
let
j
=
0
;
j
<
resolvedKeybindings
.
length
;
j
++
)
{
result
[
resultLen
++
]
=
new
ResolvedKeybindingItem
(
resolvedKeybindings
[
j
],
item
.
command
,
item
.
commandArgs
,
when
,
isDefault
);
}
}
}
return
result
;
}
public
resolveKeybinding
(
kb
:
Keybinding
):
ResolvedKeybinding
{
return
new
USLayoutResolvedKeybinding
(
kb
,
OS
)
;
public
resolveKeybinding
(
kb
:
Keybinding
):
ResolvedKeybinding
[]
{
return
[
new
USLayoutResolvedKeybinding
(
kb
,
OS
)]
;
}
public
resolveKeyboardEvent
(
keyboardEvent
:
IKeyboardEvent
):
ResolvedKeybinding
{
...
...
@@ -407,7 +414,7 @@ export class StandaloneKeybindingService extends AbstractKeybindingService {
keyboardEvent
.
metaKey
,
keyboardEvent
.
keyCode
);
return
this
.
resolveKeybinding
(
keybinding
);
return
this
.
resolveKeybinding
(
keybinding
)
[
0
]
;
}
}
...
...
src/vs/editor/contrib/suggest/browser/suggestWidget.ts
浏览文件 @
0ebecd5c
...
...
@@ -7,6 +7,7 @@
import
'
vs/css!./suggest
'
;
import
*
as
nls
from
'
vs/nls
'
;
import
{
createMatches
}
from
'
vs/base/common/filters
'
;
import
*
as
strings
from
'
vs/base/common/strings
'
;
import
Event
,
{
Emitter
,
chain
}
from
'
vs/base/common/event
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
...
...
@@ -136,7 +137,7 @@ class Renderer implements IRenderer<ICompletionItem, ISuggestionTemplateData> {
}
}
data
.
highlightedLabel
.
set
(
suggestion
.
label
,
element
.
highlights
);
data
.
highlightedLabel
.
set
(
suggestion
.
label
,
createMatches
(
element
.
matches
)
);
data
.
typeLabel
.
textContent
=
(
suggestion
.
detail
||
''
).
replace
(
/
\n
.*$/m
,
''
);
data
.
documentation
.
textContent
=
suggestion
.
documentation
||
''
;
...
...
@@ -234,7 +235,7 @@ class SuggestionDetails {
return
;
}
this
.
titleLabel
.
set
(
item
.
suggestion
.
label
,
item
.
highlights
);
this
.
titleLabel
.
set
(
item
.
suggestion
.
label
,
createMatches
(
item
.
matches
)
);
this
.
type
.
innerText
=
item
.
suggestion
.
detail
||
''
;
this
.
docs
.
textContent
=
item
.
suggestion
.
documentation
;
this
.
back
.
onmousedown
=
e
=>
{
...
...
src/vs/editor/contrib/suggest/common/completionModel.ts
浏览文件 @
0ebecd5c
...
...
@@ -5,14 +5,13 @@
'
use strict
'
;
import
{
isFalsyOrEmpty
}
from
'
vs/base/common/arrays
'
;
import
{
indexOfIgnoreCase
}
from
'
vs/base/common/strings
'
;
import
{
IMatch
,
fuzzyContiguousFilter
}
from
'
vs/base/common/filters
'
;
import
{
fuzzyMatchAndScore
}
from
'
vs/base/common/filters
'
;
import
{
ISuggestSupport
}
from
'
vs/editor/common/modes
'
;
import
{
ISuggestionItem
}
from
'
./suggest
'
;
export
interface
ICompletionItem
extends
ISuggestionItem
{
highlights
?:
IMatch
[];
matches
?:
number
[];
score
?:
number
;
}
export
interface
ICompletionStats
{
...
...
@@ -100,17 +99,17 @@ export class CompletionModel {
private
_createCachedState
():
void
{
this
.
_filteredItems
=
[];
this
.
_topScoreIdx
=
-
1
;
this
.
_topScoreIdx
=
0
;
this
.
_isIncomplete
=
false
;
this
.
_stats
=
{
suggestionCount
:
0
,
snippetCount
:
0
,
textCount
:
0
};
const
{
leadingLineContent
,
characterCountDelta
}
=
this
.
_lineContext
;
const
{
leadingLineContent
,
characterCountDelta
}
=
this
.
_lineContext
;
let
word
=
''
;
let
topScore
=
-
1
;
let
topScore
=
Number
.
MIN_VALUE
;
for
(
const
item
of
this
.
_items
)
{
const
{
suggestion
,
container
}
=
item
;
const
{
suggestion
,
container
}
=
item
;
// collect those supports that signaled having
// an incomplete result
...
...
@@ -124,36 +123,32 @@ export class CompletionModel {
word
=
wordLen
===
0
?
''
:
leadingLineContent
.
slice
(
-
wordLen
);
}
let
match
=
false
;
// compute highlights based on 'label'
item
.
highlights
=
fuzzyContiguousFilter
(
word
,
suggestion
.
label
);
match
=
item
.
highlights
!==
null
;
// no match on label nor codeSnippet -> check on filterText
if
(
!
match
&&
typeof
suggestion
.
filterText
===
'
string
'
)
{
if
(
!
isFalsyOrEmpty
(
fuzzyContiguousFilter
(
word
,
suggestion
.
filterText
)))
{
match
=
true
;
// try to compute highlights by stripping none-word
// characters from the end of the string
item
.
highlights
=
fuzzyContiguousFilter
(
word
.
replace
(
/^
\W
+|
\W
+$/
,
''
),
suggestion
.
label
);
let
match
=
fuzzyMatchAndScore
(
word
,
suggestion
.
label
);
if
(
!
match
)
{
if
(
typeof
suggestion
.
filterText
===
'
string
'
)
{
match
=
fuzzyMatchAndScore
(
word
,
suggestion
.
filterText
);
}
else
{
continue
;
}
if
(
match
)
{
match
=
fuzzyMatchAndScore
(
word
.
replace
(
/^
\W
+|
\W
+$/
,
''
),
suggestion
.
label
);
}
else
{
continue
;
}
}
if
(
!
match
)
{
continue
;
if
(
match
)
{
item
.
score
=
match
[
0
];
item
.
matches
=
match
[
1
];
if
(
item
.
score
>
topScore
)
{
topScore
=
item
.
score
;
this
.
_topScoreIdx
=
this
.
_filteredItems
.
length
;
}
}
this
.
_filteredItems
.
push
(
item
);
// compute score against word
const
score
=
CompletionModel
.
_scoreByHighlight
(
item
,
word
);
if
(
score
>
topScore
)
{
topScore
=
score
;
this
.
_topScoreIdx
=
this
.
_filteredItems
.
length
-
1
;
}
// update stats
this
.
_stats
.
suggestionCount
++
;
switch
(
suggestion
.
type
)
{
...
...
@@ -162,63 +157,4 @@ export class CompletionModel {
}
}
}
private
static
_base
=
100
;
private
static
_scoreByHighlight
(
item
:
ICompletionItem
,
currentWord
:
string
):
number
{
const
{
highlights
,
suggestion
}
=
item
;
if
(
isFalsyOrEmpty
(
highlights
))
{
return
0
;
}
let
caseSensitiveMatches
=
0
;
let
caseInsensitiveMatches
=
0
;
let
firstMatchStart
=
0
;
const
len
=
Math
.
min
(
CompletionModel
.
_base
,
suggestion
.
label
.
length
);
let
currentWordOffset
=
0
;
for
(
let
pos
=
0
,
idx
=
0
;
pos
<
len
;
pos
++
)
{
const
highlight
=
highlights
[
idx
];
if
(
pos
===
highlight
.
start
)
{
// reached a highlight: find highlighted part
// and count case-sensitive /case-insensitive matches
const
part
=
suggestion
.
label
.
substring
(
highlight
.
start
,
highlight
.
end
);
currentWordOffset
=
indexOfIgnoreCase
(
currentWord
,
part
,
currentWordOffset
);
if
(
currentWordOffset
>=
0
)
{
do
{
if
(
suggestion
.
label
[
pos
]
===
currentWord
[
currentWordOffset
])
{
caseSensitiveMatches
+=
1
;
}
else
{
caseInsensitiveMatches
+=
1
;
}
pos
+=
1
;
currentWordOffset
+=
1
;
}
while
(
pos
<
highlight
.
end
);
}
// proceed with next highlight, store first start,
// exit loop when no highlight is available
if
(
idx
===
0
)
{
firstMatchStart
=
highlight
.
start
;
}
idx
+=
1
;
if
(
idx
>=
highlights
.
length
)
{
break
;
}
}
}
// combine the 4 scoring values into one
// value using base_100. Values further left
// are more important
return
(
CompletionModel
.
_base
**
3
)
*
caseSensitiveMatches
+
(
CompletionModel
.
_base
**
2
)
*
caseInsensitiveMatches
+
(
CompletionModel
.
_base
**
1
)
*
(
CompletionModel
.
_base
-
firstMatchStart
)
+
(
CompletionModel
.
_base
**
0
)
*
(
CompletionModel
.
_base
-
highlights
.
length
);
}
}
src/vs/editor/contrib/suggest/test/common/completionModel.test.ts
浏览文件 @
0ebecd5c
...
...
@@ -93,7 +93,7 @@ suite('CompletionModel', function () {
const
completeItem
=
createSuggestItem
(
'
foobar
'
,
1
,
false
,
{
lineNumber
:
1
,
column
:
2
});
const
incompleteItem
=
createSuggestItem
(
'
foofoo
'
,
1
,
true
,
{
lineNumber
:
1
,
column
:
2
});
const
model
=
new
CompletionModel
([
completeItem
,
incompleteItem
],
2
,
{
leadingLineContent
:
'
foo
'
,
characterCountDelta
:
0
});
const
model
=
new
CompletionModel
([
completeItem
,
incompleteItem
],
2
,
{
leadingLineContent
:
''
,
characterCountDelta
:
0
});
assert
.
equal
(
model
.
incomplete
,
true
);
assert
.
equal
(
model
.
items
.
length
,
2
);
...
...
@@ -134,16 +134,16 @@ suite('CompletionModel', function () {
assertTopScore
(
'
pa
'
,
0
,
'
parse
'
,
'
posix
'
,
'
sep
'
,
'
pafdsa
'
,
'
path
'
,
'
p
'
);
// issue #14583
assertTopScore
(
'
log
'
,
3
,
'
HTMLOptGroupElement
'
,
'
ScrollLogicalPosition
'
,
'
SVGFEMorphologyElement
'
,
'
log
'
);
assertTopScore
(
'
e
'
,
2
,
'
Abstract
Worker
'
,
'
Activ
eXObject
'
,
'
else
'
);
assertTopScore
(
'
log
'
,
2
,
'
HTMLOptGroupElement
'
,
'
ScrollLogicalPosition
'
,
'
log
'
);
assertTopScore
(
'
e
'
,
2
,
'
Abstract
Eorker
'
,
'
Activ_
eXObject
'
,
'
else
'
);
// issue #14446
assertTopScore
(
'
workbench.sideb
'
,
1
,
'
workbench.editor.defaultSideBySideLayout
'
,
'
workbench.sideBar.location
'
);
// issue #11423
assertTopScore
(
'
editor.r
'
,
2
,
'
diffEditor.renderSideBySide
'
,
'
editor.overviewRulerlanes
'
,
'
editor.renderControlCharacter
'
,
'
editor.renderWhitespace
'
);
assertTopScore
(
'
editor.R
'
,
1
,
'
diffEditor.renderSideBySide
'
,
'
editor.overviewRulerlanes
'
,
'
editor.renderControlCharacter
'
,
'
editor.renderWhitespace
'
);
assertTopScore
(
'
Editor.r
'
,
0
,
'
diffEditor.renderSideBySide
'
,
'
editor.overviewRulerlanes
'
,
'
editor.renderControlCharacter
'
,
'
editor.renderWhitespace
'
);
//
assertTopScore('editor.R', 1, 'diffEditor.renderSideBySide', 'editor.overviewRulerlanes', 'editor.renderControlCharacter', 'editor.renderWhitespace');
//
assertTopScore('Editor.r', 0, 'diffEditor.renderSideBySide', 'editor.overviewRulerlanes', 'editor.renderControlCharacter', 'editor.renderWhitespace');
assertTopScore
(
'
-mo
'
,
1
,
'
-ms-ime-mode
'
,
'
-moz-columns
'
);
// dupe, issue #14861
...
...
src/vs/platform/contextkey/browser/contextKeyService.ts
浏览文件 @
0ebecd5c
...
...
@@ -7,18 +7,19 @@
import
{
IDisposable
,
dispose
}
from
'
vs/base/common/lifecycle
'
;
import
{
CommandsRegistry
}
from
'
vs/platform/commands/common/commands
'
;
import
{
KeybindingResolver
}
from
'
vs/platform/keybinding/common/keybindingResolver
'
;
import
{
IContextKey
,
IContextKeyServiceTarget
,
IContextKeyService
,
SET_CONTEXT_COMMAND_ID
,
ContextKeyExpr
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
IContextKey
,
IContext
,
IContext
KeyServiceTarget
,
IContextKeyService
,
SET_CONTEXT_COMMAND_ID
,
ContextKeyExpr
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
IConfigurationService
}
from
'
vs/platform/configuration/common/configuration
'
;
import
Event
,
{
Emitter
,
debounceEvent
}
from
'
vs/base/common/event
'
;
const
KEYBINDING_CONTEXT_ATTR
=
'
data-keybinding-context
'
;
export
class
ContextValuesContainer
{
protected
_parent
:
ContextValuesContainer
;
export
class
Context
implements
IContext
{
protected
_parent
:
Context
;
protected
_value
:
{
[
key
:
string
]:
any
;
};
protected
_id
:
number
;
constructor
(
id
:
number
,
parent
:
Context
ValuesContainer
)
{
constructor
(
id
:
number
,
parent
:
Context
)
{
this
.
_id
=
id
;
this
.
_parent
=
parent
;
this
.
_value
=
Object
.
create
(
null
);
...
...
@@ -46,18 +47,9 @@ export class ContextValuesContainer {
}
return
ret
;
}
public
fillInContext
(
bucket
:
any
):
void
{
if
(
this
.
_parent
)
{
this
.
_parent
.
fillInContext
(
bucket
);
}
for
(
let
key
in
this
.
_value
)
{
bucket
[
key
]
=
this
.
_value
[
key
];
}
}
}
class
ConfigAwareContextValuesContainer
extends
Context
ValuesContainer
{
class
ConfigAwareContextValuesContainer
extends
Context
{
private
_emitter
:
Emitter
<
string
>
;
private
_subscription
:
IDisposable
;
...
...
@@ -169,9 +161,8 @@ export abstract class AbstractContextKeyService {
}
public
contextMatchesRules
(
rules
:
ContextKeyExpr
):
boolean
{
const
ctx
=
Object
.
create
(
null
);
this
.
getContextValuesContainer
(
this
.
_myContextId
).
fillInContext
(
ctx
);
const
result
=
KeybindingResolver
.
contextMatchesRules
(
ctx
,
rules
);
const
context
=
this
.
getContextValuesContainer
(
this
.
_myContextId
);
const
result
=
KeybindingResolver
.
contextMatchesRules
(
context
,
rules
);
// console.group(rules.serialize() + ' -> ' + result);
// rules.keys().forEach(key => { console.log(key, ctx[key]); });
// console.groupEnd();
...
...
@@ -194,13 +185,11 @@ export abstract class AbstractContextKeyService {
}
}
public
getContextValue
(
target
:
IContextKeyServiceTarget
):
any
{
let
res
=
Object
.
create
(
null
);
this
.
getContextValuesContainer
(
findContextAttr
(
target
)).
fillInContext
(
res
);
return
res
;
public
getContext
(
target
:
IContextKeyServiceTarget
):
IContext
{
return
this
.
getContextValuesContainer
(
findContextAttr
(
target
));
}
public
abstract
getContextValuesContainer
(
contextId
:
number
):
Context
ValuesContainer
;
public
abstract
getContextValuesContainer
(
contextId
:
number
):
Context
;
public
abstract
createChildContext
(
parentContextId
?:
number
):
number
;
public
abstract
disposeContext
(
contextId
:
number
):
void
;
}
...
...
@@ -209,7 +198,7 @@ export class ContextKeyService extends AbstractContextKeyService implements ICon
private
_lastContextId
:
number
;
private
_contexts
:
{
[
contextId
:
string
]:
Context
ValuesContainer
;
[
contextId
:
string
]:
Context
;
};
private
_toDispose
:
IDisposable
[]
=
[];
...
...
@@ -239,13 +228,13 @@ export class ContextKeyService extends AbstractContextKeyService implements ICon
this
.
_toDispose
=
dispose
(
this
.
_toDispose
);
}
public
getContextValuesContainer
(
contextId
:
number
):
Context
ValuesContainer
{
public
getContextValuesContainer
(
contextId
:
number
):
Context
{
return
this
.
_contexts
[
String
(
contextId
)];
}
public
createChildContext
(
parentContextId
:
number
=
this
.
_myContextId
):
number
{
let
id
=
(
++
this
.
_lastContextId
);
this
.
_contexts
[
String
(
id
)]
=
new
Context
ValuesContainer
(
id
,
this
.
getContextValuesContainer
(
parentContextId
));
this
.
_contexts
[
String
(
id
)]
=
new
Context
(
id
,
this
.
getContextValuesContainer
(
parentContextId
));
return
id
;
}
...
...
@@ -281,7 +270,7 @@ class ScopedContextKeyService extends AbstractContextKeyService {
return
this
.
_parent
.
onDidChangeContext
;
}
public
getContextValuesContainer
(
contextId
:
number
):
Context
ValuesContainer
{
public
getContextValuesContainer
(
contextId
:
number
):
Context
{
return
this
.
_parent
.
getContextValuesContainer
(
contextId
);
}
...
...
src/vs/platform/contextkey/common/contextkey.ts
浏览文件 @
0ebecd5c
...
...
@@ -88,7 +88,7 @@ export abstract class ContextKeyExpr {
public
abstract
getType
():
ContextKeyExprType
;
public
abstract
equals
(
other
:
ContextKeyExpr
):
boolean
;
public
abstract
evaluate
(
context
:
any
):
boolean
;
public
abstract
evaluate
(
context
:
IContext
):
boolean
;
public
abstract
normalize
():
ContextKeyExpr
;
public
abstract
serialize
():
string
;
public
abstract
keys
():
string
[];
...
...
@@ -139,8 +139,8 @@ export class ContextKeyDefinedExpr implements ContextKeyExpr {
return
false
;
}
public
evaluate
(
context
:
any
):
boolean
{
return
(
!!
context
[
this
.
key
]
);
public
evaluate
(
context
:
IContext
):
boolean
{
return
(
!!
context
.
getValue
(
this
.
key
)
);
}
public
normalize
():
ContextKeyExpr
{
...
...
@@ -187,10 +187,10 @@ export class ContextKeyEqualsExpr implements ContextKeyExpr {
return
false
;
}
public
evaluate
(
context
:
any
):
boolean
{
public
evaluate
(
context
:
IContext
):
boolean
{
/* tslint:disable:triple-equals */
// Intentional ==
return
(
context
[
this
.
key
]
==
this
.
value
);
return
(
context
.
getValue
(
this
.
key
)
==
this
.
value
);
/* tslint:enable:triple-equals */
}
...
...
@@ -248,10 +248,10 @@ export class ContextKeyNotEqualsExpr implements ContextKeyExpr {
return
false
;
}
public
evaluate
(
context
:
any
):
boolean
{
public
evaluate
(
context
:
IContext
):
boolean
{
/* tslint:disable:triple-equals */
// Intentional !=
return
(
context
[
this
.
key
]
!=
this
.
value
);
return
(
context
.
getValue
(
this
.
key
)
!=
this
.
value
);
/* tslint:enable:triple-equals */
}
...
...
@@ -303,8 +303,8 @@ export class ContextKeyNotExpr implements ContextKeyExpr {
return
false
;
}
public
evaluate
(
context
:
any
):
boolean
{
return
(
!
context
[
this
.
key
]
);
public
evaluate
(
context
:
IContext
):
boolean
{
return
(
!
context
.
getValue
(
this
.
key
)
);
}
public
normalize
():
ContextKeyExpr
{
...
...
@@ -346,7 +346,7 @@ export class ContextKeyAndExpr implements ContextKeyExpr {
return
false
;
}
public
evaluate
(
context
:
any
):
boolean
{
public
evaluate
(
context
:
IContext
):
boolean
{
for
(
let
i
=
0
,
len
=
this
.
expr
.
length
;
i
<
len
;
i
++
)
{
if
(
!
this
.
expr
[
i
].
evaluate
(
context
))
{
return
false
;
...
...
@@ -441,6 +441,10 @@ export class RawContextKey<T> extends ContextKeyDefinedExpr {
}
}
export
interface
IContext
{
getValue
<
T
>
(
key
:
string
):
T
;
}
export
interface
IContextKey
<
T
>
{
set
(
value
:
T
):
void
;
reset
():
void
;
...
...
@@ -467,7 +471,7 @@ export interface IContextKeyService {
getContextKeyValue
<
T
>
(
key
:
string
):
T
;
createScoped
(
target
?:
IContextKeyServiceTarget
):
IContextKeyService
;
getContext
Value
(
target
:
IContextKeyServiceTarget
):
any
;
getContext
(
target
:
IContextKeyServiceTarget
):
IContext
;
}
export
const
SET_CONTEXT_COMMAND_ID
=
'
setContext
'
;
src/vs/platform/contextkey/test/common/contextkey.test.ts
浏览文件 @
0ebecd5c
...
...
@@ -7,6 +7,8 @@
import
*
as
assert
from
'
assert
'
;
import
{
ContextKeyExpr
}
from
'
vs/platform/contextkey/common/contextkey
'
;
const
createContext
=
ctx
=>
({
getValue
:
key
=>
ctx
[
key
]
});
suite
(
'
ContextKeyExpr
'
,
()
=>
{
test
(
'
ContextKeyExpr.equals
'
,
function
()
{
let
a
=
ContextKeyExpr
.
and
(
...
...
@@ -48,11 +50,11 @@ suite('ContextKeyExpr', () => {
test
(
'
evaluate
'
,
function
()
{
/* tslint:disable:triple-equals */
let
context
=
{
let
context
=
createContext
(
{
'
a
'
:
true
,
'
b
'
:
false
,
'
c
'
:
'
5
'
};
}
)
;
function
testExpression
(
expr
:
string
,
expected
:
boolean
):
void
{
let
rules
=
ContextKeyExpr
.
deserialize
(
expr
);
assert
.
equal
(
rules
.
evaluate
(
context
),
expected
,
expr
);
...
...
src/vs/platform/keybinding/common/abstractKeybindingService.ts
浏览文件 @
0ebecd5c
...
...
@@ -62,7 +62,7 @@ export abstract class AbstractKeybindingService implements IKeybindingService {
}
protected
abstract
_getResolver
():
KeybindingResolver
;
public
abstract
resolveKeybinding
(
keybinding
:
Keybinding
):
ResolvedKeybinding
;
public
abstract
resolveKeybinding
(
keybinding
:
Keybinding
):
ResolvedKeybinding
[]
;
public
abstract
resolveKeyboardEvent
(
keyboardEvent
:
IKeyboardEvent
):
ResolvedKeybinding
;
public
getDefaultKeybindings
():
string
{
...
...
@@ -101,7 +101,7 @@ export abstract class AbstractKeybindingService implements IKeybindingService {
return
null
;
}
const
contextValue
=
this
.
_contextKeyService
.
getContext
Value
(
target
);
const
contextValue
=
this
.
_contextKeyService
.
getContext
(
target
);
const
currentChord
=
this
.
_currentChord
?
this
.
_currentChord
.
keypress
:
null
;
return
this
.
_getResolver
().
resolve
(
contextValue
,
currentChord
,
firstPart
);
}
...
...
@@ -120,7 +120,7 @@ export abstract class AbstractKeybindingService implements IKeybindingService {
return
shouldPreventDefault
;
}
const
contextValue
=
this
.
_contextKeyService
.
getContext
Value
(
target
);
const
contextValue
=
this
.
_contextKeyService
.
getContext
(
target
);
const
currentChord
=
this
.
_currentChord
?
this
.
_currentChord
.
keypress
:
null
;
const
keypressLabel
=
keybinding
.
getLabel
();
const
resolveResult
=
this
.
_getResolver
().
resolve
(
contextValue
,
currentChord
,
firstPart
);
...
...
src/vs/platform/keybinding/common/keybinding.ts
浏览文件 @
0ebecd5c
...
...
@@ -44,7 +44,10 @@ export interface IKeybindingService {
onDidUpdateKeybindings
:
Event
<
IKeybindingEvent
>
;
resolveKeybinding
(
keybinding
:
Keybinding
):
ResolvedKeybinding
;
/**
* Returns none, one or many (depending on keyboard layout)!
*/
resolveKeybinding
(
keybinding
:
Keybinding
):
ResolvedKeybinding
[];
resolveKeyboardEvent
(
keyboardEvent
:
IKeyboardEvent
):
ResolvedKeybinding
;
...
...
src/vs/platform/keybinding/common/keybindingResolver.ts
浏览文件 @
0ebecd5c
...
...
@@ -5,7 +5,7 @@
'
use strict
'
;
import
{
isFalsyOrEmpty
}
from
'
vs/base/common/arrays
'
;
import
{
ContextKeyExpr
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
ContextKeyExpr
,
IContext
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
ResolvedKeybindingItem
}
from
'
vs/platform/keybinding/common/resolvedKeybindingItem
'
;
import
{
CommandsRegistry
,
ICommandHandlerDescription
}
from
'
vs/platform/commands/common/commands
'
;
...
...
@@ -234,7 +234,7 @@ export class KeybindingResolver {
return
items
[
items
.
length
-
1
];
}
public
resolve
(
context
:
any
,
currentChord
:
string
,
keypress
:
string
):
IResolveResult
{
public
resolve
(
context
:
IContext
,
currentChord
:
string
,
keypress
:
string
):
IResolveResult
{
let
lookupMap
:
ResolvedKeybindingItem
[]
=
null
;
if
(
currentChord
!==
null
)
{
...
...
@@ -285,7 +285,7 @@ export class KeybindingResolver {
};
}
private
_findCommand
(
context
:
any
,
matches
:
ResolvedKeybindingItem
[]):
ResolvedKeybindingItem
{
private
_findCommand
(
context
:
IContext
,
matches
:
ResolvedKeybindingItem
[]):
ResolvedKeybindingItem
{
for
(
let
i
=
matches
.
length
-
1
;
i
>=
0
;
i
--
)
{
let
k
=
matches
[
i
];
...
...
@@ -299,7 +299,7 @@ export class KeybindingResolver {
return
null
;
}
public
static
contextMatchesRules
(
context
:
any
,
rules
:
ContextKeyExpr
):
boolean
{
public
static
contextMatchesRules
(
context
:
IContext
,
rules
:
ContextKeyExpr
):
boolean
{
if
(
!
rules
)
{
return
true
;
}
...
...
src/vs/platform/keybinding/test/common/abstractKeybindingService.test.ts
浏览文件 @
0ebecd5c
...
...
@@ -12,7 +12,7 @@ import { IDisposable } from 'vs/base/common/lifecycle';
import
Severity
from
'
vs/base/common/severity
'
;
import
{
ICommandService
}
from
'
vs/platform/commands/common/commands
'
;
import
{
KeybindingResolver
}
from
'
vs/platform/keybinding/common/keybindingResolver
'
;
import
{
ContextKeyExpr
,
IContextKeyService
,
IContextKeyServiceTarget
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
IContext
,
ContextKeyExpr
,
IContextKeyService
,
IContextKeyServiceTarget
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
IStatusbarService
}
from
'
vs/platform/statusbar/common/statusbar
'
;
import
{
IMessageService
}
from
'
vs/platform/message/common/message
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
...
...
@@ -20,6 +20,8 @@ import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKe
import
{
OS
}
from
'
vs/base/common/platform
'
;
import
{
IKeyboardEvent
}
from
'
vs/platform/keybinding/common/keybinding
'
;
const
createContext
=
ctx
=>
({
getValue
:
key
=>
ctx
[
key
]
});
suite
(
'
AbstractKeybindingService
'
,
()
=>
{
class
TestKeybindingService
extends
AbstractKeybindingService
{
...
...
@@ -40,8 +42,8 @@ suite('AbstractKeybindingService', () => {
return
this
.
_resolver
;
}
public
resolveKeybinding
(
kb
:
Keybinding
):
ResolvedKeybinding
{
return
new
USLayoutResolvedKeybinding
(
kb
,
OS
)
;
public
resolveKeybinding
(
kb
:
Keybinding
):
ResolvedKeybinding
[]
{
return
[
new
USLayoutResolvedKeybinding
(
kb
,
OS
)]
;
}
public
resolveKeyboardEvent
(
keyboardEvent
:
IKeyboardEvent
):
ResolvedKeybinding
{
...
...
@@ -52,7 +54,7 @@ suite('AbstractKeybindingService', () => {
keyboardEvent
.
metaKey
,
keyboardEvent
.
keyCode
);
return
this
.
resolveKeybinding
(
keybinding
);
return
this
.
resolveKeybinding
(
keybinding
)
[
0
]
;
}
public
testDispatch
(
kb
:
number
):
boolean
{
...
...
@@ -69,7 +71,7 @@ suite('AbstractKeybindingService', () => {
}
let
createTestKeybindingService
:
(
items
:
ResolvedKeybindingItem
[],
contextValue
?:
any
)
=>
TestKeybindingService
=
null
;
let
currentContextValue
:
any
=
null
;
let
currentContextValue
:
IContext
=
null
;
let
executeCommandCalls
:
{
commandId
:
string
;
args
:
any
[];
}[]
=
null
;
let
showMessageCalls
:
{
sev
:
Severity
,
message
:
any
;
}[]
=
null
;
let
statusMessageCalls
:
string
[]
=
null
;
...
...
@@ -91,7 +93,7 @@ suite('AbstractKeybindingService', () => {
contextMatchesRules
:
undefined
,
getContextKeyValue
:
undefined
,
createScoped
:
undefined
,
getContext
Value
:
(
target
:
IContextKeyServiceTarget
):
any
=>
{
getContext
:
(
target
:
IContextKeyServiceTarget
):
any
=>
{
return
currentContextValue
;
}
};
...
...
@@ -269,9 +271,9 @@ suite('AbstractKeybindingService', () => {
// send Ctrl/Cmd + K
currentContextValue
=
{
currentContextValue
=
createContext
(
{
key1
:
true
};
}
)
;
let
shouldPreventDefault
=
kbService
.
testDispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
);
assert
.
equal
(
shouldPreventDefault
,
true
);
assert
.
deepEqual
(
executeCommandCalls
,
[{
...
...
@@ -287,7 +289,7 @@ suite('AbstractKeybindingService', () => {
statusMessageCallsDisposed
=
[];
// send Ctrl/Cmd + K
currentContextValue
=
{}
;
currentContextValue
=
createContext
({})
;
shouldPreventDefault
=
kbService
.
testDispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
);
assert
.
equal
(
shouldPreventDefault
,
true
);
assert
.
deepEqual
(
executeCommandCalls
,
[]);
...
...
@@ -302,7 +304,7 @@ suite('AbstractKeybindingService', () => {
statusMessageCallsDisposed
=
[];
// send Ctrl/Cmd + X
currentContextValue
=
{}
;
currentContextValue
=
createContext
({})
;
shouldPreventDefault
=
kbService
.
testDispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_X
);
assert
.
equal
(
shouldPreventDefault
,
true
);
assert
.
deepEqual
(
executeCommandCalls
,
[{
...
...
@@ -331,7 +333,7 @@ suite('AbstractKeybindingService', () => {
// send Ctrl/Cmd + K
currentContextValue
=
{}
;
currentContextValue
=
createContext
({})
;
let
shouldPreventDefault
=
kbService
.
testDispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
);
assert
.
equal
(
shouldPreventDefault
,
true
);
assert
.
deepEqual
(
executeCommandCalls
,
[{
...
...
@@ -347,9 +349,9 @@ suite('AbstractKeybindingService', () => {
statusMessageCallsDisposed
=
[];
// send Ctrl/Cmd + K
currentContextValue
=
{
currentContextValue
=
createContext
(
{
key1
:
true
};
}
)
;
shouldPreventDefault
=
kbService
.
testDispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
);
assert
.
equal
(
shouldPreventDefault
,
true
);
assert
.
deepEqual
(
executeCommandCalls
,
[{
...
...
@@ -365,9 +367,9 @@ suite('AbstractKeybindingService', () => {
statusMessageCallsDisposed
=
[];
// send Ctrl/Cmd + X
currentContextValue
=
{
currentContextValue
=
createContext
(
{
key1
:
true
};
}
)
;
shouldPreventDefault
=
kbService
.
testDispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_X
);
assert
.
equal
(
shouldPreventDefault
,
false
);
assert
.
deepEqual
(
executeCommandCalls
,
[]);
...
...
@@ -389,7 +391,7 @@ suite('AbstractKeybindingService', () => {
]);
// send Ctrl/Cmd + K
currentContextValue
=
{}
;
currentContextValue
=
createContext
({})
;
let
shouldPreventDefault
=
kbService
.
testDispatch
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
);
assert
.
equal
(
shouldPreventDefault
,
false
);
assert
.
deepEqual
(
executeCommandCalls
,
[{
...
...
src/vs/platform/keybinding/test/common/keybindingResolver.test.ts
浏览文件 @
0ebecd5c
...
...
@@ -7,11 +7,13 @@
import
*
as
assert
from
'
assert
'
;
import
{
KeyCode
,
KeyMod
,
KeyChord
,
createKeybinding
,
KeybindingType
,
SimpleKeybinding
}
from
'
vs/base/common/keyCodes
'
;
import
{
KeybindingResolver
}
from
'
vs/platform/keybinding/common/keybindingResolver
'
;
import
{
ContextKeyAndExpr
,
ContextKeyExpr
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
ContextKeyAndExpr
,
ContextKeyExpr
,
IContext
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
ResolvedKeybindingItem
}
from
'
vs/platform/keybinding/common/resolvedKeybindingItem
'
;
import
{
USLayoutResolvedKeybinding
}
from
'
vs/platform/keybinding/common/usLayoutResolvedKeybinding
'
;
import
{
OS
}
from
'
vs/base/common/platform
'
;
const
createContext
=
ctx
=>
({
getValue
:
key
=>
ctx
[
key
]
});
suite
(
'
KeybindingResolver
'
,
()
=>
{
function
kbItem
(
keybinding
:
number
,
command
:
string
,
commandArgs
:
any
,
when
:
ContextKeyExpr
,
isDefault
:
boolean
):
ResolvedKeybindingItem
{
...
...
@@ -35,12 +37,12 @@ suite('KeybindingResolver', () => {
let
contextRules
=
ContextKeyExpr
.
equals
(
'
bar
'
,
'
baz
'
);
let
keybindingItem
=
kbItem
(
keybinding
,
'
yes
'
,
null
,
contextRules
,
true
);
assert
.
equal
(
KeybindingResolver
.
contextMatchesRules
(
{
bar
:
'
baz
'
}
,
contextRules
),
true
);
assert
.
equal
(
KeybindingResolver
.
contextMatchesRules
(
{
bar
:
'
bz
'
}
,
contextRules
),
false
);
assert
.
equal
(
KeybindingResolver
.
contextMatchesRules
(
createContext
({
bar
:
'
baz
'
})
,
contextRules
),
true
);
assert
.
equal
(
KeybindingResolver
.
contextMatchesRules
(
createContext
({
bar
:
'
bz
'
})
,
contextRules
),
false
);
let
resolver
=
new
KeybindingResolver
([
keybindingItem
],
[]);
assert
.
equal
(
resolver
.
resolve
(
{
bar
:
'
baz
'
}
,
null
,
getDispatchStr
(
<
SimpleKeybinding
>
runtimeKeybinding
)).
commandId
,
'
yes
'
);
assert
.
equal
(
resolver
.
resolve
(
{
bar
:
'
bz
'
}
,
null
,
getDispatchStr
(
<
SimpleKeybinding
>
runtimeKeybinding
)),
null
);
assert
.
equal
(
resolver
.
resolve
(
createContext
({
bar
:
'
baz
'
})
,
null
,
getDispatchStr
(
<
SimpleKeybinding
>
runtimeKeybinding
)).
commandId
,
'
yes
'
);
assert
.
equal
(
resolver
.
resolve
(
createContext
({
bar
:
'
bz
'
})
,
null
,
getDispatchStr
(
<
SimpleKeybinding
>
runtimeKeybinding
)),
null
);
});
test
(
'
resolve key with arguments
'
,
function
()
{
...
...
@@ -51,7 +53,7 @@ suite('KeybindingResolver', () => {
let
keybindingItem
=
kbItem
(
keybinding
,
'
yes
'
,
commandArgs
,
contextRules
,
true
);
let
resolver
=
new
KeybindingResolver
([
keybindingItem
],
[]);
assert
.
equal
(
resolver
.
resolve
(
{
bar
:
'
baz
'
}
,
null
,
getDispatchStr
(
<
SimpleKeybinding
>
runtimeKeybinding
)).
commandArgs
,
commandArgs
);
assert
.
equal
(
resolver
.
resolve
(
createContext
({
bar
:
'
baz
'
})
,
null
,
getDispatchStr
(
<
SimpleKeybinding
>
runtimeKeybinding
)).
commandArgs
,
commandArgs
);
});
test
(
'
KeybindingResolver.combine simple 1
'
,
function
()
{
...
...
@@ -333,7 +335,7 @@ suite('KeybindingResolver', () => {
}
};
let
testResolve
=
(
ctx
:
any
,
_expectedKey
:
number
,
commandId
:
string
)
=>
{
let
testResolve
=
(
ctx
:
IContext
,
_expectedKey
:
number
,
commandId
:
string
)
=>
{
const
expectedKey
=
createKeybinding
(
_expectedKey
,
OS
);
if
(
expectedKey
.
type
===
KeybindingType
.
Chord
)
{
...
...
@@ -360,30 +362,30 @@ suite('KeybindingResolver', () => {
testKey
(
'
first
'
,
[]);
testKey
(
'
second
'
,
[
KeyCode
.
KEY_Z
,
KeyCode
.
KEY_X
]);
testResolve
(
{
key2
:
true
}
,
KeyCode
.
KEY_X
,
'
second
'
);
testResolve
(
{}
,
KeyCode
.
KEY_Z
,
'
second
'
);
testResolve
(
createContext
({
key2
:
true
})
,
KeyCode
.
KEY_X
,
'
second
'
);
testResolve
(
createContext
({})
,
KeyCode
.
KEY_Z
,
'
second
'
);
testKey
(
'
third
'
,
[
KeyCode
.
KEY_X
]);
testResolve
(
{
key3
:
true
}
,
KeyCode
.
KEY_X
,
'
third
'
);
testResolve
(
createContext
({
key3
:
true
})
,
KeyCode
.
KEY_X
,
'
third
'
);
testKey
(
'
fourth
'
,
[]);
testKey
(
'
fifth
'
,
[
KeyChord
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_Y
,
KeyCode
.
KEY_Z
)]);
testResolve
(
{}
,
KeyChord
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_Y
,
KeyCode
.
KEY_Z
),
'
fifth
'
);
testResolve
(
createContext
({})
,
KeyChord
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_Y
,
KeyCode
.
KEY_Z
),
'
fifth
'
);
testKey
(
'
seventh
'
,
[
KeyChord
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
,
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
)]);
testResolve
(
{}
,
KeyChord
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
,
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
),
'
seventh
'
);
testResolve
(
createContext
({})
,
KeyChord
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
,
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
),
'
seventh
'
);
testKey
(
'
uncomment lines
'
,
[
KeyChord
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
,
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_U
)]);
testResolve
(
{}
,
KeyChord
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
,
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_U
),
'
uncomment lines
'
);
testResolve
(
createContext
({})
,
KeyChord
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
,
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_U
),
'
uncomment lines
'
);
testKey
(
'
comment lines
'
,
[
KeyChord
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
,
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_C
)]);
testResolve
(
{}
,
KeyChord
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
,
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_C
),
'
comment lines
'
);
testResolve
(
createContext
({})
,
KeyChord
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
,
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_C
),
'
comment lines
'
);
testKey
(
'
unreachablechord
'
,
[]);
testKey
(
'
eleven
'
,
[
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_G
]);
testResolve
(
{}
,
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_G
,
'
eleven
'
);
testResolve
(
createContext
({})
,
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_G
,
'
eleven
'
);
testKey
(
'
sixth
'
,
[]);
});
...
...
src/vs/platform/keybinding/test/common/mockKeybindingService.ts
浏览文件 @
0ebecd5c
...
...
@@ -54,7 +54,7 @@ export class MockContextKeyService implements IContextKeyService {
public
getContextKeyValue
(
key
:
string
)
{
return
;
}
public
getContext
Value
(
domNode
:
HTMLElement
):
any
{
public
getContext
(
domNode
:
HTMLElement
):
any
{
return
null
;
}
public
createScoped
(
domNode
:
HTMLElement
):
IContextKeyService
{
...
...
@@ -77,8 +77,8 @@ export class MockKeybindingService implements IKeybindingService {
return
[];
}
public
resolveKeybinding
(
keybinding
:
Keybinding
):
ResolvedKeybinding
{
return
new
USLayoutResolvedKeybinding
(
keybinding
,
OS
)
;
public
resolveKeybinding
(
keybinding
:
Keybinding
):
ResolvedKeybinding
[]
{
return
[
new
USLayoutResolvedKeybinding
(
keybinding
,
OS
)]
;
}
public
resolveKeyboardEvent
(
keyboardEvent
:
IKeyboardEvent
):
ResolvedKeybinding
{
...
...
@@ -89,7 +89,7 @@ export class MockKeybindingService implements IKeybindingService {
keyboardEvent
.
metaKey
,
keyboardEvent
.
keyCode
);
return
this
.
resolveKeybinding
(
keybinding
);
return
this
.
resolveKeybinding
(
keybinding
)
[
0
]
;
}
public
lookupKeybindings
(
commandId
:
string
):
ResolvedKeybinding
[]
{
...
...
src/vs/workbench/parts/extensions/browser/extensionEditor.ts
浏览文件 @
0ebecd5c
...
...
@@ -669,8 +669,11 @@ export class ExtensionEditor extends BaseEditor {
}
const
keyBinding
=
createKeybinding
(
KeybindingIO
.
readKeybinding
(
key
||
rawKeyBinding
.
key
,
OS
),
OS
);
const
resolvedKeybinding
=
this
.
keybindingService
.
resolveKeybinding
(
keyBinding
);
const
result
=
resolvedKeybinding
.
getLabel
();
const
resolvedKeybindings
=
this
.
keybindingService
.
resolveKeybinding
(
keyBinding
);
if
(
resolvedKeybindings
.
length
===
0
)
{
return
null
;
}
const
result
=
resolvedKeybindings
[
0
].
getLabel
();
return
result
===
'
unknown
'
?
null
:
result
;
}
...
...
src/vs/workbench/parts/preferences/browser/keybindingsEditorContribution.ts
浏览文件 @
0ebecd5c
...
...
@@ -160,20 +160,21 @@ export class DefineKeybindingController implements editorCommon.IEditorContribut
var
m
=
model
.
findMatches
(
regex
,
false
,
true
,
false
,
false
,
false
).
map
(
m
=>
m
.
range
);
let
data
=
m
.
map
((
range
)
=>
{
let
text
=
model
.
getValueInRange
(
range
);
let
strKeybinding
=
text
.
substring
(
1
,
text
.
length
-
1
);
strKeybinding
=
strKeybinding
.
replace
(
/
\\\\
/g
,
'
\\
'
);
let
numKeybinding
=
KeybindingIO
.
readKeybinding
(
strKeybinding
,
OS
);
const
text
=
model
.
getValueInRange
(
range
);
const
strKeybinding
=
text
.
substring
(
1
,
text
.
length
-
1
).
replace
(
/
\\\\
/g
,
'
\\
'
);
const
numKeybinding
=
KeybindingIO
.
readKeybinding
(
strKeybinding
,
OS
);
const
keybinding
=
createKeybinding
(
numKeybinding
,
OS
);
const
usResolvedKeybinding
=
new
USLayoutResolvedKeybinding
(
keybinding
,
OS
);
let
keybinding
=
createKeybinding
(
numKeybinding
,
OS
);
let
resolvedKeybinding
=
this
.
_keybindingService
.
resolveKeybinding
(
keybinding
);
let
label
:
string
=
null
;
const
resolvedKeybindings
=
this
.
_keybindingService
.
resolveKeybinding
(
keybinding
);
if
(
resolvedKeybindings
.
length
>
0
)
{
label
=
resolvedKeybindings
[
0
].
getLabel
();
}
const
usResolvedKeybinding
=
new
USLayoutResolvedKeybinding
(
keybinding
,
OS
);
return
{
usLabel
:
usResolvedKeybinding
.
getLabel
(),
label
:
resolvedKeybinding
.
getLabel
()
,
label
:
label
,
range
:
range
};
});
...
...
src/vs/workbench/parts/search/browser/searchActions.ts
浏览文件 @
0ebecd5c
...
...
@@ -39,13 +39,16 @@ export function isSearchViewletFocussed(viewletService: IViewletService): boolea
}
export
function
appendKeyBindingLabel
(
label
:
string
,
keyBinding
:
number
|
ResolvedKeybinding
,
keyBindingService2
:
IKeybindingService
):
string
{
let
resolvedKb
:
ResolvedKeybinding
;
if
(
typeof
keyBinding
===
'
number
'
)
{
resolvedKb
=
keyBindingService2
.
resolveKeybinding
(
createKeybinding
(
keyBinding
,
OS
));
const
resolvedKeybindings
=
keyBindingService2
.
resolveKeybinding
(
createKeybinding
(
keyBinding
,
OS
));
return
doAppendKeyBindingLabel
(
label
,
resolvedKeybindings
.
length
>
0
?
resolvedKeybindings
[
0
]
:
null
);
}
else
{
re
solvedKb
=
keyBinding
;
re
turn
doAppendKeyBindingLabel
(
label
,
keyBinding
)
;
}
return
resolvedKb
?
label
+
'
(
'
+
resolvedKb
.
getLabel
()
+
'
)
'
:
label
;
}
function
doAppendKeyBindingLabel
(
label
:
string
,
keyBinding
:
ResolvedKeybinding
):
string
{
return
keyBinding
?
label
+
'
(
'
+
keyBinding
.
getLabel
()
+
'
)
'
:
label
;
}
export
class
ToggleCaseSensitiveAction
extends
Action
{
...
...
src/vs/workbench/parts/search/test/browser/searchActions.test.ts
浏览文件 @
0ebecd5c
...
...
@@ -30,7 +30,7 @@ suite('Search Actions', () => {
instantiationService
=
new
TestInstantiationService
();
instantiationService
.
stub
(
IModelService
,
stubModelService
(
instantiationService
));
instantiationService
.
stub
(
IKeybindingService
,
{});
instantiationService
.
stub
(
IKeybindingService
,
'
resolveKeybinding
'
,
(
keybinding
:
Keybinding
)
=>
new
USLayoutResolvedKeybinding
(
keybinding
,
OS
)
);
instantiationService
.
stub
(
IKeybindingService
,
'
resolveKeybinding
'
,
(
keybinding
:
Keybinding
)
=>
[
new
USLayoutResolvedKeybinding
(
keybinding
,
OS
)]
);
counter
=
0
;
});
...
...
src/vs/workbench/parts/update/electron-browser/update.ts
浏览文件 @
0ebecd5c
...
...
@@ -86,9 +86,13 @@ export function loadReleaseNotes(accessor: ServicesAccessor, version: string): T
return
unassigned
;
}
const
resolvedKeybinding
=
keybindingService
.
resolveKeybinding
(
keybinding
);
const
resolvedKeybinding
s
=
keybindingService
.
resolveKeybinding
(
keybinding
);
return
resolvedKeybinding
.
getLabel
();
if
(
resolvedKeybindings
.
length
===
0
)
{
return
unassigned
;
}
return
resolvedKeybindings
[
0
].
getLabel
();
};
return
text
...
...
src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts
浏览文件 @
0ebecd5c
...
...
@@ -221,9 +221,15 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
const
item
=
items
[
i
];
const
when
=
(
item
.
when
?
item
.
when
.
normalize
()
:
null
);
const
keybinding
=
item
.
keybinding
;
const
resolvedKeybinding
=
(
keybinding
?
this
.
resolveKeybinding
(
keybinding
)
:
null
);
result
[
resultLen
++
]
=
new
ResolvedKeybindingItem
(
resolvedKeybinding
,
item
.
command
,
item
.
commandArgs
,
when
,
isDefault
);
if
(
!
keybinding
)
{
// This might be a removal keybinding item in user settings => accept it
result
[
resultLen
++
]
=
new
ResolvedKeybindingItem
(
null
,
item
.
command
,
item
.
commandArgs
,
when
,
isDefault
);
}
else
{
const
resolvedKeybindings
=
this
.
resolveKeybinding
(
keybinding
);
for
(
let
j
=
0
;
j
<
resolvedKeybindings
.
length
;
j
++
)
{
result
[
resultLen
++
]
=
new
ResolvedKeybindingItem
(
resolvedKeybindings
[
j
],
item
.
command
,
item
.
commandArgs
,
when
,
isDefault
);
}
}
}
return
result
;
...
...
@@ -242,14 +248,8 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
return
extraUserKeybindings
.
map
((
k
,
i
)
=>
KeybindingIO
.
readKeybindingItem
(
k
,
i
,
OS
));
}
public
resolveKeybinding
(
kb
:
Keybinding
):
ResolvedKeybinding
{
// TODO@keybindings
let
r
=
this
.
_keyboardMapper
.
resolveKeybinding
(
kb
);
if
(
r
.
length
!==
1
)
{
console
.
warn
(
'
oh noes => I cannot fulfill API!!!
'
);
return
null
;
}
return
r
[
0
];
public
resolveKeybinding
(
kb
:
Keybinding
):
ResolvedKeybinding
[]
{
return
this
.
_keyboardMapper
.
resolveKeybinding
(
kb
);
}
public
resolveKeyboardEvent
(
keyboardEvent
:
IKeyboardEvent
):
ResolvedKeybinding
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录