Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
后端镜像
Tabby
提交
9b6a0912
T
Tabby
项目概览
后端镜像
/
Tabby
通知
31
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,发现更多精彩内容 >>
提交
9b6a0912
编写于
10月 12, 2018
作者:
E
Eugene Pankov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
hotkeys for specific shells
上级
cc610e15
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
128 addition
and
25 deletion
+128
-25
terminus-core/src/api/hotkeyProvider.ts
terminus-core/src/api/hotkeyProvider.ts
+2
-0
terminus-core/src/services/config.service.ts
terminus-core/src/services/config.service.ts
+33
-8
terminus-core/src/services/hotkeys.service.ts
terminus-core/src/services/hotkeys.service.ts
+35
-9
terminus-settings/src/components/settingsTab.component.pug
terminus-settings/src/components/settingsTab.component.pug
+2
-2
terminus-settings/src/components/settingsTab.component.ts
terminus-settings/src/components/settingsTab.component.ts
+24
-1
terminus-terminal/src/config.ts
terminus-terminal/src/config.ts
+5
-0
terminus-terminal/src/hotkeys.ts
terminus-terminal/src/hotkeys.ts
+13
-0
terminus-terminal/src/index.ts
terminus-terminal/src/index.ts
+7
-2
terminus-terminal/src/services/terminal.service.ts
terminus-terminal/src/services/terminal.service.ts
+6
-2
terminus-terminal/src/shells/custom.ts
terminus-terminal/src/shells/custom.ts
+1
-1
未找到文件。
terminus-core/src/api/hotkeyProvider.ts
浏览文件 @
9b6a0912
...
...
@@ -5,4 +5,6 @@ export interface IHotkeyDescription {
export
abstract
class
HotkeyProvider
{
hotkeys
:
IHotkeyDescription
[]
=
[]
abstract
provide
():
Promise
<
IHotkeyDescription
[]
>
}
terminus-core/src/services/config.service.ts
浏览文件 @
9b6a0912
...
...
@@ -9,15 +9,19 @@ import { HostAppService } from './hostApp.service'
const
configMerge
=
(
a
,
b
)
=>
require
(
'
deepmerge
'
)(
a
,
b
,
{
arrayMerge
:
(
_d
,
s
)
=>
s
})
function
isStructuralMember
(
v
)
{
return
v
instanceof
Object
&&
!
(
v
instanceof
Array
)
&&
Object
.
keys
(
v
).
length
>
0
&&
!
v
.
__nonStructural
}
function
isNonStructuralObjectMember
(
v
)
{
return
v
instanceof
Object
&&
!
(
v
instanceof
Array
)
&&
v
.
__nonStructural
}
export
class
ConfigProxy
{
constructor
(
real
:
any
,
defaults
:
any
)
{
for
(
let
key
in
defaults
)
{
if
(
defaults
[
key
]
instanceof
Object
&&
!
(
defaults
[
key
]
instanceof
Array
)
&&
Object
.
keys
(
defaults
[
key
]).
length
>
0
&&
!
defaults
[
key
].
__nonStructural
)
{
if
(
isStructuralMember
(
defaults
[
key
]))
{
if
(
!
real
[
key
])
{
real
[
key
]
=
{}
}
...
...
@@ -38,15 +42,36 @@ export class ConfigProxy {
{
enumerable
:
true
,
configurable
:
false
,
get
:
()
=>
(
real
[
key
]
!==
undefined
)
?
real
[
key
]
:
defaults
[
key
]
,
get
:
()
=>
this
.
getValue
(
key
)
,
set
:
(
value
)
=>
{
real
[
key
]
=
value
this
.
setValue
(
key
,
value
)
}
}
)
}
}
this
.
getValue
=
(
key
:
string
)
=>
{
if
(
real
[
key
]
!==
undefined
)
{
return
real
[
key
]
}
else
{
if
(
isNonStructuralObjectMember
(
defaults
[
key
]))
{
real
[
key
]
=
{...
defaults
[
key
]}
delete
real
[
key
].
__nonStructural
return
real
[
key
]
}
else
{
return
defaults
[
key
]
}
}
}
this
.
setValue
=
(
key
:
string
,
value
:
any
)
=>
{
real
[
key
]
=
value
}
}
getValue
(
key
:
string
):
any
{
}
// tslint:disable-line
setValue
(
key
:
string
,
value
:
any
)
{
}
// tslint:disable-line
}
@
Injectable
()
...
...
terminus-core/src/services/hotkeys.service.ts
浏览文件 @
9b6a0912
...
...
@@ -24,13 +24,13 @@ export class HotkeysService {
globalHotkey
=
new
EventEmitter
()
private
currentKeystrokes
:
EventBufferEntry
[]
=
[]
private
disabledLevel
=
0
private
hotkeyDescriptions
:
IHotkeyDescription
[]
private
hotkeyDescriptions
:
IHotkeyDescription
[]
=
[]
constructor
(
private
zone
:
NgZone
,
private
electron
:
ElectronService
,
private
config
:
ConfigService
,
@
Inject
(
HotkeyProvider
)
hotkeyProviders
:
HotkeyProvider
[],
@
Inject
(
HotkeyProvider
)
private
hotkeyProviders
:
HotkeyProvider
[],
)
{
let
events
=
[
'
keydown
'
,
'
keyup
'
]
events
.
forEach
((
event
)
=>
{
...
...
@@ -42,11 +42,13 @@ export class HotkeysService {
}
})
})
this
.
hotkeyDescriptions
=
this
.
config
.
enabledServices
(
hotkeyProviders
).
map
(
x
=>
x
.
hotkeys
).
reduce
((
a
,
b
)
=>
a
.
concat
(
b
))
this
.
config
.
changed$
.
subscribe
(()
=>
{
this
.
registerGlobalHotkey
()
})
this
.
registerGlobalHotkey
()
this
.
getHotkeyDescriptions
().
then
(
hotkeys
=>
{
this
.
hotkeyDescriptions
=
hotkeys
})
}
pushKeystroke
(
name
,
nativeEvent
)
{
...
...
@@ -102,14 +104,25 @@ export class HotkeysService {
}
getHotkeysConfig
()
{
return
this
.
getHotkeysConfigRecursive
(
this
.
config
.
store
.
hotkeys
)
}
getHotkeysConfigRecursive
(
branch
)
{
let
keys
=
{}
for
(
let
key
in
this
.
config
.
store
.
hotkeys
)
{
let
value
=
this
.
config
.
store
.
hotkeys
[
key
]
if
(
typeof
value
===
'
string
'
)
{
value
=
[
value
]
for
(
let
key
in
branch
)
{
let
value
=
branch
[
key
]
if
(
value
instanceof
Object
&&
!
(
value
instanceof
Array
))
{
let
subkeys
=
this
.
getHotkeysConfigRecursive
(
value
)
for
(
let
subkey
in
subkeys
)
{
keys
[
key
+
'
.
'
+
subkey
]
=
subkeys
[
subkey
]
}
}
else
{
if
(
typeof
value
===
'
string
'
)
{
value
=
[
value
]
}
value
=
value
.
map
((
item
)
=>
(
typeof
item
===
'
string
'
)
?
[
item
]
:
item
)
keys
[
key
]
=
value
}
value
=
value
.
map
((
item
)
=>
(
typeof
item
===
'
string
'
)
?
[
item
]
:
item
)
keys
[
key
]
=
value
}
return
keys
}
...
...
@@ -169,6 +182,15 @@ export class HotkeysService {
isEnabled
()
{
return
this
.
disabledLevel
===
0
}
async
getHotkeyDescriptions
():
Promise
<
IHotkeyDescription
[]
>
{
return
(
await
Promise
.
all
(
this
.
config
.
enabledServices
(
this
.
hotkeyProviders
)
.
map
(
async
x
=>
x
.
provide
?
x
.
provide
()
:
x
.
hotkeys
)
)
).
reduce
((
a
,
b
)
=>
a
.
concat
(
b
))
}
}
@
Injectable
()
...
...
@@ -243,4 +265,8 @@ export class AppHotkeyProvider extends HotkeyProvider {
name
:
'
Tab 10
'
,
},
]
async
provide
():
Promise
<
IHotkeyDescription
[]
>
{
return
this
.
hotkeys
}
}
terminus-settings/src/components/settingsTab.component.pug
浏览文件 @
9b6a0912
...
...
@@ -244,8 +244,8 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
td {{hotkey.id}}
td
multi-hotkey-input(
[
(model)]='config.store.hotkeys[hotkey.id]
',
(modelChange)='config.save(); docking.dock()'
[
model]='getHotkey(hotkey.id)
',
(modelChange)='
setHotkey(hotkey.id, $event);
config.save(); docking.dock()'
)
ngb-tab(*ngFor='let provider of settingsProviders', [id]='provider.id')
...
...
terminus-settings/src/components/settingsTab.component.ts
浏览文件 @
9b6a0912
import
*
as
yaml
from
'
js-yaml
'
import
{
Subscription
}
from
'
rxjs
'
import
{
Component
,
Inject
,
Input
}
from
'
@angular/core
'
import
{
HotkeysService
}
from
'
terminus-core
'
import
{
ElectronService
,
DockingService
,
...
...
@@ -43,12 +44,12 @@ export class SettingsTabComponent extends BaseTabComponent {
public
hostApp
:
HostAppService
,
public
homeBase
:
HomeBaseService
,
public
shellIntegration
:
ShellIntegrationService
,
hotkeys
:
HotkeysService
,
@
Inject
(
HotkeyProvider
)
hotkeyProviders
:
HotkeyProvider
[],
@
Inject
(
SettingsTabProvider
)
public
settingsProviders
:
SettingsTabProvider
[],
@
Inject
(
Theme
)
public
themes
:
Theme
[],
)
{
super
()
this
.
hotkeyDescriptions
=
config
.
enabledServices
(
hotkeyProviders
).
map
(
x
=>
x
.
hotkeys
).
reduce
((
a
,
b
)
=>
a
.
concat
(
b
))
this
.
setTitle
(
'
Settings
'
)
this
.
screens
=
this
.
docking
.
getScreens
()
this
.
settingsProviders
=
config
.
enabledServices
(
this
.
settingsProviders
)
...
...
@@ -59,6 +60,10 @@ export class SettingsTabComponent extends BaseTabComponent {
this
.
configSubscription
=
config
.
changed$
.
subscribe
(()
=>
{
this
.
configFile
=
config
.
readRaw
()
})
hotkeys
.
getHotkeyDescriptions
().
then
(
descriptions
=>
{
this
.
hotkeyDescriptions
=
descriptions
})
}
async
ngOnInit
()
{
...
...
@@ -98,4 +103,22 @@ export class SettingsTabComponent extends BaseTabComponent {
await
this
.
shellIntegration
.
install
()
this
.
isShellIntegrationInstalled
=
true
}
getHotkey
(
id
:
string
)
{
let
ptr
=
this
.
config
.
store
.
hotkeys
for
(
let
token
of
id
.
split
(
/
\.
/g
))
{
ptr
=
ptr
[
token
]
}
return
ptr
}
setHotkey
(
id
:
string
,
value
)
{
let
ptr
=
this
.
config
.
store
let
prop
=
'
hotkeys
'
for
(
let
token
of
id
.
split
(
/
\.
/g
))
{
ptr
=
ptr
[
prop
]
prop
=
token
}
ptr
[
prop
]
=
value
}
}
terminus-terminal/src/config.ts
浏览文件 @
9b6a0912
...
...
@@ -2,6 +2,11 @@ import { ConfigProvider, Platform } from 'terminus-core'
export
class
TerminalConfigProvider
extends
ConfigProvider
{
defaults
=
{
hotkeys
:
{
shell
:
{
__nonStructural
:
true
,
},
},
terminal
:
{
frontend
:
'
hterm
'
,
autoOpen
:
false
,
...
...
terminus-terminal/src/hotkeys.ts
浏览文件 @
9b6a0912
import
{
Injectable
}
from
'
@angular/core
'
import
{
IHotkeyDescription
,
HotkeyProvider
}
from
'
terminus-core
'
import
{
TerminalService
}
from
'
./services/terminal.service
'
@
Injectable
()
export
class
TerminalHotkeyProvider
extends
HotkeyProvider
{
...
...
@@ -61,4 +62,16 @@ export class TerminalHotkeyProvider extends HotkeyProvider {
name
:
'
Intelligent Ctrl-C (copy/abort)
'
,
},
]
constructor
(
private
terminal
:
TerminalService
,
)
{
super
()
}
async
provide
():
Promise
<
IHotkeyDescription
[]
>
{
let
shells
=
await
this
.
terminal
.
shells$
.
toPromise
()
return
this
.
hotkeys
.
concat
(
shells
.
map
(
shell
=>
({
id
:
`shell.
${
shell
.
id
}
`
,
name
:
`New tab:
${
shell
.
name
}
`
})))
}
}
terminus-terminal/src/index.ts
浏览文件 @
9b6a0912
...
...
@@ -148,11 +148,16 @@ export default class TerminalModule {
if
(
hotkey
===
'
new-tab
'
)
{
terminal
.
openTab
()
}
})
hotkeys
.
matchedHotkey
.
subscribe
(
async
(
hotkey
)
=>
{
if
(
hotkey
===
'
new-window
'
)
{
hostApp
.
newWindow
()
}
if
(
hotkey
.
startsWith
(
'
shell.
'
))
{
let
shells
=
await
terminal
.
shells$
let
shell
=
shells
.
find
(
x
=>
x
.
id
===
hotkey
.
split
(
'
.
'
)[
1
])
if
(
shell
)
{
terminal
.
openTab
(
shell
)
}
}
})
hostApp
.
cliOpenDirectory$
.
subscribe
(
async
directory
=>
{
if
(
await
fs
.
exists
(
directory
))
{
...
...
terminus-terminal/src/services/terminal.service.ts
浏览文件 @
9b6a0912
...
...
@@ -27,10 +27,14 @@ export class TerminalService {
})
}
async
getShells
():
Promise
<
IShell
[]
>
{
let
shellLists
=
await
Promise
.
all
(
this
.
config
.
enabledServices
(
this
.
shellProviders
).
map
(
x
=>
x
.
provide
()))
return
shellLists
.
reduce
((
a
,
b
)
=>
a
.
concat
(
b
))
}
async
reloadShells
()
{
this
.
shells
=
new
AsyncSubject
<
IShell
[]
>
()
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
.
next
(
await
this
.
getShells
())
this
.
shells
.
complete
()
}
...
...
terminus-terminal/src/shells/custom.ts
浏览文件 @
9b6a0912
...
...
@@ -15,7 +15,7 @@ export class CustomShellProvider extends ShellProvider {
let
args
=
this
.
config
.
store
.
terminal
.
customShell
.
split
(
'
'
)
return
[{
id
:
'
custom
'
,
name
:
'
Custom
'
,
name
:
'
Custom
shell
'
,
command
:
args
[
0
],
args
:
args
.
slice
(
1
),
}]
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录