mirror of
https://github.com/Eugeny/tabby.git
synced 2025-07-21 19:07:59 +00:00
Merge branch 'master' of github.com:Eugeny/terminus
This commit is contained in:
82
app/main.js
82
app/main.js
@@ -108,25 +108,79 @@ setupWindowManagement = () => {
|
|||||||
|
|
||||||
|
|
||||||
setupMenu = () => {
|
setupMenu = () => {
|
||||||
var template = [{
|
let template = [{
|
||||||
label: "Application",
|
label: "Application",
|
||||||
submenu: [
|
submenu: [
|
||||||
{ type: "separator" },
|
{ role: 'about', label: 'About Terminus' },
|
||||||
{ label: "Quit", accelerator: "CmdOrCtrl+Q", click: () => {
|
{ type: 'separator' },
|
||||||
app.window.webContents.send('host:quit-request')
|
{
|
||||||
}}
|
label: 'Preferences',
|
||||||
|
accelerator: 'Cmd+,',
|
||||||
|
click () {
|
||||||
|
app.window.webContents.send('host:preferences-menu')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ type: 'separator' },
|
||||||
|
{ role: 'services', submenu: [] },
|
||||||
|
{ type: 'separator' },
|
||||||
|
{ role: 'hide' },
|
||||||
|
{ role: 'hideothers' },
|
||||||
|
{ role: 'unhide' },
|
||||||
|
{ type: 'separator' },
|
||||||
|
{
|
||||||
|
label: 'Quit',
|
||||||
|
accelerator: 'Cmd+Q',
|
||||||
|
click () {
|
||||||
|
app.window.webContents.send('host:quit-request')
|
||||||
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Edit",
|
label: "Edit",
|
||||||
submenu: [
|
submenu: [
|
||||||
{ label: "Undo", accelerator: "CmdOrCtrl+Z", selector: "undo:" },
|
{role: 'undo'},
|
||||||
{ label: "Redo", accelerator: "Shift+CmdOrCtrl+Z", selector: "redo:" },
|
{role: 'redo'},
|
||||||
{ type: "separator" },
|
{type: 'separator'},
|
||||||
{ label: "Cut", accelerator: "CmdOrCtrl+X", selector: "cut:" },
|
{role: 'cut'},
|
||||||
{ label: "Copy", accelerator: "CmdOrCtrl+C", selector: "copy:" },
|
{role: 'copy'},
|
||||||
{ label: "Paste", accelerator: "CmdOrCtrl+V", selector: "paste:" },
|
{role: 'paste'},
|
||||||
{ label: "Select All", accelerator: "CmdOrCtrl+A", selector: "selectAll:" }
|
{role: 'pasteandmatchstyle'},
|
||||||
|
{role: 'delete'},
|
||||||
|
{role: 'selectall'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'View',
|
||||||
|
submenu: [
|
||||||
|
{role: 'reload'},
|
||||||
|
{role: 'forcereload'},
|
||||||
|
{role: 'toggledevtools'},
|
||||||
|
{type: 'separator'},
|
||||||
|
{role: 'resetzoom'},
|
||||||
|
{role: 'zoomin'},
|
||||||
|
{role: 'zoomout'},
|
||||||
|
{type: 'separator'},
|
||||||
|
{role: 'togglefullscreen'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: 'window',
|
||||||
|
submenu: [
|
||||||
|
{role: 'close'},
|
||||||
|
{role: 'minimize'},
|
||||||
|
{role: 'zoom'},
|
||||||
|
{type: 'separator'},
|
||||||
|
{role: 'front'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: 'help',
|
||||||
|
submenu: [
|
||||||
|
{
|
||||||
|
label: 'Website',
|
||||||
|
click () { electron.shell.openExternal('https://eugeny.github.io/terminus') }
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
|
|
||||||
|
@@ -19,6 +19,7 @@ export class HostAppService {
|
|||||||
platform: Platform
|
platform: Platform
|
||||||
nodePlatform: string
|
nodePlatform: string
|
||||||
quitRequested = new EventEmitter<any>()
|
quitRequested = new EventEmitter<any>()
|
||||||
|
preferencesMenu$ = new Subject<void>()
|
||||||
ready = new EventEmitter<any>()
|
ready = new EventEmitter<any>()
|
||||||
shown = new EventEmitter<any>()
|
shown = new EventEmitter<any>()
|
||||||
secondInstance$ = new Subject<{ argv: string[], cwd: string }>()
|
secondInstance$ = new Subject<{ argv: string[], cwd: string }>()
|
||||||
@@ -39,6 +40,7 @@ export class HostAppService {
|
|||||||
}[this.nodePlatform]
|
}[this.nodePlatform]
|
||||||
|
|
||||||
electron.ipcRenderer.on('host:quit-request', () => this.zone.run(() => this.quitRequested.emit()))
|
electron.ipcRenderer.on('host:quit-request', () => this.zone.run(() => this.quitRequested.emit()))
|
||||||
|
electron.ipcRenderer.on('host:preferences-menu', () => this.zone.run(() => this.preferencesMenu$.next()))
|
||||||
|
|
||||||
electron.ipcRenderer.on('uncaughtException', ($event, err) => {
|
electron.ipcRenderer.on('uncaughtException', ($event, err) => {
|
||||||
this.logger.error('Unhandled exception:', err)
|
this.logger.error('Unhandled exception:', err)
|
||||||
|
@@ -41,6 +41,9 @@ export class PluginManagerService {
|
|||||||
|
|
||||||
async detectPath () {
|
async detectPath () {
|
||||||
this.npmPath = this.config.store.npm
|
this.npmPath = this.config.store.npm
|
||||||
|
if (await fs.exists(this.npmPath)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if (this.hostApp.platform !== Platform.Windows) {
|
if (this.hostApp.platform !== Platform.Windows) {
|
||||||
let searchPaths = (await exec('bash -c -l "echo $PATH"'))[0].toString().trim().split(':')
|
let searchPaths = (await exec('bash -c -l "echo $PATH"'))[0].toString().trim().split(':')
|
||||||
for (let searchPath of searchPaths) {
|
for (let searchPath of searchPaths) {
|
||||||
|
@@ -1,14 +1,16 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { ToolbarButtonProvider, IToolbarButton, AppService } from 'terminus-core'
|
import { ToolbarButtonProvider, IToolbarButton, AppService, HostAppService } from 'terminus-core'
|
||||||
|
|
||||||
import { SettingsTabComponent } from './components/settingsTab.component'
|
import { SettingsTabComponent } from './components/settingsTab.component'
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ButtonProvider extends ToolbarButtonProvider {
|
export class ButtonProvider extends ToolbarButtonProvider {
|
||||||
constructor (
|
constructor (
|
||||||
|
hostApp: HostAppService,
|
||||||
private app: AppService,
|
private app: AppService,
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
|
hostApp.preferencesMenu$.subscribe(() => this.open())
|
||||||
}
|
}
|
||||||
|
|
||||||
provide (): IToolbarButton[] {
|
provide (): IToolbarButton[] {
|
||||||
@@ -16,14 +18,16 @@ export class ButtonProvider extends ToolbarButtonProvider {
|
|||||||
icon: 'sliders',
|
icon: 'sliders',
|
||||||
title: 'Settings',
|
title: 'Settings',
|
||||||
weight: 10,
|
weight: 10,
|
||||||
click: () => {
|
click: () => this.open(),
|
||||||
let settingsTab = this.app.tabs.find((tab) => tab instanceof SettingsTabComponent)
|
|
||||||
if (settingsTab) {
|
|
||||||
this.app.selectTab(settingsTab)
|
|
||||||
} else {
|
|
||||||
this.app.openNewTab(SettingsTabComponent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open (): void {
|
||||||
|
let settingsTab = this.app.tabs.find((tab) => tab instanceof SettingsTabComponent)
|
||||||
|
if (settingsTab) {
|
||||||
|
this.app.selectTab(settingsTab)
|
||||||
|
} else {
|
||||||
|
this.app.openNewTab(SettingsTabComponent)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -69,6 +69,15 @@ export class TerminalTabComponent extends BaseTabComponent {
|
|||||||
this.session.releaseInitialDataBuffer()
|
this.session.releaseInitialDataBuffer()
|
||||||
})
|
})
|
||||||
this.hotkeysSubscription = this.hotkeys.matchedHotkey.subscribe(hotkey => {
|
this.hotkeysSubscription = this.hotkeys.matchedHotkey.subscribe(hotkey => {
|
||||||
|
if (!this.hasFocus) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (hotkey === 'copy') {
|
||||||
|
this.hterm.copySelectionToClipboard()
|
||||||
|
}
|
||||||
|
if (hotkey === 'clear') {
|
||||||
|
this.clear()
|
||||||
|
}
|
||||||
if (hotkey === 'zoom-in') {
|
if (hotkey === 'zoom-in') {
|
||||||
this.zoomIn()
|
this.zoomIn()
|
||||||
}
|
}
|
||||||
@@ -228,6 +237,11 @@ export class TerminalTabComponent extends BaseTabComponent {
|
|||||||
this.io.writeUTF8(data)
|
this.io.writeUTF8(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clear () {
|
||||||
|
this.hterm.wipeContents()
|
||||||
|
this.hterm.onVTKeystroke('\f')
|
||||||
|
}
|
||||||
|
|
||||||
async configure (): Promise<void> {
|
async configure (): Promise<void> {
|
||||||
let config = this.config.store
|
let config = this.config.store
|
||||||
preferenceManager.set('font-family', config.terminal.font)
|
preferenceManager.set('font-family', config.terminal.font)
|
||||||
|
@@ -44,6 +44,12 @@ export class TerminalConfigProvider extends ConfigProvider {
|
|||||||
shell: '~default-shell~',
|
shell: '~default-shell~',
|
||||||
},
|
},
|
||||||
hotkeys: {
|
hotkeys: {
|
||||||
|
'copy': [
|
||||||
|
'⌘-C',
|
||||||
|
],
|
||||||
|
'clear': [
|
||||||
|
'⌘-K',
|
||||||
|
],
|
||||||
'zoom-in': [
|
'zoom-in': [
|
||||||
'⌘-=',
|
'⌘-=',
|
||||||
'⌘-Shift-+',
|
'⌘-Shift-+',
|
||||||
@@ -69,6 +75,12 @@ export class TerminalConfigProvider extends ConfigProvider {
|
|||||||
shell: '~clink~',
|
shell: '~clink~',
|
||||||
},
|
},
|
||||||
hotkeys: {
|
hotkeys: {
|
||||||
|
'copy': [
|
||||||
|
'Ctrl-Shift-C',
|
||||||
|
],
|
||||||
|
'clear': [
|
||||||
|
'Ctrl-L',
|
||||||
|
],
|
||||||
'zoom-in': [
|
'zoom-in': [
|
||||||
'Ctrl-=',
|
'Ctrl-=',
|
||||||
'Ctrl-Shift-+',
|
'Ctrl-Shift-+',
|
||||||
@@ -93,6 +105,12 @@ export class TerminalConfigProvider extends ConfigProvider {
|
|||||||
shell: '~default-shell~',
|
shell: '~default-shell~',
|
||||||
},
|
},
|
||||||
hotkeys: {
|
hotkeys: {
|
||||||
|
'copy': [
|
||||||
|
'Ctrl-Shift-C',
|
||||||
|
],
|
||||||
|
'clear': [
|
||||||
|
'Ctrl-L',
|
||||||
|
],
|
||||||
'zoom-in': [
|
'zoom-in': [
|
||||||
'Ctrl-=',
|
'Ctrl-=',
|
||||||
'Ctrl-Shift-+',
|
'Ctrl-Shift-+',
|
||||||
|
@@ -4,6 +4,14 @@ import { IHotkeyDescription, HotkeyProvider } from 'terminus-core'
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class TerminalHotkeyProvider extends HotkeyProvider {
|
export class TerminalHotkeyProvider extends HotkeyProvider {
|
||||||
hotkeys: IHotkeyDescription[] = [
|
hotkeys: IHotkeyDescription[] = [
|
||||||
|
{
|
||||||
|
id: 'copy',
|
||||||
|
name: 'Copy to clipboard',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'clear',
|
||||||
|
name: 'Clear terminal',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'zoom-in',
|
id: 'zoom-in',
|
||||||
name: 'Zoom in',
|
name: 'Zoom in',
|
||||||
|
Reference in New Issue
Block a user