Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
2bac4776
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,发现更多精彩内容 >>
提交
2bac4776
编写于
5月 01, 2020
作者:
J
Johannes Rieken
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
perf - use bulk function to add command and menu items, fixes #96693
上级
b19b7a7f
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
83 addition
and
34 deletion
+83
-34
src/vs/base/common/iterator.ts
src/vs/base/common/iterator.ts
+4
-0
src/vs/platform/actions/common/actions.ts
src/vs/platform/actions/common/actions.ts
+56
-18
src/vs/platform/actions/common/menuService.ts
src/vs/platform/actions/common/menuService.ts
+1
-1
src/vs/workbench/api/common/menusExtensionPoint.ts
src/vs/workbench/api/common/menusExtensionPoint.ts
+22
-15
未找到文件。
src/vs/base/common/iterator.ts
浏览文件 @
2bac4776
...
...
@@ -10,6 +10,10 @@ export namespace Iterable {
return
_empty
;
}
export
function
*
single
<
T
>
(
element
:
T
):
Iterable
<
T
>
{
yield
element
;
}
export
function
from
<
T
>
(
iterable
:
Iterable
<
T
>
|
undefined
|
null
):
Iterable
<
T
>
{
return
iterable
||
_empty
;
}
...
...
src/vs/platform/actions/common/actions.ts
浏览文件 @
2bac4776
...
...
@@ -14,6 +14,7 @@ import { Event, Emitter } from 'vs/base/common/event';
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
ThemeIcon
}
from
'
vs/platform/theme/common/themeService
'
;
import
{
UriDto
}
from
'
vs/base/common/types
'
;
import
{
Iterable
}
from
'
vs/base/common/iterator
'
;
export
interface
ILocalizedString
{
value
:
string
;
...
...
@@ -153,30 +154,50 @@ export interface IMenuService {
export
type
ICommandsMap
=
Map
<
string
,
ICommandAction
>
;
export
interface
IMenuRegistryChangeEvent
{
has
(
id
:
MenuId
):
boolean
;
}
export
interface
IMenuRegistry
{
readonly
onDidChangeMenu
:
Event
<
IMenuRegistryChangeEvent
>
;
addCommands
(
newCommands
:
Iterable
<
ICommandAction
>
):
IDisposable
;
addCommand
(
userCommand
:
ICommandAction
):
IDisposable
;
getCommand
(
id
:
string
):
ICommandAction
|
undefined
;
getCommands
():
ICommandsMap
;
appendMenuItems
(
items
:
Iterable
<
{
id
:
MenuId
,
item
:
IMenuItem
|
ISubmenuItem
}
>
):
IDisposable
;
appendMenuItem
(
menu
:
MenuId
,
item
:
IMenuItem
|
ISubmenuItem
):
IDisposable
;
getMenuItems
(
loc
:
MenuId
):
Array
<
IMenuItem
|
ISubmenuItem
>
;
readonly
onDidChangeMenu
:
Event
<
MenuId
>
;
}
export
const
MenuRegistry
:
IMenuRegistry
=
new
class
implements
IMenuRegistry
{
private
readonly
_commands
=
new
Map
<
string
,
ICommandAction
>
();
private
readonly
_menuItems
=
new
Map
<
MenuId
,
Array
<
IMenuItem
|
ISubmenuItem
>>
();
private
readonly
_onDidChangeMenu
=
new
Emitter
<
MenuId
>
();
private
readonly
_onDidChangeMenu
=
new
Emitter
<
IMenuRegistryChangeEvent
>
();
readonly
onDidChangeMenu
:
Event
<
MenuId
>
=
this
.
_onDidChangeMenu
.
event
;
readonly
onDidChangeMenu
:
Event
<
IMenuRegistryChangeEvent
>
=
this
.
_onDidChangeMenu
.
event
;
addCommand
(
command
:
ICommandAction
):
IDisposable
{
this
.
_commands
.
set
(
command
.
id
,
command
);
this
.
_onDidChangeMenu
.
fire
(
MenuId
.
CommandPalette
);
return
this
.
addCommands
(
Iterable
.
single
(
command
));
}
private
readonly
_commandPaletteChangeEvent
:
IMenuRegistryChangeEvent
=
{
has
:
id
=>
id
===
MenuId
.
CommandPalette
};
addCommands
(
commands
:
Iterable
<
ICommandAction
>
):
IDisposable
{
for
(
const
command
of
commands
)
{
this
.
_commands
.
set
(
command
.
id
,
command
);
}
this
.
_onDidChangeMenu
.
fire
(
this
.
_commandPaletteChangeEvent
);
return
{
dispose
:
()
=>
{
if
(
this
.
_commands
.
delete
(
command
.
id
))
{
this
.
_onDidChangeMenu
.
fire
(
MenuId
.
CommandPalette
);
let
didChange
=
false
;
for
(
const
command
of
commands
)
{
didChange
=
this
.
_commands
.
delete
(
command
.
id
)
||
didChange
;
}
if
(
didChange
)
{
this
.
_onDidChangeMenu
.
fire
(
this
.
_commandPaletteChangeEvent
);
}
}
};
...
...
@@ -193,20 +214,37 @@ export const MenuRegistry: IMenuRegistry = new class implements IMenuRegistry {
}
appendMenuItem
(
id
:
MenuId
,
item
:
IMenuItem
|
ISubmenuItem
):
IDisposable
{
let
array
=
this
.
_menuItems
.
get
(
id
);
if
(
!
array
)
{
array
=
[
item
];
this
.
_menuItems
.
set
(
id
,
array
);
}
else
{
array
.
push
(
item
);
return
this
.
appendMenuItems
(
Iterable
.
single
({
id
,
item
}));
}
appendMenuItems
(
items
:
Iterable
<
{
id
:
MenuId
,
item
:
IMenuItem
|
ISubmenuItem
}
>
):
IDisposable
{
const
changedIds
=
new
Set
<
MenuId
>
();
for
(
const
{
id
,
item
}
of
items
)
{
let
array
=
this
.
_menuItems
.
get
(
id
);
if
(
!
array
)
{
array
=
[
item
];
this
.
_menuItems
.
set
(
id
,
array
);
}
else
{
array
.
push
(
item
);
}
changedIds
.
add
(
id
);
}
this
.
_onDidChangeMenu
.
fire
(
id
);
this
.
_onDidChangeMenu
.
fire
(
changedIds
);
return
{
dispose
:
()
=>
{
const
idx
=
array
!
.
indexOf
(
item
);
if
(
idx
>=
0
)
{
array
!
.
splice
(
idx
,
1
);
this
.
_onDidChangeMenu
.
fire
(
id
);
const
changedIds
=
new
Set
<
MenuId
>
();
for
(
const
{
id
,
item
}
of
items
)
{
const
array
=
this
.
_menuItems
.
get
(
id
);
const
idx
=
array
?.
indexOf
(
item
)
??
-
1
;
if
(
idx
>=
0
)
{
array
!
.
splice
(
idx
,
1
);
changedIds
.
add
(
id
);
}
this
.
_onDidChangeMenu
.
fire
(
changedIds
);
}
}
};
...
...
src/vs/platform/actions/common/menuService.ts
浏览文件 @
2bac4776
...
...
@@ -45,7 +45,7 @@ class Menu implements IMenu {
// rebuild this menu whenever the menu registry reports an
// event for this MenuId
this
.
_dispoables
.
add
(
Event
.
debounce
(
Event
.
filter
(
MenuRegistry
.
onDidChangeMenu
,
menuId
=>
menuId
===
this
.
_id
),
Event
.
filter
(
MenuRegistry
.
onDidChangeMenu
,
set
=>
set
.
has
(
this
.
_id
)
),
()
=>
{
},
50
)(
this
.
_build
,
this
));
...
...
src/vs/workbench/api/common/menusExtensionPoint.ts
浏览文件 @
2bac4776
...
...
@@ -10,7 +10,7 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema';
import
{
forEach
}
from
'
vs/base/common/collections
'
;
import
{
IExtensionPointUser
,
ExtensionMessageCollector
,
ExtensionsRegistry
}
from
'
vs/workbench/services/extensions/common/extensionsRegistry
'
;
import
{
ContextKeyExpr
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
MenuId
,
MenuRegistry
,
ILocalizedString
,
IMenuItem
}
from
'
vs/platform/actions/common/actions
'
;
import
{
MenuId
,
MenuRegistry
,
ILocalizedString
,
IMenuItem
,
ICommandAction
}
from
'
vs/platform/actions/common/actions
'
;
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
DisposableStore
}
from
'
vs/base/common/lifecycle
'
;
import
{
ThemeIcon
}
from
'
vs/platform/theme/common/themeService
'
;
...
...
@@ -381,7 +381,7 @@ export const commandsExtensionPoint = ExtensionsRegistry.registerExtensionPoint<
commandsExtensionPoint
.
setHandler
(
extensions
=>
{
function
handleCommand
(
userFriendlyCommand
:
schema
.
IUserFriendlyCommand
,
extension
:
IExtensionPointUser
<
any
>
)
{
function
handleCommand
(
userFriendlyCommand
:
schema
.
IUserFriendlyCommand
,
extension
:
IExtensionPointUser
<
any
>
,
bucket
:
ICommandAction
[]
)
{
if
(
!
schema
.
isValidCommand
(
userFriendlyCommand
,
extension
.
collector
))
{
return
;
...
...
@@ -405,29 +405,30 @@ commandsExtensionPoint.setHandler(extensions => {
if
(
MenuRegistry
.
getCommand
(
command
))
{
extension
.
collector
.
info
(
localize
(
'
dup
'
,
"
Command `{0}` appears multiple times in the `commands` section.
"
,
userFriendlyCommand
.
command
));
}
const
registration
=
MenuRegistry
.
addCommand
({
bucket
.
push
({
id
:
command
,
title
,
category
,
precondition
:
ContextKeyExpr
.
deserialize
(
enablement
),
icon
:
absoluteIcon
});
_commandRegistrations
.
add
(
registration
);
}
// remove all previous command registrations
_commandRegistrations
.
clear
();
const
newCommands
:
ICommandAction
[]
=
[];
for
(
const
extension
of
extensions
)
{
const
{
value
}
=
extension
;
if
(
Array
.
isArray
(
value
))
{
for
(
const
command
of
value
)
{
handleCommand
(
command
,
extension
);
handleCommand
(
command
,
extension
,
newCommands
);
}
}
else
{
handleCommand
(
value
,
extension
);
handleCommand
(
value
,
extension
,
newCommands
);
}
}
_commandRegistrations
.
add
(
MenuRegistry
.
addCommands
(
newCommands
));
});
const
_menuRegistrations
=
new
DisposableStore
();
...
...
@@ -440,6 +441,8 @@ ExtensionsRegistry.registerExtensionPoint<{ [loc: string]: schema.IUserFriendlyM
// remove all previous menu registrations
_menuRegistrations
.
clear
();
const
items
:
{
id
:
MenuId
,
item
:
IMenuItem
}[]
=
[];
for
(
let
extension
of
extensions
)
{
const
{
value
,
collector
}
=
extension
;
...
...
@@ -461,7 +464,7 @@ ExtensionsRegistry.registerExtensionPoint<{ [loc: string]: schema.IUserFriendlyM
for
(
let
item
of
entry
.
value
)
{
let
command
=
MenuRegistry
.
getCommand
(
item
.
command
);
let
alt
=
item
.
alt
&&
MenuRegistry
.
getCommand
(
item
.
alt
);
let
alt
=
item
.
alt
&&
MenuRegistry
.
getCommand
(
item
.
alt
)
||
undefined
;
if
(
!
command
)
{
collector
.
error
(
localize
(
'
missing.command
'
,
"
Menu item references a command `{0}` which is not defined in the 'commands' section.
"
,
item
.
command
));
...
...
@@ -486,15 +489,19 @@ ExtensionsRegistry.registerExtensionPoint<{ [loc: string]: schema.IUserFriendlyM
}
}
const
registration
=
MenuRegistry
.
appendMenuItem
(
menu
,
{
command
,
alt
,
group
,
order
,
when
:
ContextKeyExpr
.
deserialize
(
item
.
when
)
}
as
IMenuItem
);
_menuRegistrations
.
add
(
registration
);
items
.
push
({
id
:
menu
,
item
:
{
command
,
alt
,
group
,
order
,
when
:
ContextKeyExpr
.
deserialize
(
item
.
when
)
}
});
}
});
}
_menuRegistrations
.
add
(
MenuRegistry
.
appendMenuItems
(
items
));
});
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录