Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
后端镜像
Tabby
提交
0de12b6b
T
Tabby
项目概览
后端镜像
/
Tabby
通知
35
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
Tabby
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
0de12b6b
编写于
11月 26, 2017
作者:
E
Eugene Pankov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
allow disabling plugins
上级
0c15f503
变更
17
隐藏空白更改
内联
并排
Showing
17 changed file
with
92 addition
and
42 deletion
+92
-42
app/src/app.module.ts
app/src/app.module.ts
+1
-1
app/src/entry.ts
app/src/entry.ts
+1
-0
app/src/plugins.ts
app/src/plugins.ts
+18
-13
terminus-core/src/components/appRoot.component.ts
terminus-core/src/components/appRoot.component.ts
+1
-1
terminus-core/src/components/startPage.component.ts
terminus-core/src/components/startPage.component.ts
+3
-1
terminus-core/src/configDefaults.yaml
terminus-core/src/configDefaults.yaml
+1
-0
terminus-core/src/services/config.service.ts
terminus-core/src/services/config.service.ts
+26
-0
terminus-core/src/services/hotkeys.service.ts
terminus-core/src/services/hotkeys.service.ts
+1
-1
terminus-core/src/services/tabRecovery.service.ts
terminus-core/src/services/tabRecovery.service.ts
+3
-1
terminus-core/src/services/themes.service.ts
terminus-core/src/services/themes.service.ts
+1
-1
terminus-plugin-manager/src/components/pluginsSettingsTab.component.pug
...n-manager/src/components/pluginsSettingsTab.component.pug
+14
-15
terminus-plugin-manager/src/components/pluginsSettingsTab.component.ts
...in-manager/src/components/pluginsSettingsTab.component.ts
+12
-0
terminus-settings/src/components/settingsTab.component.ts
terminus-settings/src/components/settingsTab.component.ts
+3
-1
terminus-terminal/src/components/terminalSettingsTab.component.ts
...-terminal/src/components/terminalSettingsTab.component.ts
+3
-3
terminus-terminal/src/components/terminalTab.component.ts
terminus-terminal/src/components/terminalTab.component.ts
+2
-2
terminus-terminal/src/services/sessions.service.ts
terminus-terminal/src/services/sessions.service.ts
+1
-1
terminus-terminal/src/services/terminal.service.ts
terminus-terminal/src/services/terminal.service.ts
+1
-1
未找到文件。
app/src/app.module.ts
浏览文件 @
0de12b6b
...
...
@@ -5,7 +5,7 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
export
function
getRootModule
(
plugins
:
any
[])
{
let
imports
=
[
BrowserModule
,
...
(
plugins
.
map
(
x
=>
x
.
default
.
forRoot
?
x
.
default
.
forRoot
()
:
x
.
default
))
,
...
plugins
,
NgbModule
.
forRoot
(),
]
let
bootstrap
=
[
...
...
app/src/entry.ts
浏览文件 @
0de12b6b
...
...
@@ -30,6 +30,7 @@ async function bootstrap (plugins: IPluginInfo[], safeMode = false): Promise<NgM
(
document
.
querySelector
(
'
.progress .bar
'
)
as
HTMLElement
).
style
.
width
=
100
*
current
/
total
+
'
%
'
})
let
module
=
getRootModule
(
pluginsModules
)
window
[
'
rootModule
'
]
=
module
return
await
platformBrowserDynamic
().
bootstrapModule
(
module
)
}
...
...
app/src/plugins.ts
浏览文件 @
0de12b6b
...
...
@@ -82,7 +82,7 @@ nodeRequire('module').prototype.require = function (query) {
export
async
function
findPlugins
():
Promise
<
IPluginInfo
[]
>
{
let
paths
=
nodeModule
.
globalPaths
let
foundPlugins
:
IPluginInfo
[]
=
[]
let
candidateLocations
:
{
pluginDir
:
string
,
p
lugin
Name
:
string
}[]
=
[]
let
candidateLocations
:
{
pluginDir
:
string
,
p
ackage
Name
:
string
}[]
=
[]
for
(
let
pluginDir
of
paths
)
{
pluginDir
=
normalizePath
(
pluginDir
)
...
...
@@ -93,24 +93,26 @@ export async function findPlugins (): Promise<IPluginInfo[]> {
if
(
await
fs
.
exists
(
path
.
join
(
pluginDir
,
'
package.json
'
)))
{
candidateLocations
.
push
({
pluginDir
:
path
.
dirname
(
pluginDir
),
p
lugin
Name
:
path
.
basename
(
pluginDir
)
p
ackage
Name
:
path
.
basename
(
pluginDir
)
})
}
for
(
let
p
lugin
Name
of
pluginNames
)
{
candidateLocations
.
push
({
pluginDir
,
p
lugin
Name
})
for
(
let
p
ackage
Name
of
pluginNames
)
{
candidateLocations
.
push
({
pluginDir
,
p
ackage
Name
})
}
}
for
(
let
{
pluginDir
,
p
lugin
Name
}
of
candidateLocations
)
{
let
pluginPath
=
path
.
join
(
pluginDir
,
p
lugin
Name
)
for
(
let
{
pluginDir
,
p
ackage
Name
}
of
candidateLocations
)
{
let
pluginPath
=
path
.
join
(
pluginDir
,
p
ackage
Name
)
let
infoPath
=
path
.
join
(
pluginPath
,
'
package.json
'
)
if
(
!
await
fs
.
exists
(
infoPath
))
{
continue
}
if
(
foundPlugins
.
some
(
x
=>
x
.
name
===
pluginName
.
substring
(
'
terminus-
'
.
length
)))
{
console
.
info
(
`Plugin
${
pluginName
}
already exists, overriding`
)
foundPlugins
=
foundPlugins
.
filter
(
x
=>
x
.
name
!==
pluginName
.
substring
(
'
terminus-
'
.
length
))
let
name
=
packageName
.
substring
(
'
terminus-
'
.
length
)
if
(
foundPlugins
.
some
(
x
=>
x
.
name
===
name
))
{
console
.
info
(
`Plugin
${
packageName
}
already exists, overriding`
)
foundPlugins
=
foundPlugins
.
filter
(
x
=>
x
.
name
!==
name
)
}
try
{
...
...
@@ -121,8 +123,8 @@ export async function findPlugins (): Promise<IPluginInfo[]> {
let
author
=
info
.
author
author
=
author
.
name
||
author
foundPlugins
.
push
({
name
:
pluginName
.
substring
(
'
terminus-
'
.
length
)
,
packageName
:
p
lugin
Name
,
name
:
name
,
packageName
:
p
ackage
Name
,
isBuiltin
:
pluginDir
===
builtinPluginsPath
,
version
:
info
.
version
,
description
:
info
.
description
,
...
...
@@ -131,7 +133,7 @@ export async function findPlugins (): Promise<IPluginInfo[]> {
info
,
})
}
catch
(
error
)
{
console
.
error
(
'
Cannot load package info for
'
,
p
lugin
Name
)
console
.
error
(
'
Cannot load package info for
'
,
p
ackage
Name
)
}
}
...
...
@@ -147,7 +149,10 @@ export async function loadPlugins (foundPlugins: IPluginInfo[], progress: Progre
console
.
info
(
`Loading
${
foundPlugin
.
name
}
:
${
nodeRequire
.
resolve
(
foundPlugin
.
path
)}
`
)
progress
(
index
,
foundPlugins
.
length
)
try
{
let
pluginModule
=
nodeRequire
(
foundPlugin
.
path
)
let
packageModule
=
nodeRequire
(
foundPlugin
.
path
)
let
pluginModule
=
packageModule
.
default
.
forRoot
?
packageModule
.
default
.
forRoot
()
:
packageModule
.
default
pluginModule
[
'
pluginName
'
]
=
foundPlugin
.
name
pluginModule
[
'
bootstrap
'
]
=
packageModule
.
bootstrap
plugins
.
push
(
pluginModule
)
}
catch
(
error
)
{
console
.
error
(
`Could not load
${
foundPlugin
.
name
}
:`
,
error
)
...
...
terminus-core/src/components/appRoot.component.ts
浏览文件 @
0de12b6b
...
...
@@ -170,7 +170,7 @@ export class AppRootComponent {
private
getToolbarButtons
(
aboveZero
:
boolean
):
IToolbarButton
[]
{
let
buttons
:
IToolbarButton
[]
=
[]
this
.
toolbarButtonProviders
.
forEach
((
provider
)
=>
{
this
.
config
.
enabledServices
(
this
.
toolbarButtonProviders
).
forEach
(
provider
=>
{
buttons
=
buttons
.
concat
(
provider
.
provide
())
})
return
buttons
...
...
terminus-core/src/components/startPage.component.ts
浏览文件 @
0de12b6b
import
*
as
os
from
'
os
'
import
{
Component
,
Inject
}
from
'
@angular/core
'
import
{
ElectronService
}
from
'
../services/electron.service
'
import
{
ConfigService
}
from
'
../services/config.service
'
import
{
IToolbarButton
,
ToolbarButtonProvider
}
from
'
../api
'
@
Component
({
...
...
@@ -13,13 +14,14 @@ export class StartPageComponent {
constructor
(
private
electron
:
ElectronService
,
private
config
:
ConfigService
,
@
Inject
(
ToolbarButtonProvider
)
private
toolbarButtonProviders
:
ToolbarButtonProvider
[],
)
{
this
.
version
=
electron
.
app
.
getVersion
()
}
getButtons
():
IToolbarButton
[]
{
return
this
.
toolbarButtonProviders
return
this
.
config
.
enabledServices
(
this
.
toolbarButtonProviders
)
.
map
(
provider
=>
provider
.
provide
())
.
reduce
((
a
,
b
)
=>
a
.
concat
(
b
))
.
sort
((
a
:
IToolbarButton
,
b
:
IToolbarButton
)
=>
(
a
.
weight
||
0
)
-
(
b
.
weight
||
0
))
...
...
terminus-core/src/configDefaults.yaml
浏览文件 @
0de12b6b
...
...
@@ -6,3 +6,4 @@ appearance:
theme
:
Standard
frame
:
thin
css
:
'
/*
*
{
color:
blue
!important;
}
*/'
pluginBlacklist
:
[]
terminus-core/src/services/config.service.ts
浏览文件 @
0de12b6b
...
...
@@ -6,6 +6,7 @@ import { Injectable, Inject } from '@angular/core'
import
{
ConfigProvider
}
from
'
../api/configProvider
'
import
{
ElectronService
}
from
'
./electron.service
'
import
{
HostAppService
}
from
'
./hostApp.service
'
import
*
as
Reflect
from
'
core-js/es7/reflect
'
const
configMerge
=
(
a
,
b
)
=>
require
(
'
deepmerge
'
)(
a
,
b
,
{
arrayMerge
:
(
_d
,
s
)
=>
s
})
...
...
@@ -57,6 +58,7 @@ export class ConfigService {
private
_store
:
any
private
path
:
string
private
defaults
:
any
private
servicesCache
:
{
[
id
:
string
]:
Function
[]
}
=
null
constructor
(
electron
:
ElectronService
,
...
...
@@ -98,4 +100,28 @@ export class ConfigService {
requestRestart
():
void
{
this
.
restartRequested
=
true
}
enabledServices
<
T
>
(
services
:
T
[]):
T
[]
{
if
(
!
this
.
servicesCache
)
{
this
.
servicesCache
=
{}
let
ngModule
=
Reflect
.
getMetadata
(
'
annotations
'
,
window
[
'
rootModule
'
])[
0
]
for
(
let
imp
of
ngModule
.
imports
)
{
let
module
=
imp
[
'
module
'
]
||
imp
let
annotations
=
Reflect
.
getMetadata
(
'
annotations
'
,
module
)
if
(
annotations
)
{
this
.
servicesCache
[
module
[
'
pluginName
'
]]
=
annotations
[
0
].
providers
.
map
(
provider
=>
{
return
provider
[
'
useClass
'
]
||
provider
})
}
}
}
return
services
.
filter
(
service
=>
{
for
(
let
pluginName
in
this
.
servicesCache
)
{
if
(
this
.
servicesCache
[
pluginName
].
includes
(
service
.
constructor
))
{
return
!
this
.
store
.
pluginBlacklist
.
includes
(
pluginName
)
}
}
return
true
})
}
}
terminus-core/src/services/hotkeys.service.ts
浏览文件 @
0de12b6b
...
...
@@ -42,7 +42,7 @@ export class HotkeysService {
}
})
})
this
.
hotkeyDescriptions
=
hotkeyProviders
.
map
(
x
=>
x
.
hotkeys
).
reduce
((
a
,
b
)
=>
a
.
concat
(
b
))
this
.
hotkeyDescriptions
=
this
.
config
.
enabledServices
(
hotkeyProviders
)
.
map
(
x
=>
x
.
hotkeys
).
reduce
((
a
,
b
)
=>
a
.
concat
(
b
))
this
.
config
.
changed$
.
subscribe
(()
=>
{
this
.
registerGlobalHotkey
()
})
...
...
terminus-core/src/services/tabRecovery.service.ts
浏览文件 @
0de12b6b
...
...
@@ -3,6 +3,7 @@ import { TabRecoveryProvider, RecoveredTab } from '../api/tabRecovery'
import
{
BaseTabComponent
}
from
'
../components/baseTab.component
'
import
{
Logger
,
LogService
}
from
'
../services/log.service
'
import
{
AppService
}
from
'
../services/app.service
'
import
{
ConfigService
}
from
'
../services/config.service
'
@
Injectable
()
export
class
TabRecoveryService
{
...
...
@@ -11,6 +12,7 @@ export class TabRecoveryService {
constructor
(
@
Inject
(
TabRecoveryProvider
)
private
tabRecoveryProviders
:
TabRecoveryProvider
[],
private
app
:
AppService
,
private
config
:
ConfigService
,
log
:
LogService
)
{
this
.
logger
=
log
.
create
(
'
tabRecovery
'
)
...
...
@@ -31,7 +33,7 @@ export class TabRecoveryService {
if
(
window
.
localStorage
.
tabsRecovery
)
{
let
tabs
:
RecoveredTab
[]
=
[]
for
(
let
token
of
JSON
.
parse
(
window
.
localStorage
.
tabsRecovery
))
{
for
(
let
provider
of
this
.
tabRecoveryProviders
)
{
for
(
let
provider
of
this
.
config
.
enabledServices
(
this
.
tabRecoveryProviders
)
)
{
try
{
let
tab
=
await
provider
.
recover
(
token
)
if
(
tab
)
{
...
...
terminus-core/src/services/themes.service.ts
浏览文件 @
0de12b6b
...
...
@@ -17,7 +17,7 @@ export class ThemesService {
}
findTheme
(
name
:
string
):
Theme
{
return
this
.
themes
.
find
(
x
=>
x
.
name
===
name
)
return
this
.
config
.
enabledServices
(
this
.
themes
)
.
find
(
x
=>
x
.
name
===
name
)
}
findCurrentTheme
():
Theme
{
...
...
terminus-plugin-manager/src/components/pluginsSettingsTab.component.pug
浏览文件 @
0de12b6b
...
...
@@ -10,34 +10,23 @@ h3 Installed
.list-group
ng-container(*ngFor='let plugin of pluginManager.installedPlugins|orderBy:"name"')
.list-group-item.flex-column.align-items-start
(*ngIf='knownUpgrades[plugin.name]')
.list-group-item.flex-column.align-items-start
.d-flex.w-100
.mr-auto.d-flex.flex-column
strong {{plugin.name}}
small.text-muted.mb-0((click)='showPluginInfo(plugin)') {{plugin.description}}
a.text-muted.mb-0((click)='showPluginInfo(plugin)')
small {{plugin.description}}
.d-flex.flex-column.align-items-end.mr-3
div {{plugin.version}}
small.text-muted {{plugin.author}}
button.btn.btn-outline-primary(
*ngIf='npmInstalled',
*ngIf='npmInstalled
&& knownUpgrades[plugin.name]
',
(click)='upgradePlugin(plugin)',
[disabled]='busy[plugin.name] != undefined'
)
i.fa.fa-fw.fa-arrow-up(*ngIf='busy[plugin.name] != BusyState.Installing')
i.fa.fa-fw.fa-circle-o-notch.fa-spin(*ngIf='busy[plugin.name] == BusyState.Installing')
span Upgrade ({{knownUpgrades[plugin.name].version}})
ng-container(*ngFor='let plugin of pluginManager.installedPlugins|orderBy:"name"')
.list-group-item.flex-column.align-items-start(*ngIf='!knownUpgrades[plugin.name]')
.d-flex.w-100
.mr-auto.d-flex.flex-column
strong {{plugin.name}}
a.text-muted.mb-0((click)='showPluginInfo(plugin)')
small {{plugin.description}}
.d-flex.flex-column.align-items-end.mr-3
div {{plugin.version}}
small.text-muted {{plugin.author}}
i.fa.fa-check.text-success.ml-1(*ngIf='plugin.isOfficial', title='Official')
button.btn.btn-outline-danger(
(click)='uninstallPlugin(plugin)',
*ngIf='!plugin.isBuiltin && npmInstalled',
...
...
@@ -45,6 +34,16 @@ h3 Installed
)
i.fa.fa-fw.fa-trash-o(*ngIf='busy[plugin.name] != BusyState.Uninstalling')
i.fa.fa-fw.fa-circle-o-notch.fa-spin(*ngIf='busy[plugin.name] == BusyState.Uninstalling')
button.btn.btn-outline-danger(
*ngIf='config.store.pluginBlacklist.includes(plugin.name)',
(click)='enablePlugin(plugin)'
)
i.fa.fa-fw.fa-play
button.btn.btn-outline-primary(
*ngIf='!config.store.pluginBlacklist.includes(plugin.name)',
(click)='disablePlugin(plugin)'
)
i.fa.fa-fw.fa-pause
.text-center.mt-5(*ngIf='npmMissing')
h4 npm not installed
...
...
terminus-plugin-manager/src/components/pluginsSettingsTab.component.ts
浏览文件 @
0de12b6b
...
...
@@ -105,4 +105,16 @@ export class PluginsSettingsTabComponent {
showPluginInfo
(
plugin
:
IPluginInfo
)
{
this
.
electron
.
shell
.
openExternal
(
'
https://www.npmjs.com/package/
'
+
plugin
.
packageName
)
}
enablePlugin
(
plugin
:
IPluginInfo
)
{
this
.
config
.
store
.
pluginBlacklist
=
this
.
config
.
store
.
pluginBlacklist
.
filter
(
x
=>
x
!==
plugin
.
name
)
this
.
config
.
save
()
this
.
config
.
requestRestart
()
}
disablePlugin
(
plugin
:
IPluginInfo
)
{
this
.
config
.
store
.
pluginBlacklist
.
push
(
plugin
.
name
)
this
.
config
.
save
()
this
.
config
.
requestRestart
()
}
}
terminus-settings/src/components/settingsTab.component.ts
浏览文件 @
0de12b6b
...
...
@@ -27,10 +27,12 @@ export class SettingsTabComponent extends BaseTabComponent {
@
Inject
(
Theme
)
public
themes
:
Theme
[],
)
{
super
()
this
.
hotkeyDescriptions
=
hotkeyProviders
.
map
(
x
=>
x
.
hotkeys
).
reduce
((
a
,
b
)
=>
a
.
concat
(
b
))
this
.
hotkeyDescriptions
=
config
.
enabledServices
(
hotkeyProviders
)
.
map
(
x
=>
x
.
hotkeys
).
reduce
((
a
,
b
)
=>
a
.
concat
(
b
))
this
.
title
=
'
Settings
'
this
.
scrollable
=
true
this
.
screens
=
this
.
docking
.
getScreens
()
this
.
settingsProviders
=
config
.
enabledServices
(
this
.
settingsProviders
)
this
.
themes
=
config
.
enabledServices
(
this
.
themes
)
}
getRecoveryToken
():
any
{
...
...
terminus-terminal/src/components/terminalSettingsTab.component.ts
浏览文件 @
0de12b6b
...
...
@@ -27,7 +27,7 @@ export class TerminalSettingsTabComponent {
@
Inject
(
TerminalColorSchemeProvider
)
private
colorSchemeProviders
:
TerminalColorSchemeProvider
[],
@
Inject
(
SessionPersistenceProvider
)
persistenceProviders
:
SessionPersistenceProvider
[],
)
{
this
.
persistenceProviders
=
persistenceProviders
.
filter
(
x
=>
x
.
isAvailable
())
this
.
persistenceProviders
=
this
.
config
.
enabledServices
(
persistenceProviders
)
.
filter
(
x
=>
x
.
isAvailable
())
}
async
ngOnInit
()
{
...
...
@@ -46,8 +46,8 @@ export class TerminalSettingsTabComponent {
this
.
fonts
.
sort
()
})
}
this
.
colorSchemes
=
(
await
Promise
.
all
(
this
.
co
lorSchemeProviders
.
map
(
x
=>
x
.
getSchemes
()))).
reduce
((
a
,
b
)
=>
a
.
concat
(
b
))
this
.
shells
=
(
await
Promise
.
all
(
this
.
shellProviders
.
map
(
x
=>
x
.
provide
()))).
reduce
((
a
,
b
)
=>
a
.
concat
(
b
))
this
.
colorSchemes
=
(
await
Promise
.
all
(
this
.
co
nfig
.
enabledServices
(
this
.
colorSchemeProviders
)
.
map
(
x
=>
x
.
getSchemes
()))).
reduce
((
a
,
b
)
=>
a
.
concat
(
b
))
this
.
shells
=
(
await
Promise
.
all
(
this
.
config
.
enabledServices
(
this
.
shellProviders
)
.
map
(
x
=>
x
.
provide
()))).
reduce
((
a
,
b
)
=>
a
.
concat
(
b
))
}
fontAutocomplete
=
(
text$
:
Observable
<
string
>
)
=>
{
...
...
terminus-terminal/src/components/terminalTab.component.ts
浏览文件 @
0de12b6b
...
...
@@ -125,7 +125,7 @@ export class TerminalTabComponent extends BaseTabComponent {
})
this
.
hterm
=
new
hterm
.
hterm
.
Terminal
()
this
.
decorators
.
forEach
((
decorator
)
=>
{
this
.
config
.
enabledServices
(
this
.
decorators
)
.
forEach
((
decorator
)
=>
{
decorator
.
attach
(
this
)
})
...
...
@@ -406,7 +406,7 @@ export class TerminalTabComponent extends BaseTabComponent {
}
ngOnDestroy
()
{
this
.
decorators
.
forEach
(
decorator
=>
{
this
.
config
.
enabledServices
(
this
.
decorators
)
.
forEach
(
decorator
=>
{
decorator
.
detach
(
this
)
})
this
.
hotkeysSubscription
.
unsubscribe
()
...
...
terminus-terminal/src/services/sessions.service.ts
浏览文件 @
0de12b6b
...
...
@@ -202,7 +202,7 @@ export class SessionsService {
)
{
nodePTY
=
electron
.
remoteRequirePluginModule
(
'
terminus-terminal
'
,
'
node-pty-tmp
'
,
global
as
any
)
this
.
logger
=
log
.
create
(
'
sessions
'
)
this
.
persistenceProviders
=
this
.
persistenceProviders
.
filter
(
x
=>
x
.
isAvailable
())
this
.
persistenceProviders
=
this
.
config
.
enabledServices
(
this
.
persistenceProviders
)
.
filter
(
x
=>
x
.
isAvailable
())
}
async
prepareNewSession
(
options
:
SessionOptions
):
Promise
<
SessionOptions
>
{
...
...
terminus-terminal/src/services/terminal.service.ts
浏览文件 @
0de12b6b
...
...
@@ -27,7 +27,7 @@ export class TerminalService {
async
reloadShells
()
{
this
.
shells$
=
new
AsyncSubject
<
IShell
[]
>
()
let
shellLists
=
await
Promise
.
all
(
this
.
shellProviders
.
map
(
x
=>
x
.
provide
()))
let
shellLists
=
await
Promise
.
all
(
this
.
config
.
enabledServices
(
this
.
shellProviders
)
.
map
(
x
=>
x
.
provide
()))
this
.
shells$
.
next
(
shellLists
.
reduce
((
a
,
b
)
=>
a
.
concat
(
b
)))
this
.
shells$
.
complete
()
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录