Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
a0184cc5
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,发现更多精彩内容 >>
提交
a0184cc5
编写于
6月 11, 2019
作者:
S
Sandeep Somavarapu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
#75079 Use fileservice for listening to keybindings file changes
上级
3c1b39ae
变更
1
显示空白变更内容
内联
并排
Showing
1 changed file
with
131 addition
and
43 deletion
+131
-43
src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts
...services/keybinding/electron-browser/keybindingService.ts
+131
-43
未找到文件。
src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts
浏览文件 @
a0184cc5
...
...
@@ -8,13 +8,11 @@ import * as nativeKeymap from 'native-keymap';
import
{
release
}
from
'
os
'
;
import
*
as
dom
from
'
vs/base/browser/dom
'
;
import
{
StandardKeyboardEvent
}
from
'
vs/base/browser/keyboardEvent
'
;
import
{
onUnexpectedError
}
from
'
vs/base/common/errors
'
;
import
{
Emitter
,
Event
}
from
'
vs/base/common/event
'
;
import
{
IJSONSchema
}
from
'
vs/base/common/jsonSchema
'
;
import
{
Keybinding
,
ResolvedKeybinding
}
from
'
vs/base/common/keyCodes
'
;
import
{
KeybindingParser
}
from
'
vs/base/common/keybindingParser
'
;
import
{
OS
,
OperatingSystem
}
from
'
vs/base/common/platform
'
;
import
{
ConfigWatcher
}
from
'
vs/base/node/config
'
;
import
{
ICommandService
,
CommandsRegistry
}
from
'
vs/platform/commands/common/commands
'
;
import
{
IConfigurationService
}
from
'
vs/platform/configuration/common/configuration
'
;
import
{
Extensions
as
ConfigExtensions
,
IConfigurationNode
,
IConfigurationRegistry
}
from
'
vs/platform/configuration/common/configurationRegistry
'
;
...
...
@@ -41,6 +39,13 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten
import
{
MenuRegistry
}
from
'
vs/platform/actions/common/actions
'
;
import
{
registerSingleton
}
from
'
vs/platform/instantiation/common/extensions
'
;
import
{
commandsExtensionPoint
}
from
'
vs/workbench/api/common/menusExtensionPoint
'
;
import
{
Disposable
,
IDisposable
,
toDisposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
RunOnceScheduler
}
from
'
vs/base/common/async
'
;
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
IFileService
,
FileChangesEvent
,
FileChangeType
}
from
'
vs/platform/files/common/files
'
;
import
{
dirname
,
isEqual
}
from
'
vs/base/common/resources
'
;
import
{
parse
}
from
'
vs/base/common/json
'
;
import
*
as
objects
from
'
vs/base/common/objects
'
;
export
class
KeyboardMapperFactory
{
public
static
readonly
INSTANCE
=
new
KeyboardMapperFactory
();
...
...
@@ -267,8 +272,7 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
private
_keyboardMapper
:
IKeyboardMapper
;
private
_cachedResolver
:
KeybindingResolver
|
null
;
private
_firstTimeComputingResolver
:
boolean
;
private
userKeybindings
:
ConfigWatcher
<
IUserFriendlyKeybinding
[]
>
;
private
userKeybindings
:
UserKeybindings
;
constructor
(
@
IContextKeyService
contextKeyService
:
IContextKeyService
,
...
...
@@ -278,7 +282,8 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
@
IEnvironmentService
environmentService
:
IEnvironmentService
,
@
IConfigurationService
configurationService
:
IConfigurationService
,
@
IWindowService
private
readonly
windowService
:
IWindowService
,
@
IExtensionService
extensionService
:
IExtensionService
@
IExtensionService
extensionService
:
IExtensionService
,
@
IFileService
fileService
:
IFileService
)
{
super
(
contextKeyService
,
commandService
,
telemetryService
,
notificationService
);
...
...
@@ -303,9 +308,27 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
});
this
.
_cachedResolver
=
null
;
this
.
_firstTimeComputingResolver
=
true
;
this
.
userKeybindings
=
this
.
_register
(
new
ConfigWatcher
(
environmentService
.
keybindingsResource
.
fsPath
,
{
defaultConfig
:
[],
onError
:
error
=>
onUnexpectedError
(
error
)
}));
this
.
userKeybindings
=
this
.
_register
(
new
UserKeybindings
(
environmentService
.
keybindingsResource
,
fileService
));
this
.
userKeybindings
.
initialize
().
then
(()
=>
{
if
(
this
.
userKeybindings
.
keybindings
.
length
)
{
this
.
updateResolver
({
source
:
KeybindingSource
.
User
});
}
});
this
.
_register
(
this
.
userKeybindings
.
onDidChange
(()
=>
{
/* __GDPR__
"customKeybindingsChanged" : {
"keyCount" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
this
.
_telemetryService
.
publicLog
(
'
customKeybindingsChanged
'
,
{
keyCount
:
this
.
userKeybindings
.
keybindings
.
length
});
this
.
updateResolver
({
source
:
KeybindingSource
.
User
,
keybindings
:
this
.
userKeybindings
.
keybindings
});
}));
keybindingsExtPoint
.
setHandler
((
extensions
)
=>
{
...
...
@@ -321,11 +344,6 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
updateSchema
();
this
.
_register
(
extensionService
.
onDidRegisterExtensions
(()
=>
updateSchema
()));
this
.
_register
(
this
.
userKeybindings
.
onDidUpdateConfiguration
(
event
=>
this
.
updateResolver
({
source
:
KeybindingSource
.
User
,
keybindings
:
event
.
config
})));
this
.
_register
(
dom
.
addDisposableListener
(
window
,
dom
.
EventType
.
KEY_DOWN
,
(
e
:
KeyboardEvent
)
=>
{
let
keyEvent
=
new
StandardKeyboardEvent
(
e
);
let
shouldPreventDefault
=
this
.
_dispatch
(
keyEvent
,
keyEvent
.
target
);
...
...
@@ -353,18 +371,8 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
return
`Layout info:\n
${
layoutInfo
}
\n
${
mapperInfo
}
\n\nRaw mapping:\n
${
rawMapping
}
`
;
}
private
_safeGetConfig
():
IUserFriendlyKeybinding
[]
{
let
rawConfig
=
this
.
userKeybindings
.
getConfig
();
if
(
Array
.
isArray
(
rawConfig
))
{
return
rawConfig
;
}
return
[];
}
public
customKeybindingsCount
():
number
{
let
userKeybindings
=
this
.
_safeGetConfig
();
return
userKeybindings
.
length
;
return
this
.
userKeybindings
.
keybindings
.
length
;
}
private
updateResolver
(
event
:
IKeybindingEvent
):
void
{
...
...
@@ -375,9 +383,8 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
protected
_getResolver
():
KeybindingResolver
{
if
(
!
this
.
_cachedResolver
)
{
const
defaults
=
this
.
_resolveKeybindingItems
(
KeybindingsRegistry
.
getDefaultKeybindings
(),
true
);
const
overrides
=
this
.
_resolveUserKeybindingItems
(
this
.
_getExtraKeybindings
(
this
.
_firstTimeComputingResolver
),
false
);
const
overrides
=
this
.
_resolveUserKeybindingItems
(
this
.
userKeybindings
.
keybindings
.
map
((
k
)
=>
KeybindingIO
.
readUserKeybindingItem
(
k
)
),
false
);
this
.
_cachedResolver
=
new
KeybindingResolver
(
defaults
,
overrides
);
this
.
_firstTimeComputingResolver
=
false
;
}
return
this
.
_cachedResolver
;
}
...
...
@@ -427,24 +434,6 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
return
result
;
}
private
_getExtraKeybindings
(
isFirstTime
:
boolean
):
IUserKeybindingItem
[]
{
let
extraUserKeybindings
:
IUserFriendlyKeybinding
[]
=
this
.
_safeGetConfig
();
if
(
!
isFirstTime
)
{
let
cnt
=
extraUserKeybindings
.
length
;
/* __GDPR__
"customKeybindingsChanged" : {
"keyCount" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
this
.
_telemetryService
.
publicLog
(
'
customKeybindingsChanged
'
,
{
keyCount
:
cnt
});
}
return
extraUserKeybindings
.
map
((
k
)
=>
KeybindingIO
.
readUserKeybindingItem
(
k
));
}
public
resolveKeybinding
(
kb
:
Keybinding
):
ResolvedKeybinding
[]
{
return
this
.
_keyboardMapper
.
resolveKeybinding
(
kb
);
}
...
...
@@ -585,6 +574,105 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
}
}
class
UserKeybindings
extends
Disposable
{
private
_keybindings
:
IUserFriendlyKeybinding
[]
=
[];
get
keybindings
():
IUserFriendlyKeybinding
[]
{
return
this
.
_keybindings
;
}
private
readonly
reloadConfigurationScheduler
:
RunOnceScheduler
;
protected
readonly
_onDidChange
:
Emitter
<
void
>
=
this
.
_register
(
new
Emitter
<
void
>
());
readonly
onDidChange
:
Event
<
void
>
=
this
.
_onDidChange
.
event
;
private
fileWatcherDisposable
:
IDisposable
=
Disposable
.
None
;
private
directoryWatcherDisposable
:
IDisposable
=
Disposable
.
None
;
constructor
(
private
readonly
keybindingsResource
:
URI
,
private
readonly
fileService
:
IFileService
)
{
super
();
this
.
_register
(
fileService
.
onFileChanges
(
e
=>
this
.
handleFileEvents
(
e
)));
this
.
reloadConfigurationScheduler
=
this
.
_register
(
new
RunOnceScheduler
(()
=>
this
.
reload
().
then
(
changed
=>
{
if
(
changed
)
{
this
.
_onDidChange
.
fire
();
}
}),
50
));
this
.
_register
(
toDisposable
(()
=>
{
this
.
stopWatchingResource
();
this
.
stopWatchingDirectory
();
}));
}
private
watchResource
():
void
{
this
.
fileWatcherDisposable
=
this
.
fileService
.
watch
(
this
.
keybindingsResource
);
}
private
stopWatchingResource
():
void
{
this
.
fileWatcherDisposable
.
dispose
();
this
.
fileWatcherDisposable
=
Disposable
.
None
;
}
private
watchDirectory
():
void
{
const
directory
=
dirname
(
this
.
keybindingsResource
);
this
.
directoryWatcherDisposable
=
this
.
fileService
.
watch
(
directory
);
}
private
stopWatchingDirectory
():
void
{
this
.
directoryWatcherDisposable
.
dispose
();
this
.
directoryWatcherDisposable
=
Disposable
.
None
;
}
async
initialize
():
Promise
<
void
>
{
const
exists
=
await
this
.
fileService
.
exists
(
this
.
keybindingsResource
);
this
.
onResourceExists
(
exists
);
await
this
.
reload
();
}
private
async
reload
():
Promise
<
boolean
>
{
const
existing
=
this
.
_keybindings
;
try
{
const
content
=
await
this
.
fileService
.
readFile
(
this
.
keybindingsResource
);
this
.
_keybindings
=
parse
(
content
.
value
.
toString
());
}
catch
(
e
)
{
this
.
_keybindings
=
[];
}
return
existing
?
!
objects
.
equals
(
existing
,
this
.
_keybindings
)
:
true
;
}
private
async
handleFileEvents
(
event
:
FileChangesEvent
):
Promise
<
void
>
{
const
events
=
event
.
changes
;
let
affectedByChanges
=
false
;
// Find changes that affect the resource
for
(
const
event
of
events
)
{
affectedByChanges
=
isEqual
(
this
.
keybindingsResource
,
event
.
resource
);
if
(
affectedByChanges
)
{
if
(
event
.
type
===
FileChangeType
.
ADDED
)
{
this
.
onResourceExists
(
true
);
}
else
if
(
event
.
type
===
FileChangeType
.
DELETED
)
{
this
.
onResourceExists
(
false
);
}
break
;
}
}
if
(
affectedByChanges
)
{
this
.
reloadConfigurationScheduler
.
schedule
();
}
}
private
onResourceExists
(
exists
:
boolean
):
void
{
if
(
exists
)
{
this
.
stopWatchingDirectory
();
this
.
watchResource
();
}
else
{
this
.
stopWatchingResource
();
this
.
watchDirectory
();
}
}
}
let
schemaId
=
'
vscode://schemas/keybindings
'
;
let
commandsSchemas
:
IJSONSchema
[]
=
[];
let
commandsEnum
:
string
[]
=
[];
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录