Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
ebd346b3
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,发现更多精彩内容 >>
提交
ebd346b3
编写于
3月 20, 2017
作者:
A
Alex Dima
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Share test utils between keyboard mappers
上级
b3f8aee7
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
744 addition
and
736 deletion
+744
-736
src/vs/workbench/services/keybinding/common/keyboardMapper.ts
...vs/workbench/services/keybinding/common/keyboardMapper.ts
+4
-593
src/vs/workbench/services/keybinding/common/macLinuxKeyboardMapper.ts
...ench/services/keybinding/common/macLinuxKeyboardMapper.ts
+603
-0
src/vs/workbench/services/keybinding/common/windowsKeyboardMapper.ts
...bench/services/keybinding/common/windowsKeyboardMapper.ts
+2
-1
src/vs/workbench/services/keybinding/test/keyboardMapperTestUtils.ts
...bench/services/keybinding/test/keyboardMapperTestUtils.ts
+107
-0
src/vs/workbench/services/keybinding/test/macLinuxKeyboardMapper.test.ts
...h/services/keybinding/test/macLinuxKeyboardMapper.test.ts
+9
-33
src/vs/workbench/services/keybinding/test/windowsKeyboardMapper.test.ts
...ch/services/keybinding/test/windowsKeyboardMapper.test.ts
+19
-109
未找到文件。
src/vs/workbench/services/keybinding/common/keyboardMapper.ts
浏览文件 @
ebd346b3
...
@@ -5,598 +5,9 @@
...
@@ -5,598 +5,9 @@
'
use strict
'
;
'
use strict
'
;
import
{
OperatingSystem
}
from
'
vs/base/common/platform
'
;
import
{
Keybinding
,
ResolvedKeybinding
}
from
'
vs/base/common/keyCodes
'
;
import
{
KeyCode
,
ResolvedKeybinding
,
KeyCodeUtils
,
SimpleKeybinding
,
Keybinding
,
KeybindingType
}
from
'
vs/base/common/keyCodes
'
;
import
{
KeyboardEventCode
,
KeyboardEventCodeUtils
,
IMMUTABLE_CODE_TO_KEY_CODE
}
from
'
vs/workbench/services/keybinding/common/keyboardEventCode
'
;
import
{
CharCode
}
from
'
vs/base/common/charCode
'
;
import
{
IHTMLContentElement
}
from
'
vs/base/common/htmlContent
'
;
import
{
UILabelProvider
,
AriaLabelProvider
}
from
'
vs/platform/keybinding/common/keybindingLabels
'
;
export
interface
IKeyMapping
{
export
interface
IKeyboardMapper
{
value
:
string
;
dumpDebugInfo
():
string
;
withShift
:
string
;
resolveKeybinding
(
keybinding
:
Keybinding
):
ResolvedKeybinding
[];
withAltGr
:
string
;
withShiftAltGr
:
string
;
valueIsDeadKey
?:
boolean
;
withShiftIsDeadKey
?:
boolean
;
withAltGrIsDeadKey
?:
boolean
;
withShiftAltGrIsDeadKey
?:
boolean
;
}
export
interface
IKeyboardMapping
{
[
code
:
string
]:
IKeyMapping
;
}
const
LOG
=
false
;
function
log
(
str
:
string
):
void
{
if
(
LOG
)
{
console
.
info
(
str
);
}
}
const
CHAR_CODE_TO_KEY_CODE
:
{
keyCode
:
KeyCode
;
shiftKey
:
boolean
}[]
=
[];
export
class
HardwareKeypress
{
public
readonly
ctrlKey
:
boolean
;
public
readonly
shiftKey
:
boolean
;
public
readonly
altKey
:
boolean
;
public
readonly
metaKey
:
boolean
;
public
readonly
code
:
KeyboardEventCode
;
constructor
(
ctrlKey
:
boolean
,
shiftKey
:
boolean
,
altKey
:
boolean
,
metaKey
:
boolean
,
code
:
KeyboardEventCode
)
{
this
.
ctrlKey
=
ctrlKey
;
this
.
shiftKey
=
shiftKey
;
this
.
altKey
=
altKey
;
this
.
metaKey
=
metaKey
;
this
.
code
=
code
;
}
}
export
class
NativeResolvedKeybinding
extends
ResolvedKeybinding
{
private
readonly
_mapper
:
KeyboardMapper
;
private
readonly
_OS
:
OperatingSystem
;
private
readonly
_firstPart
:
HardwareKeypress
;
private
readonly
_chordPart
:
HardwareKeypress
;
constructor
(
mapper
:
KeyboardMapper
,
OS
:
OperatingSystem
,
firstPart
:
HardwareKeypress
,
chordPart
:
HardwareKeypress
)
{
super
();
this
.
_mapper
=
mapper
;
this
.
_OS
=
OS
;
this
.
_firstPart
=
firstPart
;
this
.
_chordPart
=
chordPart
;
}
public
getLabel
():
string
{
let
firstPart
=
this
.
_firstPart
?
this
.
_mapper
.
getUILabelForHardwareCode
(
this
.
_firstPart
.
code
)
:
null
;
let
chordPart
=
this
.
_chordPart
?
this
.
_mapper
.
getUILabelForHardwareCode
(
this
.
_chordPart
.
code
)
:
null
;
return
UILabelProvider
.
toLabel
(
this
.
_firstPart
,
firstPart
,
this
.
_chordPart
,
chordPart
,
this
.
_OS
);
}
public
getAriaLabel
():
string
{
let
firstPart
=
this
.
_firstPart
?
this
.
_mapper
.
getAriaLabelForHardwareCode
(
this
.
_firstPart
.
code
)
:
null
;
let
chordPart
=
this
.
_chordPart
?
this
.
_mapper
.
getAriaLabelForHardwareCode
(
this
.
_chordPart
.
code
)
:
null
;
return
AriaLabelProvider
.
toLabel
(
this
.
_firstPart
,
firstPart
,
this
.
_chordPart
,
chordPart
,
this
.
_OS
);
}
public
getHTMLLabel
():
IHTMLContentElement
[]
{
let
firstPart
=
this
.
_firstPart
?
this
.
_mapper
.
getUILabelForHardwareCode
(
this
.
_firstPart
.
code
)
:
null
;
let
chordPart
=
this
.
_chordPart
?
this
.
_mapper
.
getUILabelForHardwareCode
(
this
.
_chordPart
.
code
)
:
null
;
return
UILabelProvider
.
toHTMLLabel
(
this
.
_firstPart
,
firstPart
,
this
.
_chordPart
,
chordPart
,
this
.
_OS
);
}
public
getElectronAccelerator
():
string
{
throw
new
Error
(
'
TODO!
'
);
// const usResolvedKeybinding = new USLayoutResolvedKeybinding(this._actual, OS);
// if (OS === OperatingSystem.Windows) {
// // electron menus always do the correct rendering on Windows
// return usResolvedKeybinding.getElectronAccelerator();
// }
// let usLabel = usResolvedKeybinding.getLabel();
// let label = this.getLabel();
// if (usLabel !== label) {
// // electron menus are incorrect in rendering (linux) and in rendering and interpreting (mac)
// // for non US standard keyboard layouts
// return null;
// }
// return usResolvedKeybinding.getElectronAccelerator();
}
public
getUserSettingsLabel
():
string
{
throw
new
Error
(
'
TODO!
'
);
// return KeybindingIO.writeKeybinding(this._actual, OS);
}
public
isChord
():
boolean
{
throw
new
Error
(
'
TODO!
'
);
}
public
hasCtrlModifier
():
boolean
{
throw
new
Error
(
'
TODO!
'
);
}
public
hasShiftModifier
():
boolean
{
throw
new
Error
(
'
TODO!
'
);
}
public
hasAltModifier
():
boolean
{
throw
new
Error
(
'
TODO!
'
);
}
public
hasMetaModifier
():
boolean
{
throw
new
Error
(
'
TODO!
'
);
}
public
getDispatchParts
():
[
string
,
string
]
{
throw
new
Error
(
'
TODO!
'
);
}
}
}
interface
IHardwareCodeMapping
{
code
:
KeyboardEventCode
;
value
:
number
;
withShift
:
number
;
withAltGr
:
number
;
withShiftAltGr
:
number
;
}
export
class
KeyboardMapper
{
private
readonly
_OS
:
OperatingSystem
;
private
readonly
_codeInfo
:
IHardwareCodeMapping
[];
private
readonly
_hwToKb
:
number
[]
=
[];
private
readonly
_hwToLabel
:
string
[]
=
[];
private
readonly
_kbToHw
:
number
[][]
=
[];
constructor
(
rawMappings
:
IKeyboardMapping
,
OS
:
OperatingSystem
)
{
this
.
_OS
=
OS
;
this
.
_hwToKb
=
[];
this
.
_kbToHw
=
[];
this
.
_hwToLabel
=
[];
for
(
let
code
=
KeyboardEventCode
.
None
;
code
<
KeyboardEventCode
.
MAX_VALUE
;
code
++
)
{
const
immutableKeyCode
=
IMMUTABLE_CODE_TO_KEY_CODE
[
code
];
if
(
immutableKeyCode
!==
-
1
)
{
this
.
_registerAllCombos1
(
false
,
false
,
false
,
code
,
immutableKeyCode
);
this
.
_hwToLabel
[
code
]
=
KeyCodeUtils
.
toString
(
immutableKeyCode
);
}
}
this
.
_codeInfo
=
[];
let
mappings
:
IHardwareCodeMapping
[]
=
[],
mappingsLen
=
0
;
for
(
let
strCode
in
rawMappings
)
{
if
(
rawMappings
.
hasOwnProperty
(
strCode
))
{
const
code
=
KeyboardEventCodeUtils
.
toEnum
(
strCode
);
if
(
code
===
KeyboardEventCode
.
None
)
{
log
(
`Unknown code
${
strCode
}
in mapping.`
);
continue
;
}
if
(
IMMUTABLE_CODE_TO_KEY_CODE
[
code
]
!==
-
1
)
{
continue
;
}
const
rawMapping
=
rawMappings
[
strCode
];
const
value
=
KeyboardMapper
.
_getCharCode
(
rawMapping
.
value
);
const
withShift
=
KeyboardMapper
.
_getCharCode
(
rawMapping
.
withShift
);
const
withAltGr
=
KeyboardMapper
.
_getCharCode
(
rawMapping
.
withAltGr
);
const
withShiftAltGr
=
KeyboardMapper
.
_getCharCode
(
rawMapping
.
withShiftAltGr
);
const
mapping
:
IHardwareCodeMapping
=
{
code
:
code
,
value
:
value
,
withShift
:
withShift
,
withAltGr
:
withAltGr
,
withShiftAltGr
:
withShiftAltGr
,
};
mappings
[
mappingsLen
++
]
=
mapping
;
this
.
_codeInfo
[
code
]
=
mapping
;
if
(
value
>=
CharCode
.
a
&&
value
<=
CharCode
.
z
)
{
this
.
_hwToLabel
[
code
]
=
String
.
fromCharCode
(
CharCode
.
A
+
(
value
-
CharCode
.
a
));
}
else
if
(
value
)
{
this
.
_hwToLabel
[
code
]
=
String
.
fromCharCode
(
value
);
}
else
{
this
.
_hwToLabel
[
code
]
=
null
;
}
}
}
// Handle all `withShiftAltGr` entries
for
(
let
i
=
mappings
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
mapping
=
mappings
[
i
];
const
withShiftAltGr
=
mapping
.
withShiftAltGr
;
if
(
withShiftAltGr
===
mapping
.
withAltGr
||
withShiftAltGr
===
mapping
.
withShift
||
withShiftAltGr
===
mapping
.
value
)
{
// handled below
continue
;
}
this
.
_registerCharCode
(
mapping
.
code
,
true
,
true
,
true
,
withShiftAltGr
);
}
// Handle all `withAltGr` entries
for
(
let
i
=
mappings
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
mapping
=
mappings
[
i
];
const
withAltGr
=
mapping
.
withAltGr
;
if
(
withAltGr
===
mapping
.
withShift
||
withAltGr
===
mapping
.
value
)
{
// handled below
continue
;
}
this
.
_registerCharCode
(
mapping
.
code
,
true
,
false
,
true
,
withAltGr
);
}
// Handle all `withShift` entries
for
(
let
i
=
mappings
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
mapping
=
mappings
[
i
];
const
withShift
=
mapping
.
withShift
;
if
(
withShift
===
mapping
.
value
)
{
// handled below
continue
;
}
this
.
_registerCharCode
(
mapping
.
code
,
false
,
true
,
false
,
withShift
);
}
// Handle all `value` entries
for
(
let
i
=
mappings
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
mapping
=
mappings
[
i
];
this
.
_registerCharCode
(
mapping
.
code
,
false
,
false
,
false
,
mapping
.
value
);
}
// // Handle all left-over available digits
this
.
_registerAllCombos1
(
false
,
false
,
false
,
KeyboardEventCode
.
Digit1
,
KeyCode
.
KEY_1
);
this
.
_registerAllCombos1
(
false
,
false
,
false
,
KeyboardEventCode
.
Digit2
,
KeyCode
.
KEY_2
);
this
.
_registerAllCombos1
(
false
,
false
,
false
,
KeyboardEventCode
.
Digit3
,
KeyCode
.
KEY_3
);
this
.
_registerAllCombos1
(
false
,
false
,
false
,
KeyboardEventCode
.
Digit4
,
KeyCode
.
KEY_4
);
this
.
_registerAllCombos1
(
false
,
false
,
false
,
KeyboardEventCode
.
Digit5
,
KeyCode
.
KEY_5
);
this
.
_registerAllCombos1
(
false
,
false
,
false
,
KeyboardEventCode
.
Digit6
,
KeyCode
.
KEY_6
);
this
.
_registerAllCombos1
(
false
,
false
,
false
,
KeyboardEventCode
.
Digit7
,
KeyCode
.
KEY_7
);
this
.
_registerAllCombos1
(
false
,
false
,
false
,
KeyboardEventCode
.
Digit8
,
KeyCode
.
KEY_8
);
this
.
_registerAllCombos1
(
false
,
false
,
false
,
KeyboardEventCode
.
Digit9
,
KeyCode
.
KEY_9
);
this
.
_registerAllCombos1
(
false
,
false
,
false
,
KeyboardEventCode
.
Digit0
,
KeyCode
.
KEY_0
);
for
(
let
i
=
0
;
i
<
KeyboardEventCode
.
MAX_VALUE
;
i
++
)
{
let
base
=
(
i
<<
3
);
for
(
let
j
=
0
;
j
<
8
;
j
++
)
{
let
actual
=
base
+
j
;
let
entry
=
this
.
_hwToKb
[
actual
];
if
(
typeof
entry
===
'
undefined
'
)
{
log
(
`
${
KeyboardEventCodeUtils
.
toString
(
i
)}
-
${
j
.
toString
(
2
)}
--- is missing`
);
}
}
}
}
public
dumpDebugInfo
():
string
{
let
result
:
string
[]
=
[];
let
cnt
=
0
;
result
.
push
(
`--------------------------------------------------------------------------------------------------`
);
for
(
let
code
=
KeyboardEventCode
.
None
;
code
<
KeyboardEventCode
.
MAX_VALUE
;
code
++
)
{
if
(
IMMUTABLE_CODE_TO_KEY_CODE
[
code
]
!==
-
1
)
{
continue
;
}
if
(
cnt
%
4
===
0
)
{
result
.
push
(
`| HW Code combination | Key | KeyCode combination | UI label |`
);
result
.
push
(
`--------------------------------------------------------------------------------------------------`
);
}
cnt
++
;
const
mapping
=
this
.
_codeInfo
[
code
];
const
strCode
=
KeyboardEventCodeUtils
.
toString
(
code
);
const
uiLabel
=
this
.
_hwToLabel
[
code
];
for
(
let
mod
=
0
;
mod
<
8
;
mod
++
)
{
const
hwCtrlKey
=
(
mod
&
0b0001
)
?
true
:
false
;
const
hwShiftKey
=
(
mod
&
0b0010
)
?
true
:
false
;
const
hwAltKey
=
(
mod
&
0b0100
)
?
true
:
false
;
const
strHw
=
`
${
hwCtrlKey
?
'
Ctrl+
'
:
''
}${
hwShiftKey
?
'
Shift+
'
:
''
}${
hwAltKey
?
'
Alt+
'
:
''
}${
strCode
}
`
;
const
uiHwLabel
=
`
${
hwCtrlKey
?
'
Ctrl+
'
:
''
}${
hwShiftKey
?
'
Shift+
'
:
''
}${
hwAltKey
?
'
Alt+
'
:
''
}${
uiLabel
}
`
;
let
key
=
0
;
if
(
mapping
)
{
if
(
hwCtrlKey
&&
hwShiftKey
&&
hwAltKey
)
{
key
=
mapping
.
withShiftAltGr
;
}
else
if
(
hwCtrlKey
&&
hwAltKey
)
{
key
=
mapping
.
withAltGr
;
}
else
if
(
hwShiftKey
)
{
key
=
mapping
.
withShift
;
}
else
{
key
=
mapping
.
value
;
}
}
let
strKey
:
string
=
'
---
'
;
if
(
key
!==
0
)
{
if
(
key
>=
CharCode
.
U_Combining_Grave_Accent
&&
key
<=
CharCode
.
U_Combining_Latin_Small_Letter_X
)
{
// combining
strKey
=
'
U+
'
+
key
.
toString
(
16
);
}
else
{
strKey
=
'
'
+
String
.
fromCharCode
(
key
)
+
'
'
;
}
}
const
hwEncoded
=
this
.
_encode
(
hwCtrlKey
,
hwShiftKey
,
hwAltKey
,
code
);
const
kbEncoded
=
this
.
_hwToKb
[
hwEncoded
];
const
kbCtrlKey
=
(
kbEncoded
&
0b0001
)
?
true
:
false
;
const
kbShiftKey
=
(
kbEncoded
&
0b0010
)
?
true
:
false
;
const
kbAltKey
=
(
kbEncoded
&
0b0100
)
?
true
:
false
;
const
keyCode
=
(
kbEncoded
>>>
3
);
const
strKb
=
`
${
kbCtrlKey
?
'
Ctrl+
'
:
''
}${
kbShiftKey
?
'
Shift+
'
:
''
}${
kbAltKey
?
'
Alt+
'
:
''
}${
KeyCodeUtils
.
toString
(
keyCode
)}
`
;
result
.
push
(
`|
${
this
.
_leftPad
(
strHw
,
30
)}
|
${
strKey
}
|
${
this
.
_leftPad
(
strKb
,
25
)}
|
${
this
.
_leftPad
(
uiHwLabel
,
25
)}
|`
);
}
result
.
push
(
`--------------------------------------------------------------------------------------------------`
);
}
return
result
.
join
(
'
\n
'
);
}
private
_leftPad
(
str
:
string
,
cnt
:
number
):
string
{
while
(
str
.
length
<
cnt
)
{
str
=
'
'
+
str
;
}
return
str
;
}
private
_registerIfUnknown
(
hwCtrlKey
:
boolean
,
hwShiftKey
:
boolean
,
hwAltKey
:
boolean
,
code
:
KeyboardEventCode
,
kbCtrlKey
:
boolean
,
kbShiftKey
:
boolean
,
kbAltKey
:
boolean
,
keyCode
:
KeyCode
,
):
void
{
let
hwEncoded
=
this
.
_encode
(
hwCtrlKey
,
hwShiftKey
,
hwAltKey
,
code
);
let
kbEncoded
=
this
.
_encode
(
kbCtrlKey
,
kbShiftKey
,
kbAltKey
,
keyCode
);
let
existing
=
this
.
_hwToKb
[
hwEncoded
]
|
0
;
let
existingKeyCode
=
existing
>>>
3
;
if
(
existingKeyCode
!==
0
)
{
return
;
}
this
.
_hwToKb
[
hwEncoded
]
=
kbEncoded
;
this
.
_kbToHw
[
kbEncoded
]
=
this
.
_kbToHw
[
kbEncoded
]
||
[];
this
.
_kbToHw
[
kbEncoded
].
unshift
(
hwEncoded
);
}
private
_registerAllCombos1
(
_ctrlKey
:
boolean
,
_shiftKey
:
boolean
,
_altKey
:
boolean
,
code
:
KeyboardEventCode
,
keyCode
:
KeyCode
,
):
void
{
for
(
let
_ctrl
=
(
_ctrlKey
?
1
:
0
);
_ctrl
<=
1
;
_ctrl
++
)
{
const
ctrlKey
=
(
_ctrl
?
true
:
false
);
for
(
let
_shift
=
(
_shiftKey
?
1
:
0
);
_shift
<=
1
;
_shift
++
)
{
const
shiftKey
=
(
_shift
?
true
:
false
);
for
(
let
_alt
=
(
_altKey
?
1
:
0
);
_alt
<=
1
;
_alt
++
)
{
const
altKey
=
(
_alt
?
true
:
false
);
this
.
_registerIfUnknown
(
ctrlKey
,
shiftKey
,
altKey
,
code
,
ctrlKey
,
shiftKey
,
altKey
,
keyCode
);
}
}
}
}
private
_registerAllCombos2
(
hwCtrlKey
:
boolean
,
hwShiftKey
:
boolean
,
hwAltKey
:
boolean
,
code
:
KeyboardEventCode
,
kbShiftKey
:
boolean
,
keyCode
:
KeyCode
,
):
void
{
this
.
_registerIfUnknown
(
hwCtrlKey
,
hwShiftKey
,
hwAltKey
,
code
,
false
,
kbShiftKey
,
false
,
keyCode
);
if
(
!
kbShiftKey
)
{
for
(
let
_ctrl
=
(
hwCtrlKey
?
1
:
0
);
_ctrl
<=
1
;
_ctrl
++
)
{
const
ctrlKey
=
(
_ctrl
?
true
:
false
);
for
(
let
_alt
=
(
hwAltKey
?
1
:
0
);
_alt
<=
1
;
_alt
++
)
{
const
altKey
=
(
_alt
?
true
:
false
);
this
.
_registerIfUnknown
(
ctrlKey
,
hwShiftKey
,
altKey
,
code
,
ctrlKey
,
kbShiftKey
,
altKey
,
keyCode
);
this
.
_registerIfUnknown
(
ctrlKey
,
true
,
altKey
,
code
,
ctrlKey
,
true
,
altKey
,
keyCode
);
}
}
}
else
{
for
(
let
_ctrl
=
(
hwCtrlKey
?
1
:
0
);
_ctrl
<=
1
;
_ctrl
++
)
{
const
ctrlKey
=
(
_ctrl
?
true
:
false
);
for
(
let
_alt
=
(
hwAltKey
?
1
:
0
);
_alt
<=
1
;
_alt
++
)
{
const
altKey
=
(
_alt
?
true
:
false
);
this
.
_registerIfUnknown
(
ctrlKey
,
hwShiftKey
,
altKey
,
code
,
ctrlKey
,
kbShiftKey
,
altKey
,
keyCode
);
}
}
}
}
private
_registerCharCode
(
code
:
KeyboardEventCode
,
ctrlKey
:
boolean
,
shiftKey
:
boolean
,
altKey
:
boolean
,
charCode
:
number
):
void
{
let
_kb
=
KeyboardMapper
.
_charCodeToKb
(
charCode
);
let
kb
=
_kb
?
{
ctrlKey
:
false
,
shiftKey
:
_kb
.
shiftKey
,
altKey
:
false
,
keyCode
:
_kb
.
keyCode
}
:
null
;
if
(
!
_kb
)
{
this
.
_registerAllCombos1
(
ctrlKey
,
shiftKey
,
altKey
,
code
,
KeyCode
.
Unknown
);
return
;
}
this
.
_registerAllCombos2
(
ctrlKey
,
shiftKey
,
altKey
,
code
,
kb
.
shiftKey
,
kb
.
keyCode
);
}
public
simpleKeybindingToHardwareKeypress
(
keybinding
:
SimpleKeybinding
):
HardwareKeypress
[]
{
const
kbEncoded
=
this
.
_encode
(
keybinding
.
ctrlKey
,
keybinding
.
shiftKey
,
keybinding
.
altKey
,
keybinding
.
keyCode
);
const
hwEncoded
=
this
.
_kbToHw
[
kbEncoded
];
let
result
:
HardwareKeypress
[]
=
[];
if
(
hwEncoded
)
{
for
(
let
i
=
0
,
len
=
hwEncoded
.
length
;
i
<
len
;
i
++
)
{
result
[
i
]
=
this
.
_decodeHw
(
hwEncoded
[
i
],
keybinding
.
metaKey
);
}
}
return
result
;
}
public
getUILabelForHardwareCode
(
code
:
KeyboardEventCode
):
string
{
if
(
this
.
_OS
===
OperatingSystem
.
Macintosh
)
{
switch
(
code
)
{
case
KeyboardEventCode
.
ArrowLeft
:
return
'
←
'
;
case
KeyboardEventCode
.
ArrowUp
:
return
'
↑
'
;
case
KeyboardEventCode
.
ArrowRight
:
return
'
→
'
;
case
KeyboardEventCode
.
ArrowDown
:
return
'
↓
'
;
}
}
return
this
.
_hwToLabel
[
code
];
}
public
getAriaLabelForHardwareCode
(
code
:
KeyboardEventCode
):
string
{
return
this
.
_hwToLabel
[
code
];
}
public
resolveKeybinding
(
keybinding
:
Keybinding
):
NativeResolvedKeybinding
[]
{
let
result
:
NativeResolvedKeybinding
[]
=
[],
resultLen
=
0
;
if
(
keybinding
.
type
===
KeybindingType
.
Chord
)
{
const
firstParts
=
this
.
simpleKeybindingToHardwareKeypress
(
keybinding
.
firstPart
);
const
chordParts
=
this
.
simpleKeybindingToHardwareKeypress
(
keybinding
.
chordPart
);
for
(
let
i
=
0
,
len
=
firstParts
.
length
;
i
<
len
;
i
++
)
{
const
firstPart
=
firstParts
[
i
];
for
(
let
j
=
0
,
lenJ
=
chordParts
.
length
;
j
<
lenJ
;
j
++
)
{
const
chordPart
=
chordParts
[
j
];
result
[
resultLen
++
]
=
new
NativeResolvedKeybinding
(
this
,
this
.
_OS
,
firstPart
,
chordPart
);
}
}
}
else
{
const
firstParts
=
this
.
simpleKeybindingToHardwareKeypress
(
keybinding
);
for
(
let
i
=
0
,
len
=
firstParts
.
length
;
i
<
len
;
i
++
)
{
const
firstPart
=
firstParts
[
i
];
result
[
resultLen
++
]
=
new
NativeResolvedKeybinding
(
this
,
this
.
_OS
,
firstPart
,
null
);
}
}
return
result
;
}
private
static
_charCodeToKb
(
charCode
:
number
):
{
keyCode
:
KeyCode
;
shiftKey
:
boolean
}
{
if
(
charCode
<
CHAR_CODE_TO_KEY_CODE
.
length
)
{
return
CHAR_CODE_TO_KEY_CODE
[
charCode
];
}
return
null
;
}
/**
* Attempt to map a combining character to a regular one that renders the same way.
*
* To the brave person following me: Good Luck!
* https://www.compart.com/en/unicode/bidiclass/NSM
*/
private
static
_getCharCode
(
char
:
string
):
number
{
if
(
char
.
length
===
0
)
{
return
0
;
}
const
charCode
=
char
.
charCodeAt
(
0
);
switch
(
charCode
)
{
case
CharCode
.
U_Combining_Grave_Accent
:
return
CharCode
.
U_GRAVE_ACCENT
;
case
CharCode
.
U_Combining_Acute_Accent
:
return
CharCode
.
U_ACUTE_ACCENT
;
case
CharCode
.
U_Combining_Circumflex_Accent
:
return
CharCode
.
U_CIRCUMFLEX
;
case
CharCode
.
U_Combining_Tilde
:
return
CharCode
.
U_SMALL_TILDE
;
case
CharCode
.
U_Combining_Macron
:
return
CharCode
.
U_MACRON
;
case
CharCode
.
U_Combining_Overline
:
return
CharCode
.
U_OVERLINE
;
case
CharCode
.
U_Combining_Breve
:
return
CharCode
.
U_BREVE
;
case
CharCode
.
U_Combining_Dot_Above
:
return
CharCode
.
U_DOT_ABOVE
;
case
CharCode
.
U_Combining_Diaeresis
:
return
CharCode
.
U_DIAERESIS
;
case
CharCode
.
U_Combining_Ring_Above
:
return
CharCode
.
U_RING_ABOVE
;
case
CharCode
.
U_Combining_Double_Acute_Accent
:
return
CharCode
.
U_DOUBLE_ACUTE_ACCENT
;
}
return
charCode
;
}
private
_encode
(
ctrlKey
:
boolean
,
shiftKey
:
boolean
,
altKey
:
boolean
,
principal
:
number
):
number
{
return
(
((
ctrlKey
?
1
:
0
)
<<
0
)
|
((
shiftKey
?
1
:
0
)
<<
1
)
|
((
altKey
?
1
:
0
)
<<
2
)
|
principal
<<
3
)
>>>
0
;
}
private
_decodeHw
(
hwEncoded
:
number
,
metaKey
:
boolean
):
HardwareKeypress
{
const
ctrlKey
=
(
hwEncoded
&
0b0001
)
?
true
:
false
;
const
shiftKey
=
(
hwEncoded
&
0b0010
)
?
true
:
false
;
const
altKey
=
(
hwEncoded
&
0b0100
)
?
true
:
false
;
const
code
=
(
hwEncoded
>>>
3
);
return
new
HardwareKeypress
(
ctrlKey
,
shiftKey
,
altKey
,
metaKey
,
code
);
}
}
(
function
()
{
function
define
(
charCode
:
number
,
keyCode
:
KeyCode
,
shiftKey
:
boolean
):
void
{
for
(
let
i
=
CHAR_CODE_TO_KEY_CODE
.
length
;
i
<
charCode
;
i
++
)
{
CHAR_CODE_TO_KEY_CODE
[
i
]
=
null
;
}
CHAR_CODE_TO_KEY_CODE
[
charCode
]
=
{
keyCode
:
keyCode
,
shiftKey
:
shiftKey
};
}
for
(
let
chCode
=
CharCode
.
A
;
chCode
<=
CharCode
.
Z
;
chCode
++
)
{
define
(
chCode
,
KeyCode
.
KEY_A
+
(
chCode
-
CharCode
.
A
),
true
);
}
for
(
let
chCode
=
CharCode
.
a
;
chCode
<=
CharCode
.
z
;
chCode
++
)
{
define
(
chCode
,
KeyCode
.
KEY_A
+
(
chCode
-
CharCode
.
a
),
false
);
}
define
(
CharCode
.
Semicolon
,
KeyCode
.
US_SEMICOLON
,
false
);
define
(
CharCode
.
Colon
,
KeyCode
.
US_SEMICOLON
,
true
);
define
(
CharCode
.
Equals
,
KeyCode
.
US_EQUAL
,
false
);
define
(
CharCode
.
Plus
,
KeyCode
.
US_EQUAL
,
true
);
define
(
CharCode
.
Comma
,
KeyCode
.
US_COMMA
,
false
);
define
(
CharCode
.
LessThan
,
KeyCode
.
US_COMMA
,
true
);
define
(
CharCode
.
Dash
,
KeyCode
.
US_MINUS
,
false
);
define
(
CharCode
.
Underline
,
KeyCode
.
US_MINUS
,
true
);
define
(
CharCode
.
Period
,
KeyCode
.
US_DOT
,
false
);
define
(
CharCode
.
GreaterThan
,
KeyCode
.
US_DOT
,
true
);
define
(
CharCode
.
Slash
,
KeyCode
.
US_SLASH
,
false
);
define
(
CharCode
.
QuestionMark
,
KeyCode
.
US_SLASH
,
true
);
define
(
CharCode
.
BackTick
,
KeyCode
.
US_BACKTICK
,
false
);
define
(
CharCode
.
Tilde
,
KeyCode
.
US_BACKTICK
,
true
);
define
(
CharCode
.
OpenSquareBracket
,
KeyCode
.
US_OPEN_SQUARE_BRACKET
,
false
);
define
(
CharCode
.
OpenCurlyBrace
,
KeyCode
.
US_OPEN_SQUARE_BRACKET
,
true
);
define
(
CharCode
.
Backslash
,
KeyCode
.
US_BACKSLASH
,
false
);
define
(
CharCode
.
Pipe
,
KeyCode
.
US_BACKSLASH
,
true
);
define
(
CharCode
.
CloseSquareBracket
,
KeyCode
.
US_CLOSE_SQUARE_BRACKET
,
false
);
define
(
CharCode
.
CloseCurlyBrace
,
KeyCode
.
US_CLOSE_SQUARE_BRACKET
,
true
);
define
(
CharCode
.
SingleQuote
,
KeyCode
.
US_QUOTE
,
false
);
define
(
CharCode
.
DoubleQuote
,
KeyCode
.
US_QUOTE
,
true
);
})();
src/vs/workbench/services/keybinding/common/macLinuxKeyboardMapper.ts
0 → 100644
浏览文件 @
ebd346b3
/*---------------------------------------------------------------------------------------------
* 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
{
OperatingSystem
}
from
'
vs/base/common/platform
'
;
import
{
KeyCode
,
ResolvedKeybinding
,
KeyCodeUtils
,
SimpleKeybinding
,
Keybinding
,
KeybindingType
}
from
'
vs/base/common/keyCodes
'
;
import
{
KeyboardEventCode
,
KeyboardEventCodeUtils
,
IMMUTABLE_CODE_TO_KEY_CODE
}
from
'
vs/workbench/services/keybinding/common/keyboardEventCode
'
;
import
{
CharCode
}
from
'
vs/base/common/charCode
'
;
import
{
IHTMLContentElement
}
from
'
vs/base/common/htmlContent
'
;
import
{
UILabelProvider
,
AriaLabelProvider
}
from
'
vs/platform/keybinding/common/keybindingLabels
'
;
import
{
IKeyboardMapper
}
from
'
vs/workbench/services/keybinding/common/keyboardMapper
'
;
export
interface
IKeyMapping
{
value
:
string
;
withShift
:
string
;
withAltGr
:
string
;
withShiftAltGr
:
string
;
valueIsDeadKey
?:
boolean
;
withShiftIsDeadKey
?:
boolean
;
withAltGrIsDeadKey
?:
boolean
;
withShiftAltGrIsDeadKey
?:
boolean
;
}
export
interface
IKeyboardMapping
{
[
code
:
string
]:
IKeyMapping
;
}
const
LOG
=
false
;
function
log
(
str
:
string
):
void
{
if
(
LOG
)
{
console
.
info
(
str
);
}
}
const
CHAR_CODE_TO_KEY_CODE
:
{
keyCode
:
KeyCode
;
shiftKey
:
boolean
}[]
=
[];
export
class
HardwareKeypress
{
public
readonly
ctrlKey
:
boolean
;
public
readonly
shiftKey
:
boolean
;
public
readonly
altKey
:
boolean
;
public
readonly
metaKey
:
boolean
;
public
readonly
code
:
KeyboardEventCode
;
constructor
(
ctrlKey
:
boolean
,
shiftKey
:
boolean
,
altKey
:
boolean
,
metaKey
:
boolean
,
code
:
KeyboardEventCode
)
{
this
.
ctrlKey
=
ctrlKey
;
this
.
shiftKey
=
shiftKey
;
this
.
altKey
=
altKey
;
this
.
metaKey
=
metaKey
;
this
.
code
=
code
;
}
}
export
class
NativeResolvedKeybinding
extends
ResolvedKeybinding
{
private
readonly
_mapper
:
MacLinuxKeyboardMapper
;
private
readonly
_OS
:
OperatingSystem
;
private
readonly
_firstPart
:
HardwareKeypress
;
private
readonly
_chordPart
:
HardwareKeypress
;
constructor
(
mapper
:
MacLinuxKeyboardMapper
,
OS
:
OperatingSystem
,
firstPart
:
HardwareKeypress
,
chordPart
:
HardwareKeypress
)
{
super
();
this
.
_mapper
=
mapper
;
this
.
_OS
=
OS
;
this
.
_firstPart
=
firstPart
;
this
.
_chordPart
=
chordPart
;
}
public
getLabel
():
string
{
let
firstPart
=
this
.
_firstPart
?
this
.
_mapper
.
getUILabelForHardwareCode
(
this
.
_firstPart
.
code
)
:
null
;
let
chordPart
=
this
.
_chordPart
?
this
.
_mapper
.
getUILabelForHardwareCode
(
this
.
_chordPart
.
code
)
:
null
;
return
UILabelProvider
.
toLabel
(
this
.
_firstPart
,
firstPart
,
this
.
_chordPart
,
chordPart
,
this
.
_OS
);
}
public
getAriaLabel
():
string
{
let
firstPart
=
this
.
_firstPart
?
this
.
_mapper
.
getAriaLabelForHardwareCode
(
this
.
_firstPart
.
code
)
:
null
;
let
chordPart
=
this
.
_chordPart
?
this
.
_mapper
.
getAriaLabelForHardwareCode
(
this
.
_chordPart
.
code
)
:
null
;
return
AriaLabelProvider
.
toLabel
(
this
.
_firstPart
,
firstPart
,
this
.
_chordPart
,
chordPart
,
this
.
_OS
);
}
public
getHTMLLabel
():
IHTMLContentElement
[]
{
let
firstPart
=
this
.
_firstPart
?
this
.
_mapper
.
getUILabelForHardwareCode
(
this
.
_firstPart
.
code
)
:
null
;
let
chordPart
=
this
.
_chordPart
?
this
.
_mapper
.
getUILabelForHardwareCode
(
this
.
_chordPart
.
code
)
:
null
;
return
UILabelProvider
.
toHTMLLabel
(
this
.
_firstPart
,
firstPart
,
this
.
_chordPart
,
chordPart
,
this
.
_OS
);
}
public
getElectronAccelerator
():
string
{
throw
new
Error
(
'
TODO!
'
);
// const usResolvedKeybinding = new USLayoutResolvedKeybinding(this._actual, OS);
// if (OS === OperatingSystem.Windows) {
// // electron menus always do the correct rendering on Windows
// return usResolvedKeybinding.getElectronAccelerator();
// }
// let usLabel = usResolvedKeybinding.getLabel();
// let label = this.getLabel();
// if (usLabel !== label) {
// // electron menus are incorrect in rendering (linux) and in rendering and interpreting (mac)
// // for non US standard keyboard layouts
// return null;
// }
// return usResolvedKeybinding.getElectronAccelerator();
}
public
getUserSettingsLabel
():
string
{
throw
new
Error
(
'
TODO!
'
);
// return KeybindingIO.writeKeybinding(this._actual, OS);
}
public
isChord
():
boolean
{
throw
new
Error
(
'
TODO!
'
);
}
public
hasCtrlModifier
():
boolean
{
throw
new
Error
(
'
TODO!
'
);
}
public
hasShiftModifier
():
boolean
{
throw
new
Error
(
'
TODO!
'
);
}
public
hasAltModifier
():
boolean
{
throw
new
Error
(
'
TODO!
'
);
}
public
hasMetaModifier
():
boolean
{
throw
new
Error
(
'
TODO!
'
);
}
public
getDispatchParts
():
[
string
,
string
]
{
throw
new
Error
(
'
TODO!
'
);
}
}
interface
IHardwareCodeMapping
{
code
:
KeyboardEventCode
;
value
:
number
;
withShift
:
number
;
withAltGr
:
number
;
withShiftAltGr
:
number
;
}
export
class
MacLinuxKeyboardMapper
implements
IKeyboardMapper
{
private
readonly
_OS
:
OperatingSystem
;
private
readonly
_codeInfo
:
IHardwareCodeMapping
[];
private
readonly
_hwToKb
:
number
[]
=
[];
private
readonly
_hwToLabel
:
string
[]
=
[];
private
readonly
_kbToHw
:
number
[][]
=
[];
constructor
(
rawMappings
:
IKeyboardMapping
,
OS
:
OperatingSystem
)
{
this
.
_OS
=
OS
;
this
.
_hwToKb
=
[];
this
.
_kbToHw
=
[];
this
.
_hwToLabel
=
[];
for
(
let
code
=
KeyboardEventCode
.
None
;
code
<
KeyboardEventCode
.
MAX_VALUE
;
code
++
)
{
const
immutableKeyCode
=
IMMUTABLE_CODE_TO_KEY_CODE
[
code
];
if
(
immutableKeyCode
!==
-
1
)
{
this
.
_registerAllCombos1
(
false
,
false
,
false
,
code
,
immutableKeyCode
);
this
.
_hwToLabel
[
code
]
=
KeyCodeUtils
.
toString
(
immutableKeyCode
);
}
}
this
.
_codeInfo
=
[];
let
mappings
:
IHardwareCodeMapping
[]
=
[],
mappingsLen
=
0
;
for
(
let
strCode
in
rawMappings
)
{
if
(
rawMappings
.
hasOwnProperty
(
strCode
))
{
const
code
=
KeyboardEventCodeUtils
.
toEnum
(
strCode
);
if
(
code
===
KeyboardEventCode
.
None
)
{
log
(
`Unknown code
${
strCode
}
in mapping.`
);
continue
;
}
if
(
IMMUTABLE_CODE_TO_KEY_CODE
[
code
]
!==
-
1
)
{
continue
;
}
const
rawMapping
=
rawMappings
[
strCode
];
const
value
=
MacLinuxKeyboardMapper
.
_getCharCode
(
rawMapping
.
value
);
const
withShift
=
MacLinuxKeyboardMapper
.
_getCharCode
(
rawMapping
.
withShift
);
const
withAltGr
=
MacLinuxKeyboardMapper
.
_getCharCode
(
rawMapping
.
withAltGr
);
const
withShiftAltGr
=
MacLinuxKeyboardMapper
.
_getCharCode
(
rawMapping
.
withShiftAltGr
);
const
mapping
:
IHardwareCodeMapping
=
{
code
:
code
,
value
:
value
,
withShift
:
withShift
,
withAltGr
:
withAltGr
,
withShiftAltGr
:
withShiftAltGr
,
};
mappings
[
mappingsLen
++
]
=
mapping
;
this
.
_codeInfo
[
code
]
=
mapping
;
if
(
value
>=
CharCode
.
a
&&
value
<=
CharCode
.
z
)
{
this
.
_hwToLabel
[
code
]
=
String
.
fromCharCode
(
CharCode
.
A
+
(
value
-
CharCode
.
a
));
}
else
if
(
value
)
{
this
.
_hwToLabel
[
code
]
=
String
.
fromCharCode
(
value
);
}
else
{
this
.
_hwToLabel
[
code
]
=
null
;
}
}
}
// Handle all `withShiftAltGr` entries
for
(
let
i
=
mappings
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
mapping
=
mappings
[
i
];
const
withShiftAltGr
=
mapping
.
withShiftAltGr
;
if
(
withShiftAltGr
===
mapping
.
withAltGr
||
withShiftAltGr
===
mapping
.
withShift
||
withShiftAltGr
===
mapping
.
value
)
{
// handled below
continue
;
}
this
.
_registerCharCode
(
mapping
.
code
,
true
,
true
,
true
,
withShiftAltGr
);
}
// Handle all `withAltGr` entries
for
(
let
i
=
mappings
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
mapping
=
mappings
[
i
];
const
withAltGr
=
mapping
.
withAltGr
;
if
(
withAltGr
===
mapping
.
withShift
||
withAltGr
===
mapping
.
value
)
{
// handled below
continue
;
}
this
.
_registerCharCode
(
mapping
.
code
,
true
,
false
,
true
,
withAltGr
);
}
// Handle all `withShift` entries
for
(
let
i
=
mappings
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
mapping
=
mappings
[
i
];
const
withShift
=
mapping
.
withShift
;
if
(
withShift
===
mapping
.
value
)
{
// handled below
continue
;
}
this
.
_registerCharCode
(
mapping
.
code
,
false
,
true
,
false
,
withShift
);
}
// Handle all `value` entries
for
(
let
i
=
mappings
.
length
-
1
;
i
>=
0
;
i
--
)
{
const
mapping
=
mappings
[
i
];
this
.
_registerCharCode
(
mapping
.
code
,
false
,
false
,
false
,
mapping
.
value
);
}
// // Handle all left-over available digits
this
.
_registerAllCombos1
(
false
,
false
,
false
,
KeyboardEventCode
.
Digit1
,
KeyCode
.
KEY_1
);
this
.
_registerAllCombos1
(
false
,
false
,
false
,
KeyboardEventCode
.
Digit2
,
KeyCode
.
KEY_2
);
this
.
_registerAllCombos1
(
false
,
false
,
false
,
KeyboardEventCode
.
Digit3
,
KeyCode
.
KEY_3
);
this
.
_registerAllCombos1
(
false
,
false
,
false
,
KeyboardEventCode
.
Digit4
,
KeyCode
.
KEY_4
);
this
.
_registerAllCombos1
(
false
,
false
,
false
,
KeyboardEventCode
.
Digit5
,
KeyCode
.
KEY_5
);
this
.
_registerAllCombos1
(
false
,
false
,
false
,
KeyboardEventCode
.
Digit6
,
KeyCode
.
KEY_6
);
this
.
_registerAllCombos1
(
false
,
false
,
false
,
KeyboardEventCode
.
Digit7
,
KeyCode
.
KEY_7
);
this
.
_registerAllCombos1
(
false
,
false
,
false
,
KeyboardEventCode
.
Digit8
,
KeyCode
.
KEY_8
);
this
.
_registerAllCombos1
(
false
,
false
,
false
,
KeyboardEventCode
.
Digit9
,
KeyCode
.
KEY_9
);
this
.
_registerAllCombos1
(
false
,
false
,
false
,
KeyboardEventCode
.
Digit0
,
KeyCode
.
KEY_0
);
for
(
let
i
=
0
;
i
<
KeyboardEventCode
.
MAX_VALUE
;
i
++
)
{
let
base
=
(
i
<<
3
);
for
(
let
j
=
0
;
j
<
8
;
j
++
)
{
let
actual
=
base
+
j
;
let
entry
=
this
.
_hwToKb
[
actual
];
if
(
typeof
entry
===
'
undefined
'
)
{
log
(
`
${
KeyboardEventCodeUtils
.
toString
(
i
)}
-
${
j
.
toString
(
2
)}
--- is missing`
);
}
}
}
}
public
dumpDebugInfo
():
string
{
let
result
:
string
[]
=
[];
let
cnt
=
0
;
result
.
push
(
`--------------------------------------------------------------------------------------------------`
);
for
(
let
code
=
KeyboardEventCode
.
None
;
code
<
KeyboardEventCode
.
MAX_VALUE
;
code
++
)
{
if
(
IMMUTABLE_CODE_TO_KEY_CODE
[
code
]
!==
-
1
)
{
continue
;
}
if
(
cnt
%
4
===
0
)
{
result
.
push
(
`| HW Code combination | Key | KeyCode combination | UI label |`
);
result
.
push
(
`--------------------------------------------------------------------------------------------------`
);
}
cnt
++
;
const
mapping
=
this
.
_codeInfo
[
code
];
const
strCode
=
KeyboardEventCodeUtils
.
toString
(
code
);
const
uiLabel
=
this
.
_hwToLabel
[
code
];
for
(
let
mod
=
0
;
mod
<
8
;
mod
++
)
{
const
hwCtrlKey
=
(
mod
&
0b0001
)
?
true
:
false
;
const
hwShiftKey
=
(
mod
&
0b0010
)
?
true
:
false
;
const
hwAltKey
=
(
mod
&
0b0100
)
?
true
:
false
;
const
strHw
=
`
${
hwCtrlKey
?
'
Ctrl+
'
:
''
}${
hwShiftKey
?
'
Shift+
'
:
''
}${
hwAltKey
?
'
Alt+
'
:
''
}${
strCode
}
`
;
const
uiHwLabel
=
`
${
hwCtrlKey
?
'
Ctrl+
'
:
''
}${
hwShiftKey
?
'
Shift+
'
:
''
}${
hwAltKey
?
'
Alt+
'
:
''
}${
uiLabel
}
`
;
let
key
=
0
;
if
(
mapping
)
{
if
(
hwCtrlKey
&&
hwShiftKey
&&
hwAltKey
)
{
key
=
mapping
.
withShiftAltGr
;
}
else
if
(
hwCtrlKey
&&
hwAltKey
)
{
key
=
mapping
.
withAltGr
;
}
else
if
(
hwShiftKey
)
{
key
=
mapping
.
withShift
;
}
else
{
key
=
mapping
.
value
;
}
}
let
strKey
:
string
=
'
---
'
;
if
(
key
!==
0
)
{
if
(
key
>=
CharCode
.
U_Combining_Grave_Accent
&&
key
<=
CharCode
.
U_Combining_Latin_Small_Letter_X
)
{
// combining
strKey
=
'
U+
'
+
key
.
toString
(
16
);
}
else
{
strKey
=
'
'
+
String
.
fromCharCode
(
key
)
+
'
'
;
}
}
const
hwEncoded
=
this
.
_encode
(
hwCtrlKey
,
hwShiftKey
,
hwAltKey
,
code
);
const
kbEncoded
=
this
.
_hwToKb
[
hwEncoded
];
const
kbCtrlKey
=
(
kbEncoded
&
0b0001
)
?
true
:
false
;
const
kbShiftKey
=
(
kbEncoded
&
0b0010
)
?
true
:
false
;
const
kbAltKey
=
(
kbEncoded
&
0b0100
)
?
true
:
false
;
const
keyCode
=
(
kbEncoded
>>>
3
);
const
strKb
=
`
${
kbCtrlKey
?
'
Ctrl+
'
:
''
}${
kbShiftKey
?
'
Shift+
'
:
''
}${
kbAltKey
?
'
Alt+
'
:
''
}${
KeyCodeUtils
.
toString
(
keyCode
)}
`
;
result
.
push
(
`|
${
this
.
_leftPad
(
strHw
,
30
)}
|
${
strKey
}
|
${
this
.
_leftPad
(
strKb
,
25
)}
|
${
this
.
_leftPad
(
uiHwLabel
,
25
)}
|`
);
}
result
.
push
(
`--------------------------------------------------------------------------------------------------`
);
}
return
result
.
join
(
'
\n
'
);
}
private
_leftPad
(
str
:
string
,
cnt
:
number
):
string
{
while
(
str
.
length
<
cnt
)
{
str
=
'
'
+
str
;
}
return
str
;
}
private
_registerIfUnknown
(
hwCtrlKey
:
boolean
,
hwShiftKey
:
boolean
,
hwAltKey
:
boolean
,
code
:
KeyboardEventCode
,
kbCtrlKey
:
boolean
,
kbShiftKey
:
boolean
,
kbAltKey
:
boolean
,
keyCode
:
KeyCode
,
):
void
{
let
hwEncoded
=
this
.
_encode
(
hwCtrlKey
,
hwShiftKey
,
hwAltKey
,
code
);
let
kbEncoded
=
this
.
_encode
(
kbCtrlKey
,
kbShiftKey
,
kbAltKey
,
keyCode
);
let
existing
=
this
.
_hwToKb
[
hwEncoded
]
|
0
;
let
existingKeyCode
=
existing
>>>
3
;
if
(
existingKeyCode
!==
0
)
{
return
;
}
this
.
_hwToKb
[
hwEncoded
]
=
kbEncoded
;
this
.
_kbToHw
[
kbEncoded
]
=
this
.
_kbToHw
[
kbEncoded
]
||
[];
this
.
_kbToHw
[
kbEncoded
].
unshift
(
hwEncoded
);
}
private
_registerAllCombos1
(
_ctrlKey
:
boolean
,
_shiftKey
:
boolean
,
_altKey
:
boolean
,
code
:
KeyboardEventCode
,
keyCode
:
KeyCode
,
):
void
{
for
(
let
_ctrl
=
(
_ctrlKey
?
1
:
0
);
_ctrl
<=
1
;
_ctrl
++
)
{
const
ctrlKey
=
(
_ctrl
?
true
:
false
);
for
(
let
_shift
=
(
_shiftKey
?
1
:
0
);
_shift
<=
1
;
_shift
++
)
{
const
shiftKey
=
(
_shift
?
true
:
false
);
for
(
let
_alt
=
(
_altKey
?
1
:
0
);
_alt
<=
1
;
_alt
++
)
{
const
altKey
=
(
_alt
?
true
:
false
);
this
.
_registerIfUnknown
(
ctrlKey
,
shiftKey
,
altKey
,
code
,
ctrlKey
,
shiftKey
,
altKey
,
keyCode
);
}
}
}
}
private
_registerAllCombos2
(
hwCtrlKey
:
boolean
,
hwShiftKey
:
boolean
,
hwAltKey
:
boolean
,
code
:
KeyboardEventCode
,
kbShiftKey
:
boolean
,
keyCode
:
KeyCode
,
):
void
{
this
.
_registerIfUnknown
(
hwCtrlKey
,
hwShiftKey
,
hwAltKey
,
code
,
false
,
kbShiftKey
,
false
,
keyCode
);
if
(
!
kbShiftKey
)
{
for
(
let
_ctrl
=
(
hwCtrlKey
?
1
:
0
);
_ctrl
<=
1
;
_ctrl
++
)
{
const
ctrlKey
=
(
_ctrl
?
true
:
false
);
for
(
let
_alt
=
(
hwAltKey
?
1
:
0
);
_alt
<=
1
;
_alt
++
)
{
const
altKey
=
(
_alt
?
true
:
false
);
this
.
_registerIfUnknown
(
ctrlKey
,
hwShiftKey
,
altKey
,
code
,
ctrlKey
,
kbShiftKey
,
altKey
,
keyCode
);
this
.
_registerIfUnknown
(
ctrlKey
,
true
,
altKey
,
code
,
ctrlKey
,
true
,
altKey
,
keyCode
);
}
}
}
else
{
for
(
let
_ctrl
=
(
hwCtrlKey
?
1
:
0
);
_ctrl
<=
1
;
_ctrl
++
)
{
const
ctrlKey
=
(
_ctrl
?
true
:
false
);
for
(
let
_alt
=
(
hwAltKey
?
1
:
0
);
_alt
<=
1
;
_alt
++
)
{
const
altKey
=
(
_alt
?
true
:
false
);
this
.
_registerIfUnknown
(
ctrlKey
,
hwShiftKey
,
altKey
,
code
,
ctrlKey
,
kbShiftKey
,
altKey
,
keyCode
);
}
}
}
}
private
_registerCharCode
(
code
:
KeyboardEventCode
,
ctrlKey
:
boolean
,
shiftKey
:
boolean
,
altKey
:
boolean
,
charCode
:
number
):
void
{
let
_kb
=
MacLinuxKeyboardMapper
.
_charCodeToKb
(
charCode
);
let
kb
=
_kb
?
{
ctrlKey
:
false
,
shiftKey
:
_kb
.
shiftKey
,
altKey
:
false
,
keyCode
:
_kb
.
keyCode
}
:
null
;
if
(
!
_kb
)
{
this
.
_registerAllCombos1
(
ctrlKey
,
shiftKey
,
altKey
,
code
,
KeyCode
.
Unknown
);
return
;
}
this
.
_registerAllCombos2
(
ctrlKey
,
shiftKey
,
altKey
,
code
,
kb
.
shiftKey
,
kb
.
keyCode
);
}
public
simpleKeybindingToHardwareKeypress
(
keybinding
:
SimpleKeybinding
):
HardwareKeypress
[]
{
const
kbEncoded
=
this
.
_encode
(
keybinding
.
ctrlKey
,
keybinding
.
shiftKey
,
keybinding
.
altKey
,
keybinding
.
keyCode
);
const
hwEncoded
=
this
.
_kbToHw
[
kbEncoded
];
let
result
:
HardwareKeypress
[]
=
[];
if
(
hwEncoded
)
{
for
(
let
i
=
0
,
len
=
hwEncoded
.
length
;
i
<
len
;
i
++
)
{
result
[
i
]
=
this
.
_decodeHw
(
hwEncoded
[
i
],
keybinding
.
metaKey
);
}
}
return
result
;
}
public
getUILabelForHardwareCode
(
code
:
KeyboardEventCode
):
string
{
if
(
this
.
_OS
===
OperatingSystem
.
Macintosh
)
{
switch
(
code
)
{
case
KeyboardEventCode
.
ArrowLeft
:
return
'
←
'
;
case
KeyboardEventCode
.
ArrowUp
:
return
'
↑
'
;
case
KeyboardEventCode
.
ArrowRight
:
return
'
→
'
;
case
KeyboardEventCode
.
ArrowDown
:
return
'
↓
'
;
}
}
return
this
.
_hwToLabel
[
code
];
}
public
getAriaLabelForHardwareCode
(
code
:
KeyboardEventCode
):
string
{
return
this
.
_hwToLabel
[
code
];
}
public
resolveKeybinding
(
keybinding
:
Keybinding
):
NativeResolvedKeybinding
[]
{
let
result
:
NativeResolvedKeybinding
[]
=
[],
resultLen
=
0
;
if
(
keybinding
.
type
===
KeybindingType
.
Chord
)
{
const
firstParts
=
this
.
simpleKeybindingToHardwareKeypress
(
keybinding
.
firstPart
);
const
chordParts
=
this
.
simpleKeybindingToHardwareKeypress
(
keybinding
.
chordPart
);
for
(
let
i
=
0
,
len
=
firstParts
.
length
;
i
<
len
;
i
++
)
{
const
firstPart
=
firstParts
[
i
];
for
(
let
j
=
0
,
lenJ
=
chordParts
.
length
;
j
<
lenJ
;
j
++
)
{
const
chordPart
=
chordParts
[
j
];
result
[
resultLen
++
]
=
new
NativeResolvedKeybinding
(
this
,
this
.
_OS
,
firstPart
,
chordPart
);
}
}
}
else
{
const
firstParts
=
this
.
simpleKeybindingToHardwareKeypress
(
keybinding
);
for
(
let
i
=
0
,
len
=
firstParts
.
length
;
i
<
len
;
i
++
)
{
const
firstPart
=
firstParts
[
i
];
result
[
resultLen
++
]
=
new
NativeResolvedKeybinding
(
this
,
this
.
_OS
,
firstPart
,
null
);
}
}
return
result
;
}
private
static
_charCodeToKb
(
charCode
:
number
):
{
keyCode
:
KeyCode
;
shiftKey
:
boolean
}
{
if
(
charCode
<
CHAR_CODE_TO_KEY_CODE
.
length
)
{
return
CHAR_CODE_TO_KEY_CODE
[
charCode
];
}
return
null
;
}
/**
* Attempt to map a combining character to a regular one that renders the same way.
*
* To the brave person following me: Good Luck!
* https://www.compart.com/en/unicode/bidiclass/NSM
*/
private
static
_getCharCode
(
char
:
string
):
number
{
if
(
char
.
length
===
0
)
{
return
0
;
}
const
charCode
=
char
.
charCodeAt
(
0
);
switch
(
charCode
)
{
case
CharCode
.
U_Combining_Grave_Accent
:
return
CharCode
.
U_GRAVE_ACCENT
;
case
CharCode
.
U_Combining_Acute_Accent
:
return
CharCode
.
U_ACUTE_ACCENT
;
case
CharCode
.
U_Combining_Circumflex_Accent
:
return
CharCode
.
U_CIRCUMFLEX
;
case
CharCode
.
U_Combining_Tilde
:
return
CharCode
.
U_SMALL_TILDE
;
case
CharCode
.
U_Combining_Macron
:
return
CharCode
.
U_MACRON
;
case
CharCode
.
U_Combining_Overline
:
return
CharCode
.
U_OVERLINE
;
case
CharCode
.
U_Combining_Breve
:
return
CharCode
.
U_BREVE
;
case
CharCode
.
U_Combining_Dot_Above
:
return
CharCode
.
U_DOT_ABOVE
;
case
CharCode
.
U_Combining_Diaeresis
:
return
CharCode
.
U_DIAERESIS
;
case
CharCode
.
U_Combining_Ring_Above
:
return
CharCode
.
U_RING_ABOVE
;
case
CharCode
.
U_Combining_Double_Acute_Accent
:
return
CharCode
.
U_DOUBLE_ACUTE_ACCENT
;
}
return
charCode
;
}
private
_encode
(
ctrlKey
:
boolean
,
shiftKey
:
boolean
,
altKey
:
boolean
,
principal
:
number
):
number
{
return
(
((
ctrlKey
?
1
:
0
)
<<
0
)
|
((
shiftKey
?
1
:
0
)
<<
1
)
|
((
altKey
?
1
:
0
)
<<
2
)
|
principal
<<
3
)
>>>
0
;
}
private
_decodeHw
(
hwEncoded
:
number
,
metaKey
:
boolean
):
HardwareKeypress
{
const
ctrlKey
=
(
hwEncoded
&
0b0001
)
?
true
:
false
;
const
shiftKey
=
(
hwEncoded
&
0b0010
)
?
true
:
false
;
const
altKey
=
(
hwEncoded
&
0b0100
)
?
true
:
false
;
const
code
=
(
hwEncoded
>>>
3
);
return
new
HardwareKeypress
(
ctrlKey
,
shiftKey
,
altKey
,
metaKey
,
code
);
}
}
(
function
()
{
function
define
(
charCode
:
number
,
keyCode
:
KeyCode
,
shiftKey
:
boolean
):
void
{
for
(
let
i
=
CHAR_CODE_TO_KEY_CODE
.
length
;
i
<
charCode
;
i
++
)
{
CHAR_CODE_TO_KEY_CODE
[
i
]
=
null
;
}
CHAR_CODE_TO_KEY_CODE
[
charCode
]
=
{
keyCode
:
keyCode
,
shiftKey
:
shiftKey
};
}
for
(
let
chCode
=
CharCode
.
A
;
chCode
<=
CharCode
.
Z
;
chCode
++
)
{
define
(
chCode
,
KeyCode
.
KEY_A
+
(
chCode
-
CharCode
.
A
),
true
);
}
for
(
let
chCode
=
CharCode
.
a
;
chCode
<=
CharCode
.
z
;
chCode
++
)
{
define
(
chCode
,
KeyCode
.
KEY_A
+
(
chCode
-
CharCode
.
a
),
false
);
}
define
(
CharCode
.
Semicolon
,
KeyCode
.
US_SEMICOLON
,
false
);
define
(
CharCode
.
Colon
,
KeyCode
.
US_SEMICOLON
,
true
);
define
(
CharCode
.
Equals
,
KeyCode
.
US_EQUAL
,
false
);
define
(
CharCode
.
Plus
,
KeyCode
.
US_EQUAL
,
true
);
define
(
CharCode
.
Comma
,
KeyCode
.
US_COMMA
,
false
);
define
(
CharCode
.
LessThan
,
KeyCode
.
US_COMMA
,
true
);
define
(
CharCode
.
Dash
,
KeyCode
.
US_MINUS
,
false
);
define
(
CharCode
.
Underline
,
KeyCode
.
US_MINUS
,
true
);
define
(
CharCode
.
Period
,
KeyCode
.
US_DOT
,
false
);
define
(
CharCode
.
GreaterThan
,
KeyCode
.
US_DOT
,
true
);
define
(
CharCode
.
Slash
,
KeyCode
.
US_SLASH
,
false
);
define
(
CharCode
.
QuestionMark
,
KeyCode
.
US_SLASH
,
true
);
define
(
CharCode
.
BackTick
,
KeyCode
.
US_BACKTICK
,
false
);
define
(
CharCode
.
Tilde
,
KeyCode
.
US_BACKTICK
,
true
);
define
(
CharCode
.
OpenSquareBracket
,
KeyCode
.
US_OPEN_SQUARE_BRACKET
,
false
);
define
(
CharCode
.
OpenCurlyBrace
,
KeyCode
.
US_OPEN_SQUARE_BRACKET
,
true
);
define
(
CharCode
.
Backslash
,
KeyCode
.
US_BACKSLASH
,
false
);
define
(
CharCode
.
Pipe
,
KeyCode
.
US_BACKSLASH
,
true
);
define
(
CharCode
.
CloseSquareBracket
,
KeyCode
.
US_CLOSE_SQUARE_BRACKET
,
false
);
define
(
CharCode
.
CloseCurlyBrace
,
KeyCode
.
US_CLOSE_SQUARE_BRACKET
,
true
);
define
(
CharCode
.
SingleQuote
,
KeyCode
.
US_QUOTE
,
false
);
define
(
CharCode
.
DoubleQuote
,
KeyCode
.
US_QUOTE
,
true
);
})();
src/vs/workbench/services/keybinding/common/windowsKeyboardMapper.ts
浏览文件 @
ebd346b3
...
@@ -11,6 +11,7 @@ import { CharCode } from 'vs/base/common/charCode';
...
@@ -11,6 +11,7 @@ import { CharCode } from 'vs/base/common/charCode';
import
{
UILabelProvider
,
AriaLabelProvider
,
ElectronAcceleratorLabelProvider
,
UserSettingsLabelProvider
}
from
'
vs/platform/keybinding/common/keybindingLabels
'
;
import
{
UILabelProvider
,
AriaLabelProvider
,
ElectronAcceleratorLabelProvider
,
UserSettingsLabelProvider
}
from
'
vs/platform/keybinding/common/keybindingLabels
'
;
import
{
OperatingSystem
}
from
'
vs/base/common/platform
'
;
import
{
OperatingSystem
}
from
'
vs/base/common/platform
'
;
import
{
IHTMLContentElement
}
from
'
vs/base/common/htmlContent
'
;
import
{
IHTMLContentElement
}
from
'
vs/base/common/htmlContent
'
;
import
{
IKeyboardMapper
}
from
'
vs/workbench/services/keybinding/common/keyboardMapper
'
;
export
interface
IKeyMapping
{
export
interface
IKeyMapping
{
vkey
:
string
;
vkey
:
string
;
...
@@ -173,7 +174,7 @@ export class WindowsNativeResolvedKeybinding extends ResolvedKeybinding {
...
@@ -173,7 +174,7 @@ export class WindowsNativeResolvedKeybinding extends ResolvedKeybinding {
}
}
}
}
export
class
WindowsKeyboardMapper
{
export
class
WindowsKeyboardMapper
implements
IKeyboardMapper
{
private
readonly
_codeInfo
:
IHardwareCodeMapping
[];
private
readonly
_codeInfo
:
IHardwareCodeMapping
[];
private
readonly
_hwToKb
:
KeyCode
[];
private
readonly
_hwToKb
:
KeyCode
[];
...
...
src/vs/workbench/services/keybinding/test/keyboardMapperTestUtils.ts
0 → 100644
浏览文件 @
ebd346b3
/*---------------------------------------------------------------------------------------------
* 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
{
IHTMLContentElement
}
from
'
vs/base/common/htmlContent
'
;
import
{
IKeyboardMapper
}
from
'
vs/workbench/services/keybinding/common/keyboardMapper
'
;
import
{
Keybinding
}
from
'
vs/base/common/keyCodes
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
readFile
,
writeFile
}
from
'
vs/base/node/pfs
'
;
export
interface
IResolvedKeybinding
{
label
:
string
;
ariaLabel
:
string
;
HTMLLabel
:
IHTMLContentElement
[];
electronAccelerator
:
string
;
userSettingsLabel
:
string
;
isChord
:
boolean
;
hasCtrlModifier
:
boolean
;
hasShiftModifier
:
boolean
;
hasAltModifier
:
boolean
;
hasMetaModifier
:
boolean
;
dispatchParts
:
[
string
,
string
];
}
export
function
assertResolveKeybinding
(
mapper
:
IKeyboardMapper
,
keybinding
:
Keybinding
,
expected
:
IResolvedKeybinding
[]):
void
{
let
actual
:
IResolvedKeybinding
[]
=
mapper
.
resolveKeybinding
(
keybinding
).
map
((
kb
=>
{
return
{
label
:
kb
.
getLabel
(),
ariaLabel
:
kb
.
getAriaLabel
(),
HTMLLabel
:
kb
.
getHTMLLabel
(),
electronAccelerator
:
kb
.
getElectronAccelerator
(),
userSettingsLabel
:
kb
.
getUserSettingsLabel
(),
isChord
:
kb
.
isChord
(),
hasCtrlModifier
:
kb
.
hasCtrlModifier
(),
hasShiftModifier
:
kb
.
hasShiftModifier
(),
hasAltModifier
:
kb
.
hasAltModifier
(),
hasMetaModifier
:
kb
.
hasMetaModifier
(),
dispatchParts
:
kb
.
getDispatchParts
(),
};
}));
assert
.
deepEqual
(
actual
,
expected
);
}
function
_htmlPieces
(
pieces
:
string
[]):
IHTMLContentElement
[]
{
let
children
:
IHTMLContentElement
[]
=
[];
for
(
let
i
=
0
,
len
=
pieces
.
length
;
i
<
len
;
i
++
)
{
if
(
i
!==
0
)
{
children
.
push
({
tagName
:
'
span
'
,
text
:
'
+
'
});
}
children
.
push
({
tagName
:
'
span
'
,
className
:
'
monaco-kbkey
'
,
text
:
pieces
[
i
]
});
}
return
children
;
}
export
function
simpleHTMLLabel
(
pieces
:
string
[]):
IHTMLContentElement
{
return
{
tagName
:
'
span
'
,
className
:
'
monaco-kb
'
,
children
:
_htmlPieces
(
pieces
)
};
}
export
function
chordHTMLLabel
(
firstPart
:
string
[],
chordPart
:
string
[]):
IHTMLContentElement
{
return
{
tagName
:
'
span
'
,
className
:
'
monaco-kb
'
,
children
:
[].
concat
(
_htmlPieces
(
firstPart
),
[{
tagName
:
'
span
'
,
text
:
'
'
}],
_htmlPieces
(
chordPart
)
)
};
}
export
function
readRawMapping
<
T
>
(
file
:
string
):
TPromise
<
T
>
{
return
readFile
(
require
.
toUrl
(
`vs/workbench/services/keybinding/test/
${
file
}
.js`
)).
then
((
buff
)
=>
{
let
contents
=
buff
.
toString
();
let
func
=
new
Function
(
'
define
'
,
contents
);
let
rawMappings
:
T
=
null
;
func
(
function
(
value
)
{
rawMappings
=
value
;
});
return
rawMappings
;
});
}
export
function
assertMapping
(
mapper
:
IKeyboardMapper
,
file
:
string
,
done
:
(
err
?:
any
)
=>
void
):
void
{
const
filePath
=
require
.
toUrl
(
`vs/workbench/services/keybinding/test/
${
file
}
`
);
readFile
(
filePath
).
then
((
buff
)
=>
{
let
expected
=
buff
.
toString
();
const
actual
=
mapper
.
dumpDebugInfo
();
if
(
actual
!==
expected
)
{
writeFile
(
filePath
,
actual
);
}
try
{
assert
.
deepEqual
(
actual
,
expected
);
}
catch
(
err
)
{
return
done
(
err
);
}
done
();
},
done
);
}
src/vs/workbench/services/keybinding/test/
k
eyboardMapper.test.ts
→
src/vs/workbench/services/keybinding/test/
macLinuxK
eyboardMapper.test.ts
浏览文件 @
ebd346b3
...
@@ -7,48 +7,24 @@
...
@@ -7,48 +7,24 @@
import
*
as
assert
from
'
assert
'
;
import
*
as
assert
from
'
assert
'
;
import
{
KeyMod
,
KeyCode
,
createKeybinding
,
SimpleKeybinding
,
Keybinding
}
from
'
vs/base/common/keyCodes
'
;
import
{
KeyMod
,
KeyCode
,
createKeybinding
,
SimpleKeybinding
,
Keybinding
}
from
'
vs/base/common/keyCodes
'
;
import
{
KeyboardMapper
,
IKeyboardMapping
}
from
'
vs/workbench/services/keybinding/common/k
eyboardMapper
'
;
import
{
MacLinuxKeyboardMapper
,
IKeyboardMapping
}
from
'
vs/workbench/services/keybinding/common/macLinuxK
eyboardMapper
'
;
import
{
OperatingSystem
}
from
'
vs/base/common/platform
'
;
import
{
OperatingSystem
}
from
'
vs/base/common/platform
'
;
import
{
UserSettingsLabelProvider
}
from
'
vs/platform/keybinding/common/keybindingLabels
'
;
import
{
UserSettingsLabelProvider
}
from
'
vs/platform/keybinding/common/keybindingLabels
'
;
import
{
USLayoutResolvedKeybinding
}
from
'
vs/platform/keybinding/common/usLayoutResolvedKeybinding
'
;
import
{
USLayoutResolvedKeybinding
}
from
'
vs/platform/keybinding/common/usLayoutResolvedKeybinding
'
;
import
{
KeyboardEventCodeUtils
}
from
'
vs/workbench/services/keybinding/common/keyboardEventCode
'
;
import
{
KeyboardEventCodeUtils
}
from
'
vs/workbench/services/keybinding/common/keyboardEventCode
'
;
import
{
IHTMLContentElement
}
from
'
vs/base/common/htmlContent
'
;
import
{
IHTMLContentElement
}
from
'
vs/base/common/htmlContent
'
;
import
{
readFile
,
writeFile
}
from
'
vs/base/node/pfs
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
readRawMapping
,
assertMapping
}
from
'
vs/workbench/services/keybinding/test/keyboardMapperTestUtils
'
;
function
createKeyboardMapper
(
file
:
string
,
OS
:
OperatingSystem
):
TPromise
<
KeyboardMapper
>
{
function
createKeyboardMapper
(
file
:
string
,
OS
:
OperatingSystem
):
TPromise
<
MacLinuxKeyboardMapper
>
{
return
readFile
(
require
.
toUrl
(
`vs/workbench/services/keybinding/test/
${
file
}
.js`
)).
then
((
buff
)
=>
{
return
readRawMapping
<
IKeyboardMapping
>
(
file
).
then
((
rawMappings
)
=>
{
let
contents
=
buff
.
toString
();
return
new
MacLinuxKeyboardMapper
(
rawMappings
,
OS
);
let
func
=
new
Function
(
'
define
'
,
contents
);
let
rawMappings
:
IKeyboardMapping
=
null
;
func
(
function
(
value
)
{
rawMappings
=
value
;
});
return
new
KeyboardMapper
(
rawMappings
,
OS
);
});
});
}
}
function
assertMapping
(
mapper
:
KeyboardMapper
,
file
:
string
,
done
:
(
err
?:
any
)
=>
void
):
void
{
const
filePath
=
require
.
toUrl
(
`vs/workbench/services/keybinding/test/
${
file
}
`
);
readFile
(
filePath
).
then
((
buff
)
=>
{
let
expected
=
buff
.
toString
();
const
actual
=
mapper
.
dumpDebugInfo
();
if
(
actual
!==
expected
)
{
writeFile
(
filePath
,
actual
);
}
try
{
assert
.
deepEqual
(
actual
,
expected
);
}
catch
(
err
)
{
return
done
(
err
);
}
done
();
},
done
);
}
suite
(
'
keyboardMapper - MAC de_ch
'
,
()
=>
{
suite
(
'
keyboardMapper - MAC de_ch
'
,
()
=>
{
let
mapper
:
KeyboardMapper
;
let
mapper
:
MacLinux
KeyboardMapper
;
suiteSetup
((
done
)
=>
{
suiteSetup
((
done
)
=>
{
createKeyboardMapper
(
'
mac_de_ch
'
,
OperatingSystem
.
Macintosh
).
then
((
_mapper
)
=>
{
createKeyboardMapper
(
'
mac_de_ch
'
,
OperatingSystem
.
Macintosh
).
then
((
_mapper
)
=>
{
...
@@ -120,7 +96,7 @@ suite('keyboardMapper - MAC de_ch', () => {
...
@@ -120,7 +96,7 @@ suite('keyboardMapper - MAC de_ch', () => {
suite
(
'
keyboardMapper - LINUX de_ch
'
,
()
=>
{
suite
(
'
keyboardMapper - LINUX de_ch
'
,
()
=>
{
let
mapper
:
KeyboardMapper
;
let
mapper
:
MacLinux
KeyboardMapper
;
suiteSetup
((
done
)
=>
{
suiteSetup
((
done
)
=>
{
createKeyboardMapper
(
'
linux_de_ch
'
,
OperatingSystem
.
Linux
).
then
((
_mapper
)
=>
{
createKeyboardMapper
(
'
linux_de_ch
'
,
OperatingSystem
.
Linux
).
then
((
_mapper
)
=>
{
...
@@ -155,7 +131,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
...
@@ -155,7 +131,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
suite
(
'
keyboardMapper - LINUX de_ch
'
,
()
=>
{
suite
(
'
keyboardMapper - LINUX de_ch
'
,
()
=>
{
let
mapper
:
KeyboardMapper
;
let
mapper
:
MacLinux
KeyboardMapper
;
suiteSetup
((
done
)
=>
{
suiteSetup
((
done
)
=>
{
createKeyboardMapper
(
'
linux_en_us
'
,
OperatingSystem
.
Linux
).
then
((
_mapper
)
=>
{
createKeyboardMapper
(
'
linux_en_us
'
,
OperatingSystem
.
Linux
).
then
((
_mapper
)
=>
{
...
@@ -169,7 +145,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
...
@@ -169,7 +145,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
});
});
});
});
function
_assertKeybindingTranslation
(
mapper
:
KeyboardMapper
,
OS
:
OperatingSystem
,
kb
:
number
,
_expected
:
string
|
string
[]):
void
{
function
_assertKeybindingTranslation
(
mapper
:
MacLinux
KeyboardMapper
,
OS
:
OperatingSystem
,
kb
:
number
,
_expected
:
string
|
string
[]):
void
{
let
expected
:
string
[];
let
expected
:
string
[];
if
(
typeof
_expected
===
'
string
'
)
{
if
(
typeof
_expected
===
'
string
'
)
{
expected
=
[
_expected
];
expected
=
[
_expected
];
...
...
src/vs/workbench/services/keybinding/test/windowsKeyboardMapper.test.ts
浏览文件 @
ebd346b3
...
@@ -5,108 +5,20 @@
...
@@ -5,108 +5,20 @@
'
use strict
'
;
'
use strict
'
;
import
*
as
assert
from
'
assert
'
;
import
{
OperatingSystem
}
from
'
vs/base/common/platform
'
;
import
{
OperatingSystem
}
from
'
vs/base/common/platform
'
;
import
{
readFile
,
writeFile
}
from
'
vs/base/node/pfs
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
WindowsKeyboardMapper
,
IKeyboardMapping
}
from
'
vs/workbench/services/keybinding/common/windowsKeyboardMapper
'
;
import
{
WindowsKeyboardMapper
,
IKeyboardMapping
}
from
'
vs/workbench/services/keybinding/common/windowsKeyboardMapper
'
;
import
{
createKeybinding
,
KeyMod
,
KeyCode
,
KeyChord
}
from
'
vs/base/common/keyCodes
'
;
import
{
createKeybinding
,
KeyMod
,
KeyCode
,
KeyChord
}
from
'
vs/base/common/keyCodes
'
;
import
{
I
HTMLContentElement
}
from
'
vs/base/common/htmlContent
'
;
import
{
I
ResolvedKeybinding
,
assertResolveKeybinding
,
readRawMapping
,
assertMapping
,
simpleHTMLLabel
,
chordHTMLLabel
}
from
'
vs/workbench/services/keybinding/test/keyboardMapperTestUtils
'
;
function
createKeyboardMapper
(
file
:
string
,
OS
:
OperatingSystem
):
TPromise
<
WindowsKeyboardMapper
>
{
function
createKeyboardMapper
(
file
:
string
):
TPromise
<
WindowsKeyboardMapper
>
{
return
readFile
(
require
.
toUrl
(
`vs/workbench/services/keybinding/test/
${
file
}
.js`
)).
then
((
buff
)
=>
{
return
readRawMapping
<
IKeyboardMapping
>
(
file
).
then
((
rawMappings
)
=>
{
let
contents
=
buff
.
toString
();
let
func
=
new
Function
(
'
define
'
,
contents
);
let
rawMappings
:
IKeyboardMapping
=
null
;
func
(
function
(
value
)
{
rawMappings
=
value
;
});
return
new
WindowsKeyboardMapper
(
rawMappings
);
return
new
WindowsKeyboardMapper
(
rawMappings
);
});
});
}
}
function
assertMapping
(
mapper
:
WindowsKeyboardMapper
,
file
:
string
,
done
:
(
err
?:
any
)
=>
void
):
void
{
function
_assertResolveKeybinding
(
mapper
:
WindowsKeyboardMapper
,
k
:
number
,
expected
:
IResolvedKeybinding
):
void
{
const
filePath
=
require
.
toUrl
(
`vs/workbench/services/keybinding/test/
${
file
}
`
);
assertResolveKeybinding
(
mapper
,
createKeybinding
(
k
,
OperatingSystem
.
Windows
),
[
expected
]);
readFile
(
filePath
).
then
((
buff
)
=>
{
let
expected
=
buff
.
toString
();
const
actual
=
mapper
.
dumpDebugInfo
();
if
(
actual
!==
expected
)
{
writeFile
(
filePath
,
actual
);
}
try
{
assert
.
deepEqual
(
actual
,
expected
);
}
catch
(
err
)
{
return
done
(
err
);
}
done
();
},
done
);
}
function
_htmlPieces
(
pieces
:
string
[]):
IHTMLContentElement
[]
{
let
children
:
IHTMLContentElement
[]
=
[];
for
(
let
i
=
0
,
len
=
pieces
.
length
;
i
<
len
;
i
++
)
{
if
(
i
!==
0
)
{
children
.
push
({
tagName
:
'
span
'
,
text
:
'
+
'
});
}
children
.
push
({
tagName
:
'
span
'
,
className
:
'
monaco-kbkey
'
,
text
:
pieces
[
i
]
});
}
return
children
;
}
function
simpleHTMLLabel
(
pieces
:
string
[]):
IHTMLContentElement
{
return
{
tagName
:
'
span
'
,
className
:
'
monaco-kb
'
,
children
:
_htmlPieces
(
pieces
)
};
}
function
chordHTMLLabel
(
firstPart
:
string
[],
chordPart
:
string
[]):
IHTMLContentElement
{
return
{
tagName
:
'
span
'
,
className
:
'
monaco-kb
'
,
children
:
[].
concat
(
_htmlPieces
(
firstPart
),
[{
tagName
:
'
span
'
,
text
:
'
'
}],
_htmlPieces
(
chordPart
)
)
};
}
interface
IResolvedKeybindingExpected
{
label
:
string
;
ariaLabel
:
string
;
HTMLLabel
:
IHTMLContentElement
[];
electronAccelerator
:
string
;
userSettingsLabel
:
string
;
isChord
:
boolean
;
hasCtrlModifier
:
boolean
;
hasShiftModifier
:
boolean
;
hasAltModifier
:
boolean
;
hasMetaModifier
:
boolean
;
dispatchParts
:
[
string
,
string
];
}
function
_assertResolvedKeybinding
(
mapper
:
WindowsKeyboardMapper
,
k
:
number
,
expected
:
IResolvedKeybindingExpected
):
void
{
let
kbs
=
mapper
.
resolveKeybinding
(
createKeybinding
(
k
,
OperatingSystem
.
Windows
));
assert
.
equal
(
kbs
.
length
,
1
);
let
kb
=
kbs
[
0
];
let
actual
:
IResolvedKeybindingExpected
=
{
label
:
kb
.
getLabel
(),
ariaLabel
:
kb
.
getAriaLabel
(),
HTMLLabel
:
kb
.
getHTMLLabel
(),
electronAccelerator
:
kb
.
getElectronAccelerator
(),
userSettingsLabel
:
kb
.
getUserSettingsLabel
(),
isChord
:
kb
.
isChord
(),
hasCtrlModifier
:
kb
.
hasCtrlModifier
(),
hasShiftModifier
:
kb
.
hasShiftModifier
(),
hasAltModifier
:
kb
.
hasAltModifier
(),
hasMetaModifier
:
kb
.
hasMetaModifier
(),
dispatchParts
:
kb
.
getDispatchParts
(),
};
assert
.
deepEqual
(
actual
,
expected
);
}
}
suite
(
'
keyboardMapper - WINDOWS de_ch
'
,
()
=>
{
suite
(
'
keyboardMapper - WINDOWS de_ch
'
,
()
=>
{
...
@@ -114,7 +26,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
...
@@ -114,7 +26,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
let
mapper
:
WindowsKeyboardMapper
;
let
mapper
:
WindowsKeyboardMapper
;
suiteSetup
((
done
)
=>
{
suiteSetup
((
done
)
=>
{
createKeyboardMapper
(
'
win_de_ch
'
,
OperatingSystem
.
Macintosh
).
then
((
_mapper
)
=>
{
createKeyboardMapper
(
'
win_de_ch
'
).
then
((
_mapper
)
=>
{
mapper
=
_mapper
;
mapper
=
_mapper
;
done
();
done
();
},
done
);
},
done
);
...
@@ -124,12 +36,9 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
...
@@ -124,12 +36,9 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
assertMapping
(
mapper
,
'
win_de_ch.txt
'
,
done
);
assertMapping
(
mapper
,
'
win_de_ch.txt
'
,
done
);
});
});
function
assertResolveKeybinding
(
kb
:
number
,
expected
:
IResolvedKeybindingExpected
):
void
{
_assertResolvedKeybinding
(
mapper
,
kb
,
expected
);
}
test
(
'
resolveKeybinding Ctrl+A
'
,
()
=>
{
test
(
'
resolveKeybinding Ctrl+A
'
,
()
=>
{
assertResolveKeybinding
(
_assertResolveKeybinding
(
mapper
,
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_A
,
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_A
,
{
{
label
:
'
Ctrl+A
'
,
label
:
'
Ctrl+A
'
,
...
@@ -148,7 +57,8 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
...
@@ -148,7 +57,8 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
});
});
test
(
'
resolveKeybinding Ctrl+Z
'
,
()
=>
{
test
(
'
resolveKeybinding Ctrl+Z
'
,
()
=>
{
assertResolveKeybinding
(
_assertResolveKeybinding
(
mapper
,
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_Z
,
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_Z
,
{
{
label
:
'
Ctrl+Z
'
,
label
:
'
Ctrl+Z
'
,
...
@@ -167,7 +77,8 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
...
@@ -167,7 +77,8 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
});
});
test
(
'
resolveKeybinding Ctrl+]
'
,
()
=>
{
test
(
'
resolveKeybinding Ctrl+]
'
,
()
=>
{
assertResolveKeybinding
(
_assertResolveKeybinding
(
mapper
,
KeyMod
.
CtrlCmd
|
KeyCode
.
US_CLOSE_SQUARE_BRACKET
,
KeyMod
.
CtrlCmd
|
KeyCode
.
US_CLOSE_SQUARE_BRACKET
,
{
{
label
:
'
Ctrl+^
'
,
label
:
'
Ctrl+^
'
,
...
@@ -186,7 +97,8 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
...
@@ -186,7 +97,8 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
});
});
test
(
'
resolveKeybinding Ctrl+/
'
,
()
=>
{
test
(
'
resolveKeybinding Ctrl+/
'
,
()
=>
{
assertResolveKeybinding
(
_assertResolveKeybinding
(
mapper
,
KeyMod
.
CtrlCmd
|
KeyCode
.
US_SLASH
,
KeyMod
.
CtrlCmd
|
KeyCode
.
US_SLASH
,
{
{
label
:
'
Ctrl+§
'
,
label
:
'
Ctrl+§
'
,
...
@@ -205,7 +117,8 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
...
@@ -205,7 +117,8 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
});
});
test
(
'
resolveKeybinding Ctrl+K Ctrl+
\\
'
,
()
=>
{
test
(
'
resolveKeybinding Ctrl+K Ctrl+
\\
'
,
()
=>
{
assertResolveKeybinding
(
_assertResolveKeybinding
(
mapper
,
KeyChord
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
,
KeyMod
.
CtrlCmd
|
KeyCode
.
US_BACKSLASH
),
KeyChord
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
,
KeyMod
.
CtrlCmd
|
KeyCode
.
US_BACKSLASH
),
{
{
label
:
'
Ctrl+K Ctrl+ä
'
,
label
:
'
Ctrl+K Ctrl+ä
'
,
...
@@ -229,7 +142,7 @@ suite('keyboardMapper - WINDOWS en_us', () => {
...
@@ -229,7 +142,7 @@ suite('keyboardMapper - WINDOWS en_us', () => {
let
mapper
:
WindowsKeyboardMapper
;
let
mapper
:
WindowsKeyboardMapper
;
suiteSetup
((
done
)
=>
{
suiteSetup
((
done
)
=>
{
createKeyboardMapper
(
'
win_en_us
'
,
OperatingSystem
.
Macintosh
).
then
((
_mapper
)
=>
{
createKeyboardMapper
(
'
win_en_us
'
).
then
((
_mapper
)
=>
{
mapper
=
_mapper
;
mapper
=
_mapper
;
done
();
done
();
},
done
);
},
done
);
...
@@ -239,12 +152,9 @@ suite('keyboardMapper - WINDOWS en_us', () => {
...
@@ -239,12 +152,9 @@ suite('keyboardMapper - WINDOWS en_us', () => {
assertMapping
(
mapper
,
'
win_en_us.txt
'
,
done
);
assertMapping
(
mapper
,
'
win_en_us.txt
'
,
done
);
});
});
function
assertResolveKeybinding
(
kb
:
number
,
expected
:
IResolvedKeybindingExpected
):
void
{
_assertResolvedKeybinding
(
mapper
,
kb
,
expected
);
}
test
(
'
resolveKeybinding Ctrl+K Ctrl+
\\
'
,
()
=>
{
test
(
'
resolveKeybinding Ctrl+K Ctrl+
\\
'
,
()
=>
{
assertResolveKeybinding
(
_assertResolveKeybinding
(
mapper
,
KeyChord
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
,
KeyMod
.
CtrlCmd
|
KeyCode
.
US_BACKSLASH
),
KeyChord
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_K
,
KeyMod
.
CtrlCmd
|
KeyCode
.
US_BACKSLASH
),
{
{
label
:
'
Ctrl+K Ctrl+
\\
'
,
label
:
'
Ctrl+K Ctrl+
\\
'
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录