Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
0e039274
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,发现更多精彩内容 >>
提交
0e039274
编写于
1月 08, 2016
作者:
J
Johannes Rieken
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
remove merge issue
上级
5846f826
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
0 addition
and
450 deletion
+0
-450
src/vs/platform/keybinding/common/commonKeybindingResolver.ts
...vs/platform/keybinding/common/commonKeybindingResolver.ts
+0
-450
未找到文件。
src/vs/platform/keybinding/common/commonKeybindingResolver.ts
已删除
100644 → 0
浏览文件 @
5846f826
/*---------------------------------------------------------------------------------------------
* 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
{
KeybindingsRegistry
}
from
'
vs/platform/keybinding/common/keybindingsRegistry
'
;
import
{
KeybindingsUtils
}
from
'
vs/platform/keybinding/common/keybindingsUtils
'
;
import
Platform
=
require
(
'
vs/base/common/platform
'
);
import
{
IKeybindingService
,
IKeybindingScopeLocation
,
ICommandHandler
,
IKeybindingItem
,
IKeybindings
,
KbExpr
,
IUserFriendlyKeybinding
,
IKeybindingContextKey
}
from
'
vs/platform/keybinding/common/keybindingService
'
;
import
{
KeyMod
,
KeyCode
,
BinaryKeybindings
,
Keybinding
}
from
'
vs/base/common/keyCodes
'
;
export
interface
IResolveResult
{
enterChord
:
number
;
commandId
:
string
;
}
export
interface
IBoundCommands
{
[
commandId
:
string
]:
boolean
;
}
interface
ICommandMap
{
[
partialKeybinding
:
number
]:
ICommandEntry
[];
}
interface
IChordsMap
{
[
partialKeybinding
:
number
]:
ICommandMap
;
}
interface
ICommandEntry
{
context
:
KbExpr
;
keybinding
:
number
;
commandId
:
string
;
}
export
class
CommonKeybindingResolver
{
private
_defaultKeybindings
:
IKeybindingItem
[];
private
_defaultBoundCommands
:
IBoundCommands
;
private
_map
:
ICommandMap
;
private
_chords
:
IChordsMap
;
private
_lookupMap
:
{
[
commandId
:
string
]:
IKeybindingItem
[];
};
private
_lookupMapUnreachable
:
{
// The value contains the keybinding or first part of a chord
[
commandId
:
string
]:
number
[];
};
private
_shouldWarnOnConflict
:
boolean
;
constructor
(
defaultKeybindings
:
IKeybindingItem
[],
overrides
:
IKeybindingItem
[],
shouldWarnOnConflict
:
boolean
=
true
)
{
defaultKeybindings
=
defaultKeybindings
.
slice
(
0
).
sort
(
sorter
);
this
.
_defaultKeybindings
=
defaultKeybindings
;
this
.
_shouldWarnOnConflict
=
shouldWarnOnConflict
;
this
.
_defaultBoundCommands
=
Object
.
create
(
null
);
for
(
let
i
=
0
,
len
=
defaultKeybindings
.
length
;
i
<
len
;
i
++
)
{
this
.
_defaultBoundCommands
[
defaultKeybindings
[
i
].
command
]
=
true
;
}
this
.
_map
=
Object
.
create
(
null
);
this
.
_lookupMap
=
Object
.
create
(
null
);
this
.
_lookupMapUnreachable
=
Object
.
create
(
null
);
this
.
_chords
=
Object
.
create
(
null
);
let
defaultKeybindingsCount
=
defaultKeybindings
.
length
;
let
allKeybindings
=
defaultKeybindings
.
concat
(
overrides
);
for
(
let
i
=
0
,
len
=
allKeybindings
.
length
;
i
<
len
;
i
++
)
{
let
k
=
allKeybindings
[
i
];
if
(
k
.
keybinding
===
0
)
{
continue
;
}
if
(
k
.
context
)
{
k
.
context
=
k
.
context
.
normalize
();
}
let
entry
:
ICommandEntry
=
{
context
:
k
.
context
,
keybinding
:
k
.
keybinding
,
commandId
:
k
.
command
};
if
(
BinaryKeybindings
.
hasChord
(
k
.
keybinding
))
{
// This is a chord
let
keybindingFirstPart
=
BinaryKeybindings
.
extractFirstPart
(
k
.
keybinding
);
let
keybindingChordPart
=
BinaryKeybindings
.
extractChordPart
(
k
.
keybinding
);
this
.
_chords
[
keybindingFirstPart
]
=
this
.
_chords
[
keybindingFirstPart
]
||
Object
.
create
(
null
);
this
.
_chords
[
keybindingFirstPart
][
keybindingChordPart
]
=
this
.
_chords
[
keybindingFirstPart
][
keybindingChordPart
]
||
[];
this
.
_chords
[
keybindingFirstPart
][
keybindingChordPart
].
push
(
entry
);
this
.
_addKeyPress
(
keybindingFirstPart
,
entry
,
k
,
i
<
defaultKeybindingsCount
);
}
else
{
this
.
_addKeyPress
(
k
.
keybinding
,
entry
,
k
,
i
<
defaultKeybindingsCount
);
}
}
}
private
_addKeyPress
(
keypress
:
number
,
entry
:
ICommandEntry
,
item
:
IKeybindingItem
,
isDefault
:
boolean
):
void
{
if
(
!
this
.
_map
[
keypress
])
{
// There is no conflict so far
this
.
_map
[
keypress
]
=
[
entry
];
this
.
_addToLookupMap
(
item
);
return
;
}
var
conflicts
=
this
.
_map
[
keypress
];
for
(
var
i
=
conflicts
.
length
-
1
;
i
>=
0
;
i
--
)
{
var
conflict
=
conflicts
[
i
];
if
(
conflict
.
commandId
===
item
.
command
)
{
continue
;
}
if
(
BinaryKeybindings
.
hasChord
(
conflict
.
keybinding
)
&&
BinaryKeybindings
.
hasChord
(
entry
.
keybinding
)
&&
conflict
.
keybinding
!==
entry
.
keybinding
)
{
// The conflict only shares the chord start with this command
continue
;
}
if
(
CommonKeybindingResolver
.
contextIsEntirelyIncluded
(
true
,
conflict
.
context
,
item
.
context
))
{
// `item` completely overwrites `conflict`
if
(
this
.
_shouldWarnOnConflict
&&
isDefault
)
{
console
.
warn
(
'
Conflict detected, command `
'
+
conflict
.
commandId
+
'
` cannot be triggered by
'
+
Keybinding
.
toUserSettingsLabel
(
keypress
));
}
this
.
_lookupMapUnreachable
[
conflict
.
commandId
]
=
this
.
_lookupMapUnreachable
[
conflict
.
commandId
]
||
[];
this
.
_lookupMapUnreachable
[
conflict
.
commandId
].
push
(
conflict
.
keybinding
);
}
}
conflicts
.
push
(
entry
);
this
.
_addToLookupMap
(
item
);
}
/**
* Returns true if `a` is completely covered by `b`.
* Returns true if `b` is a more relaxed `a`.
* Return true if (`a` === true implies `b` === true).
*/
public
static
contextIsEntirelyIncluded
(
inNormalizedForm
:
boolean
,
a
:
KbExpr
,
b
:
KbExpr
):
boolean
{
if
(
!
inNormalizedForm
)
{
a
=
a
?
a
.
normalize
()
:
null
;
b
=
b
?
b
.
normalize
()
:
null
;
}
if
(
!
b
)
{
return
true
;
}
if
(
!
a
)
{
return
false
;
}
let
aRulesArr
=
a
.
serialize
().
split
(
'
&&
'
);
let
bRulesArr
=
b
.
serialize
().
split
(
'
&&
'
);
let
aRules
:
{
[
rule
:
string
]:
boolean
;
}
=
Object
.
create
(
null
);
for
(
let
i
=
0
,
len
=
aRulesArr
.
length
;
i
<
len
;
i
++
)
{
aRules
[
aRulesArr
[
i
]]
=
true
;
}
for
(
let
i
=
0
,
len
=
bRulesArr
.
length
;
i
<
len
;
i
++
)
{
if
(
!
aRules
[
bRulesArr
[
i
]])
{
return
false
;
}
}
return
true
;
}
private
_addToLookupMap
(
item
:
IKeybindingItem
):
void
{
if
(
!
item
.
command
)
{
return
;
}
this
.
_lookupMap
[
item
.
command
]
=
this
.
_lookupMap
[
item
.
command
]
||
[];
this
.
_lookupMap
[
item
.
command
].
push
(
item
);
}
public
getDefaultBoundCommands
():
IBoundCommands
{
return
this
.
_defaultBoundCommands
;
}
public
getDefaultKeybindings
():
string
{
var
out
=
new
OutputBuilder
();
out
.
writeLine
(
'
[
'
);
this
.
_defaultKeybindings
.
forEach
(
k
=>
{
IOSupport
.
writeKeybindingItem
(
out
,
k
);
out
.
writeLine
(
'
,
'
);
});
out
.
writeLine
(
'
]
'
);
return
out
.
toString
();
}
public
lookupKeybinding
(
commandId
:
string
):
Keybinding
[]
{
let
rawPossibleTriggers
=
this
.
_lookupMap
[
commandId
]
if
(
!
rawPossibleTriggers
)
{
return
[];
}
let
possibleTriggers
=
rawPossibleTriggers
.
map
(
possibleTrigger
=>
possibleTrigger
.
keybinding
);
let
remove
=
this
.
_lookupMapUnreachable
[
commandId
];
if
(
remove
)
{
possibleTriggers
=
possibleTriggers
.
filter
((
possibleTrigger
)
=>
{
return
remove
.
indexOf
(
possibleTrigger
)
===
-
1
;
});
}
let
seenKeys
:
number
[]
=
[];
let
result
=
possibleTriggers
.
filter
((
possibleTrigger
)
=>
{
if
(
seenKeys
.
indexOf
(
possibleTrigger
)
>=
0
)
{
return
false
;
}
seenKeys
.
push
(
possibleTrigger
);
return
true
;
});
return
result
.
map
((
trigger
)
=>
{
return
new
Keybinding
(
trigger
);
}).
reverse
();
// sort most specific to the top
}
public
resolve
(
context
:
any
,
currentChord
:
number
,
keypress
:
number
):
IResolveResult
{
// console.log('resolve: ' + Keybinding.toLabel(keypress));
let
lookupMap
:
ICommandEntry
[]
=
null
;
if
(
currentChord
!==
0
)
{
let
chords
=
this
.
_chords
[
currentChord
];
if
(
!
chords
)
{
return
null
;
}
lookupMap
=
chords
[
keypress
];
}
else
{
lookupMap
=
this
.
_map
[
keypress
];
}
let
result
=
this
.
_findCommand
(
context
,
lookupMap
);
if
(
!
result
)
{
return
null
;
}
if
(
currentChord
===
0
&&
BinaryKeybindings
.
hasChord
(
result
.
keybinding
))
{
return
{
enterChord
:
keypress
,
commandId
:
null
};
}
return
{
enterChord
:
0
,
commandId
:
result
.
commandId
};
}
private
_findCommand
(
context
:
any
,
matches
:
ICommandEntry
[]):
ICommandEntry
{
if
(
!
matches
)
{
return
null
;
}
for
(
let
i
=
matches
.
length
-
1
;
i
>=
0
;
i
--
)
{
let
k
=
matches
[
i
];
if
(
!
CommonKeybindingResolver
.
contextMatchesRules
(
context
,
k
.
context
))
{
continue
;
}
return
k
;
}
return
null
;
}
public
static
contextMatchesRules
(
context
:
any
,
rules
:
KbExpr
):
boolean
{
if
(
!
rules
)
{
return
true
;
}
return
rules
.
evaluate
(
context
);
}
}
function
rightPaddedString
(
str
:
string
,
minChars
:
number
):
string
{
if
(
str
.
length
<
minChars
)
{
return
str
+
(
new
Array
(
minChars
-
str
.
length
).
join
(
'
'
));
}
return
str
;
}
function
sorter
(
a
:
IKeybindingItem
,
b
:
IKeybindingItem
):
number
{
if
(
a
.
weight1
!==
b
.
weight1
)
{
return
a
.
weight1
-
b
.
weight1
;
}
if
(
a
.
command
<
b
.
command
)
{
return
-
1
;
}
if
(
a
.
command
>
b
.
command
)
{
return
1
;
}
return
a
.
weight2
-
b
.
weight2
;
}
export
class
OutputBuilder
{
private
_lines
:
string
[]
=
[];
private
_currentLine
:
string
=
''
;
write
(
str
:
string
):
void
{
this
.
_currentLine
+=
str
;
}
writeLine
(
str
:
string
=
''
):
void
{
this
.
_lines
.
push
(
this
.
_currentLine
+
str
);
this
.
_currentLine
=
''
;
}
toString
():
string
{
this
.
writeLine
();
return
this
.
_lines
.
join
(
'
\n
'
);
}
}
export
class
IOSupport
{
public
static
writeKeybindingItem
(
out
:
OutputBuilder
,
item
:
IKeybindingItem
):
void
{
out
.
write
(
'
{ "key":
'
+
rightPaddedString
(
'
"
'
+
IOSupport
.
writeKeybinding
(
item
.
keybinding
).
replace
(
/
\\
/g
,
'
\\\\
'
)
+
'
",
'
,
25
)
+
'
"command":
'
);
let
serializedContext
=
item
.
context
?
item
.
context
.
serialize
()
:
''
;
if
(
serializedContext
.
length
>
0
)
{
out
.
write
(
'
"
'
+
item
.
command
+
'
",
'
);
out
.
writeLine
();
out
.
write
(
'
"when": "
'
);
out
.
write
(
serializedContext
);
out
.
write
(
'
"
'
);
}
else
{
out
.
write
(
'
"
'
+
item
.
command
+
'
"
'
);
}
// out.write(String(item.weight));
out
.
write
(
'
}
'
);
}
public
static
readKeybindingItem
(
input
:
IUserFriendlyKeybinding
,
index
:
number
):
IKeybindingItem
{
var
key
=
IOSupport
.
readKeybinding
(
input
.
key
);
var
context
=
IOSupport
.
readKeybindingContexts
(
input
.
when
);
return
{
keybinding
:
key
,
command
:
input
.
command
,
context
:
context
,
weight1
:
1000
,
weight2
:
index
};
}
private
static
writeKeybinding
(
input
:
number
):
string
{
return
Keybinding
.
toUserSettingsLabel
(
input
);
}
public
static
readKeybinding
(
input
:
string
):
number
{
if
(
!
input
)
{
return
null
;
}
input
=
input
.
toLowerCase
().
trim
();
var
ctrlCmd
=
false
,
shift
=
false
,
alt
=
false
,
winCtrl
=
false
,
key
:
string
=
''
;
while
(
/^
(
ctrl|shift|alt|meta|win|cmd
)(\+
|
\-)
/
.
test
(
input
))
{
if
(
/^ctrl
(\+
|
\-)
/
.
test
(
input
))
{
if
(
Platform
.
isMacintosh
)
{
winCtrl
=
true
;
}
else
{
ctrlCmd
=
true
;
}
input
=
input
.
substr
(
'
ctrl-
'
.
length
);
}
if
(
/^shift
(\+
|
\-)
/
.
test
(
input
))
{
shift
=
true
;
input
=
input
.
substr
(
'
shift-
'
.
length
);
}
if
(
/^alt
(\+
|
\-)
/
.
test
(
input
))
{
alt
=
true
;
input
=
input
.
substr
(
'
alt-
'
.
length
);
}
if
(
/^meta
(\+
|
\-)
/
.
test
(
input
))
{
if
(
Platform
.
isMacintosh
)
{
ctrlCmd
=
true
;
}
else
{
winCtrl
=
true
;
}
input
=
input
.
substr
(
'
meta-
'
.
length
);
}
if
(
/^win
(\+
|
\-)
/
.
test
(
input
))
{
if
(
Platform
.
isMacintosh
)
{
ctrlCmd
=
true
;
}
else
{
winCtrl
=
true
;
}
input
=
input
.
substr
(
'
win-
'
.
length
);
}
if
(
/^cmd
(\+
|
\-)
/
.
test
(
input
))
{
if
(
Platform
.
isMacintosh
)
{
ctrlCmd
=
true
;
}
else
{
winCtrl
=
true
;
}
input
=
input
.
substr
(
'
cmd-
'
.
length
);
}
}
if
(
/^
(
up|down|left|right
)
/
.
test
(
input
))
{
input
=
input
.
replace
(
/^
(
up|down|left|right
)
/
,(
captured
)
=>
{
return
captured
+
'
arrow
'
;
});
}
var
chord
:
number
=
0
;
var
firstSpaceIdx
=
input
.
indexOf
(
'
'
);
if
(
firstSpaceIdx
>
0
)
{
key
=
input
.
substring
(
0
,
firstSpaceIdx
);
chord
=
IOSupport
.
readKeybinding
(
input
.
substring
(
firstSpaceIdx
));
}
else
{
key
=
input
;
}
let
keyCode
=
KeyCode
.
fromString
(
key
);
let
result
=
0
;
if
(
ctrlCmd
)
{
result
|=
KeyMod
.
CtrlCmd
;
}
if
(
shift
)
{
result
|=
KeyMod
.
Shift
;
}
if
(
alt
)
{
result
|=
KeyMod
.
Alt
;
}
if
(
winCtrl
)
{
result
|=
KeyMod
.
WinCtrl
;
}
result
|=
keyCode
;
return
KeyMod
.
chord
(
result
,
chord
);
}
public
static
readKeybindingContexts
(
input
:
string
):
KbExpr
{
return
KbExpr
.
deserialize
(
input
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录