Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
53098835
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,发现更多精彩内容 >>
提交
53098835
编写于
11月 28, 2019
作者:
S
Sandeep Somavarapu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
more smart merging
上级
76801c7c
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
98 addition
and
65 deletion
+98
-65
src/vs/workbench/services/keybinding/common/keybindingsMerge.ts
.../workbench/services/keybinding/common/keybindingsMerge.ts
+98
-65
未找到文件。
src/vs/workbench/services/keybinding/common/keybindingsMerge.ts
浏览文件 @
53098835
...
...
@@ -19,6 +19,8 @@ interface ICompareResult {
}
interface
IMergeResult
{
hasLocalForwarded
:
boolean
;
hasRemoteForwarded
:
boolean
;
added
:
Set
<
string
>
;
removed
:
Set
<
string
>
;
updated
:
Set
<
string
>
;
...
...
@@ -37,78 +39,36 @@ export class KeybindingsMergeService implements IKeybindingsMergeService {
const
local
=
<
IUserFriendlyKeybinding
[]
>
parse
(
localContent
);
const
remote
=
<
IUserFriendlyKeybinding
[]
>
parse
(
remoteContent
);
const
base
=
baseContent
?
<
IUserFriendlyKeybinding
[]
>
parse
(
baseContent
)
:
null
;
const
normalizedKeys
=
this
.
getNormalizedKeys
(
local
,
remote
,
base
);
const
normalize
=
(
keybinding
:
IUserFriendlyKeybinding
):
IUserFriendlyKeybinding
=>
({
...
keybinding
,
...{
key
:
this
.
keybindingsService
.
resolveUserBinding
(
keybinding
.
key
).
map
(
part
=>
part
.
getUserSettingsLabel
()).
join
(
'
'
)
}
});
const
normalizedLocal
=
local
.
map
(
keybinding
=>
normalize
(
keybinding
));
const
normalizedRemote
=
remote
.
map
(
keybinding
=>
normalize
(
keybinding
));
const
normalizedBase
=
base
?
base
.
map
(
keybinding
=>
normalize
(
keybinding
))
:
null
;
const
byKeybinding
=
(
keybindings
:
IUserFriendlyKeybinding
[],
normalized
:
IUserFriendlyKeybinding
[])
=>
{
const
map
:
Map
<
string
,
{
keybinding
:
IUserFriendlyKeybinding
,
normalized
:
IUserFriendlyKeybinding
}[]
>
=
new
Map
<
string
,
{
keybinding
:
IUserFriendlyKeybinding
,
normalized
:
IUserFriendlyKeybinding
}[]
>
();
for
(
let
index
=
0
;
index
<
normalized
.
length
;
index
++
)
{
let
value
=
map
.
get
(
normalized
[
index
].
key
);
if
(
!
value
)
{
value
=
[];
map
.
set
(
normalized
[
index
].
key
,
value
);
}
value
.
push
({
keybinding
:
keybindings
[
index
],
normalized
:
normalized
[
index
]
});
}
return
map
;
};
let
keybindingsMergeResult
=
this
.
computeMergeResultByKeybinding
(
local
,
remote
,
base
,
normalizedKeys
);
const
localByKeybinding
=
byKeybinding
(
local
,
normalizedLocal
);
const
remoteByKeybinding
=
byKeybinding
(
remote
,
normalizedRemote
);
const
baseByKeybinding
=
base
?
byKeybinding
(
base
,
normalizedBase
!
)
:
null
;
const
localToRemoteByKeybinding
=
this
.
compareByKeybinding
(
localByKeybinding
,
remoteByKeybinding
);
if
(
localToRemoteByKeybinding
.
added
.
size
===
0
&&
localToRemoteByKeybinding
.
removed
.
size
===
0
&&
localToRemoteByKeybinding
.
updated
.
size
===
0
)
{
if
(
!
keybindingsMergeResult
.
hasLocalForwarded
&&
!
keybindingsMergeResult
.
hasRemoteForwarded
)
{
// No changes found between local and remote.
return
{
mergeContent
:
localContent
,
hasChanges
:
false
,
hasConflicts
:
false
};
}
const
baseToLocalByKeybinding
=
baseByKeybinding
?
this
.
compareByKeybinding
(
baseByKeybinding
,
localByKeybinding
)
:
{
added
:
keys
(
localByKeybinding
).
reduce
((
r
,
k
)
=>
{
r
.
add
(
k
);
return
r
;
},
new
Set
<
string
>
()),
removed
:
new
Set
<
string
>
(),
updated
:
new
Set
<
string
>
()
};
if
(
baseToLocalByKeybinding
.
added
.
size
===
0
&&
baseToLocalByKeybinding
.
removed
.
size
===
0
&&
baseToLocalByKeybinding
.
updated
.
size
===
0
)
{
// Remote has moved forward and local has not. Return remote
if
(
!
keybindingsMergeResult
.
hasLocalForwarded
&&
keybindingsMergeResult
.
hasRemoteForwarded
)
{
return
{
mergeContent
:
remoteContent
,
hasChanges
:
true
,
hasConflicts
:
false
};
}
const
baseToRemoteByKeybinding
=
baseByKeybinding
?
this
.
compareByKeybinding
(
baseByKeybinding
,
remoteByKeybinding
)
:
{
added
:
keys
(
remoteByKeybinding
).
reduce
((
r
,
k
)
=>
{
r
.
add
(
k
);
return
r
;
},
new
Set
<
string
>
()),
removed
:
new
Set
<
string
>
(),
updated
:
new
Set
<
string
>
()
};
if
(
baseToRemoteByKeybinding
.
added
.
size
===
0
&&
baseToRemoteByKeybinding
.
removed
.
size
===
0
&&
baseToRemoteByKeybinding
.
updated
.
size
===
0
)
{
if
(
keybindingsMergeResult
.
hasLocalForwarded
&&
!
keybindingsMergeResult
.
hasRemoteForwarded
)
{
// Local has moved forward and remote has not. Return local.
return
{
mergeContent
:
localContent
,
hasChanges
:
true
,
hasConflicts
:
false
};
}
// Both local and remote has moved forward.
const
byCommand
=
(
keybindings
:
IUserFriendlyKeybinding
[],
normalized
:
IUserFriendlyKeybinding
[])
=>
{
const
map
:
Map
<
string
,
{
keybinding
:
IUserFriendlyKeybinding
,
normalized
:
IUserFriendlyKeybinding
}[]
>
=
new
Map
<
string
,
{
keybinding
:
IUserFriendlyKeybinding
,
normalized
:
IUserFriendlyKeybinding
}[]
>
();
for
(
let
index
=
0
;
index
<
normalized
.
length
;
index
++
)
{
const
command
=
normalized
[
index
].
command
[
0
]
===
'
-
'
?
normalized
[
index
].
command
.
substring
(
1
)
:
normalized
[
index
].
command
;
let
value
=
map
.
get
(
command
);
if
(
!
value
)
{
value
=
[];
map
.
set
(
command
,
value
);
}
value
.
push
({
keybinding
:
keybindings
[
index
],
normalized
:
normalized
[
index
]
});
}
return
map
;
};
const
localByCommand
=
byCommand
(
local
,
normalizedLocal
);
const
remoteByCommand
=
byCommand
(
remote
,
normalizedRemote
);
const
baseByCommand
=
base
?
byCommand
(
base
,
normalizedBase
!
)
:
null
;
const
localToRemoteByCommand
=
this
.
compareByCommand
(
localByCommand
,
remoteByCommand
);
const
baseToLocalByCommand
=
baseByCommand
?
this
.
compareByCommand
(
baseByCommand
,
localByCommand
)
:
{
added
:
keys
(
localByCommand
).
reduce
((
r
,
k
)
=>
{
r
.
add
(
k
);
return
r
;
},
new
Set
<
string
>
()),
removed
:
new
Set
<
string
>
(),
updated
:
new
Set
<
string
>
()
};
const
baseToRemoteByCommand
=
baseByCommand
?
this
.
compareByCommand
(
baseByCommand
,
remoteByCommand
)
:
{
added
:
keys
(
remoteByCommand
).
reduce
((
r
,
k
)
=>
{
r
.
add
(
k
);
return
r
;
},
new
Set
<
string
>
()),
removed
:
new
Set
<
string
>
(),
updated
:
new
Set
<
string
>
()
};
const
localByCommand
=
this
.
byCommand
(
local
);
const
remoteByCommand
=
this
.
byCommand
(
remote
);
const
baseByCommand
=
base
?
this
.
byCommand
(
base
)
:
null
;
const
localToRemoteByCommand
=
this
.
compareByCommand
(
localByCommand
,
remoteByCommand
,
normalizedKeys
);
const
baseToLocalByCommand
=
baseByCommand
?
this
.
compareByCommand
(
baseByCommand
,
localByCommand
,
normalizedKeys
)
:
{
added
:
keys
(
localByCommand
).
reduce
((
r
,
k
)
=>
{
r
.
add
(
k
);
return
r
;
},
new
Set
<
string
>
()),
removed
:
new
Set
<
string
>
(),
updated
:
new
Set
<
string
>
()
};
const
baseToRemoteByCommand
=
baseByCommand
?
this
.
compareByCommand
(
baseByCommand
,
remoteByCommand
,
normalizedKeys
)
:
{
added
:
keys
(
remoteByCommand
).
reduce
((
r
,
k
)
=>
{
r
.
add
(
k
);
return
r
;
},
new
Set
<
string
>
()),
removed
:
new
Set
<
string
>
(),
updated
:
new
Set
<
string
>
()
};
const
commandsMergeResult
=
this
.
computeMergeResult
(
localToRemoteByCommand
,
baseToLocalByCommand
,
baseToRemoteByCommand
);
const
keybindingsMergeResult
=
this
.
computeMergeResult
(
localToRemoteByKeybinding
,
baseToLocalByKeybinding
,
baseToRemoteByKeybinding
);
const
eol
=
contentUtil
.
getEol
(
localContent
);
let
mergeContent
=
localContent
;
let
mergeContentChanged
=
false
;
// Removed commands in Remote
for
(
const
command
of
values
(
commandsMergeResult
.
removed
))
{
...
...
@@ -116,8 +76,13 @@ export class KeybindingsMergeService implements IKeybindingsMergeService {
continue
;
}
mergeContent
=
this
.
removeKeybindings
(
mergeContent
,
eol
,
command
);
mergeContentChanged
=
true
;
}
if
(
mergeContentChanged
)
{
keybindingsMergeResult
=
this
.
computeMergeResultByKeybinding
(
local
,
remote
,
parse
(
mergeContent
),
normalizedKeys
);
}
mergeContentChanged
=
false
;
// Added commands in remote
for
(
const
command
of
values
(
commandsMergeResult
.
added
))
{
if
(
commandsMergeResult
.
conflicts
.
has
(
command
))
{
...
...
@@ -125,13 +90,17 @@ export class KeybindingsMergeService implements IKeybindingsMergeService {
}
const
keybindings
=
remoteByCommand
.
get
(
command
)
!
;
// Ignore negated commands
if
(
keybindings
.
some
(
({
normalized
})
=>
normalized
.
command
!==
`-
${
command
}
`
&&
keybindingsMergeResult
.
conflicts
.
has
(
normalized
.
key
)))
{
if
(
keybindings
.
some
(
keybinding
=>
keybinding
.
command
!==
`-
${
command
}
`
&&
keybindingsMergeResult
.
conflicts
.
has
(
normalizedKeys
.
get
(
keybinding
.
key
)
!
)))
{
commandsMergeResult
.
conflicts
.
add
(
command
);
continue
;
}
mergeContent
=
this
.
addKeybindings
(
mergeContent
,
eol
,
keybindings
.
map
(({
keybinding
})
=>
keybinding
));
mergeContent
=
this
.
addKeybindings
(
mergeContent
,
eol
,
keybindings
);
mergeContentChanged
=
true
;
}
if
(
mergeContentChanged
)
{
keybindingsMergeResult
=
this
.
computeMergeResultByKeybinding
(
local
,
remote
,
parse
(
mergeContent
),
normalizedKeys
);
}
// Updated commands in Remote
for
(
const
command
of
values
(
commandsMergeResult
.
updated
))
{
if
(
commandsMergeResult
.
conflicts
.
has
(
command
))
{
...
...
@@ -139,11 +108,11 @@ export class KeybindingsMergeService implements IKeybindingsMergeService {
}
const
keybindings
=
remoteByCommand
.
get
(
command
)
!
;
// Ignore negated commands
if
(
keybindings
.
some
(
({
normalized
})
=>
normalized
.
command
!==
`-
${
command
}
`
&&
keybindingsMergeResult
.
conflicts
.
has
(
normalized
.
key
)))
{
if
(
keybindings
.
some
(
keybinding
=>
keybinding
.
command
!==
`-
${
command
}
`
&&
keybindingsMergeResult
.
conflicts
.
has
(
normalizedKeys
.
get
(
keybinding
.
key
)
!
)))
{
commandsMergeResult
.
conflicts
.
add
(
command
);
continue
;
}
mergeContent
=
this
.
updateKeybindings
(
mergeContent
,
eol
,
command
,
keybindings
.
map
(({
keybinding
})
=>
keybinding
)
);
mergeContent
=
this
.
updateKeybindings
(
mergeContent
,
eol
,
command
,
keybindings
);
}
const
hasConflicts
=
commandsMergeResult
.
conflicts
.
size
>
0
;
...
...
@@ -158,7 +127,7 @@ export class KeybindingsMergeService implements IKeybindingsMergeService {
return
{
mergeContent
,
hasChanges
:
true
,
hasConflicts
};
}
private
computeMergeResult
(
localToRemote
:
ICompareResult
,
baseToLocal
:
ICompareResult
,
baseToRemote
:
ICompareResult
):
IMergeResult
{
private
computeMergeResult
(
localToRemote
:
ICompareResult
,
baseToLocal
:
ICompareResult
,
baseToRemote
:
ICompareResult
):
{
added
:
Set
<
string
>
,
removed
:
Set
<
string
>
,
updated
:
Set
<
string
>
,
conflicts
:
Set
<
string
>
}
{
const
added
:
Set
<
string
>
=
new
Set
<
string
>
();
const
removed
:
Set
<
string
>
=
new
Set
<
string
>
();
const
updated
:
Set
<
string
>
=
new
Set
<
string
>
();
...
...
@@ -249,7 +218,71 @@ export class KeybindingsMergeService implements IKeybindingsMergeService {
return
{
added
,
removed
,
updated
,
conflicts
};
}
private
compareByKeybinding
(
from
:
Map
<
string
,
{
keybinding
:
IUserFriendlyKeybinding
,
normalized
:
IUserFriendlyKeybinding
}[]
>
,
to
:
Map
<
string
,
{
keybinding
:
IUserFriendlyKeybinding
,
normalized
:
IUserFriendlyKeybinding
}[]
>
):
ICompareResult
{
private
getNormalizedKeys
(
local
:
IUserFriendlyKeybinding
[],
remote
:
IUserFriendlyKeybinding
[],
base
:
IUserFriendlyKeybinding
[]
|
null
):
Map
<
string
,
string
>
{
const
keys
=
new
Map
<
string
,
string
>
();
for
(
const
keybinding
of
[...
local
,
...
remote
,
...(
base
||
[])])
{
keys
.
set
(
keybinding
.
key
,
this
.
keybindingsService
.
resolveUserBinding
(
keybinding
.
key
).
map
(
part
=>
part
.
getUserSettingsLabel
()).
join
(
'
'
));
}
return
keys
;
}
private
computeMergeResultByKeybinding
(
local
:
IUserFriendlyKeybinding
[],
remote
:
IUserFriendlyKeybinding
[],
base
:
IUserFriendlyKeybinding
[]
|
null
,
normalizedKeys
:
Map
<
string
,
string
>
):
IMergeResult
{
const
empty
=
new
Set
<
string
>
();
const
localByKeybinding
=
this
.
byKeybinding
(
local
,
normalizedKeys
);
const
remoteByKeybinding
=
this
.
byKeybinding
(
remote
,
normalizedKeys
);
const
baseByKeybinding
=
base
?
this
.
byKeybinding
(
base
,
normalizedKeys
)
:
null
;
const
localToRemoteByKeybinding
=
this
.
compareByKeybinding
(
localByKeybinding
,
remoteByKeybinding
);
if
(
localToRemoteByKeybinding
.
added
.
size
===
0
&&
localToRemoteByKeybinding
.
removed
.
size
===
0
&&
localToRemoteByKeybinding
.
updated
.
size
===
0
)
{
return
{
hasLocalForwarded
:
false
,
hasRemoteForwarded
:
false
,
added
:
empty
,
removed
:
empty
,
updated
:
empty
,
conflicts
:
empty
};
}
const
baseToLocalByKeybinding
=
baseByKeybinding
?
this
.
compareByKeybinding
(
baseByKeybinding
,
localByKeybinding
)
:
{
added
:
keys
(
localByKeybinding
).
reduce
((
r
,
k
)
=>
{
r
.
add
(
k
);
return
r
;
},
new
Set
<
string
>
()),
removed
:
new
Set
<
string
>
(),
updated
:
new
Set
<
string
>
()
};
if
(
baseToLocalByKeybinding
.
added
.
size
===
0
&&
baseToLocalByKeybinding
.
removed
.
size
===
0
&&
baseToLocalByKeybinding
.
updated
.
size
===
0
)
{
// Remote has moved forward and local has not.
return
{
hasLocalForwarded
:
false
,
hasRemoteForwarded
:
true
,
added
:
empty
,
removed
:
empty
,
updated
:
empty
,
conflicts
:
empty
};
}
const
baseToRemoteByKeybinding
=
baseByKeybinding
?
this
.
compareByKeybinding
(
baseByKeybinding
,
remoteByKeybinding
)
:
{
added
:
keys
(
remoteByKeybinding
).
reduce
((
r
,
k
)
=>
{
r
.
add
(
k
);
return
r
;
},
new
Set
<
string
>
()),
removed
:
new
Set
<
string
>
(),
updated
:
new
Set
<
string
>
()
};
if
(
baseToRemoteByKeybinding
.
added
.
size
===
0
&&
baseToRemoteByKeybinding
.
removed
.
size
===
0
&&
baseToRemoteByKeybinding
.
updated
.
size
===
0
)
{
return
{
hasLocalForwarded
:
true
,
hasRemoteForwarded
:
false
,
added
:
empty
,
removed
:
empty
,
updated
:
empty
,
conflicts
:
empty
};
}
const
{
added
,
removed
,
updated
,
conflicts
}
=
this
.
computeMergeResult
(
localToRemoteByKeybinding
,
baseToLocalByKeybinding
,
baseToRemoteByKeybinding
);
return
{
hasLocalForwarded
:
true
,
hasRemoteForwarded
:
true
,
added
,
removed
,
updated
,
conflicts
};
}
private
byKeybinding
(
keybindings
:
IUserFriendlyKeybinding
[],
keys
:
Map
<
string
,
string
>
)
{
const
map
:
Map
<
string
,
IUserFriendlyKeybinding
[]
>
=
new
Map
<
string
,
IUserFriendlyKeybinding
[]
>
();
for
(
const
keybinding
of
keybindings
)
{
const
key
=
keys
.
get
(
keybinding
.
key
)
!
;
let
value
=
map
.
get
(
key
);
if
(
!
value
)
{
value
=
[];
map
.
set
(
key
,
value
);
}
value
.
push
(
keybinding
);
}
return
map
;
}
private
byCommand
(
keybindings
:
IUserFriendlyKeybinding
[]):
Map
<
string
,
IUserFriendlyKeybinding
[]
>
{
const
map
:
Map
<
string
,
IUserFriendlyKeybinding
[]
>
=
new
Map
<
string
,
IUserFriendlyKeybinding
[]
>
();
for
(
const
keybinding
of
keybindings
)
{
const
command
=
keybinding
.
command
[
0
]
===
'
-
'
?
keybinding
.
command
.
substring
(
1
)
:
keybinding
.
command
;
let
value
=
map
.
get
(
command
);
if
(
!
value
)
{
value
=
[];
map
.
set
(
command
,
value
);
}
value
.
push
(
keybinding
);
}
return
map
;
}
private
compareByKeybinding
(
from
:
Map
<
string
,
IUserFriendlyKeybinding
[]
>
,
to
:
Map
<
string
,
IUserFriendlyKeybinding
[]
>
):
ICompareResult
{
const
fromKeys
=
keys
(
from
);
const
toKeys
=
keys
(
to
);
const
added
=
toKeys
.
filter
(
key
=>
fromKeys
.
indexOf
(
key
)
===
-
1
).
reduce
((
r
,
key
)
=>
{
r
.
add
(
key
);
return
r
;
},
new
Set
<
string
>
());
...
...
@@ -260,8 +293,8 @@ export class KeybindingsMergeService implements IKeybindingsMergeService {
if
(
removed
.
has
(
key
))
{
continue
;
}
const
value1
:
IUserFriendlyKeybinding
[]
=
from
.
get
(
key
)
!
.
map
(
({
normalized
})
=>
normalized
);
const
value2
:
IUserFriendlyKeybinding
[]
=
to
.
get
(
key
)
!
.
map
(
({
normalized
})
=>
normalized
);
const
value1
:
IUserFriendlyKeybinding
[]
=
from
.
get
(
key
)
!
.
map
(
keybinding
=>
({
...
keybinding
,
...{
key
}
})
);
const
value2
:
IUserFriendlyKeybinding
[]
=
to
.
get
(
key
)
!
.
map
(
keybinding
=>
({
...
keybinding
,
...{
key
}
})
);
if
(
!
equals
(
value1
,
value2
,
(
a
,
b
)
=>
this
.
isSameKeybinding
(
a
,
b
)))
{
updated
.
add
(
key
);
}
...
...
@@ -270,7 +303,7 @@ export class KeybindingsMergeService implements IKeybindingsMergeService {
return
{
added
,
removed
,
updated
};
}
private
compareByCommand
(
from
:
Map
<
string
,
{
keybinding
:
IUserFriendlyKeybinding
,
normalized
:
IUserFriendlyKeybinding
}[]
>
,
to
:
Map
<
string
,
{
keybinding
:
IUserFriendlyKeybinding
,
normalized
:
IUserFriendlyKeybinding
}[]
>
):
ICompareResult
{
private
compareByCommand
(
from
:
Map
<
string
,
IUserFriendlyKeybinding
[]
>
,
to
:
Map
<
string
,
IUserFriendlyKeybinding
[]
>
,
normalizedKeys
:
Map
<
string
,
string
>
):
ICompareResult
{
const
fromKeys
=
keys
(
from
);
const
toKeys
=
keys
(
to
);
const
added
=
toKeys
.
filter
(
key
=>
fromKeys
.
indexOf
(
key
)
===
-
1
).
reduce
((
r
,
key
)
=>
{
r
.
add
(
key
);
return
r
;
},
new
Set
<
string
>
());
...
...
@@ -281,8 +314,8 @@ export class KeybindingsMergeService implements IKeybindingsMergeService {
if
(
removed
.
has
(
key
))
{
continue
;
}
const
value1
:
IUserFriendlyKeybinding
[]
=
from
.
get
(
key
)
!
.
map
(
({
normalized
})
=>
normalized
);
const
value2
:
IUserFriendlyKeybinding
[]
=
to
.
get
(
key
)
!
.
map
(
({
normalized
})
=>
normalized
);
const
value1
:
IUserFriendlyKeybinding
[]
=
from
.
get
(
key
)
!
.
map
(
keybinding
=>
({
...
keybinding
,
...{
key
:
normalizedKeys
.
get
(
keybinding
.
key
)
!
}
})
);
const
value2
:
IUserFriendlyKeybinding
[]
=
to
.
get
(
key
)
!
.
map
(
keybinding
=>
({
...
keybinding
,
...{
key
:
normalizedKeys
.
get
(
keybinding
.
key
)
!
}
})
);
if
(
!
this
.
areSameKeybindingsWithSameCommand
(
value1
,
value2
))
{
updated
.
add
(
key
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录