mirror of
https://github.com/Eugeny/tabby.git
synced 2025-07-20 02:18:01 +00:00
context menu (fixes #42)
This commit is contained in:
@@ -1,15 +1,12 @@
|
||||
import { AsyncSubject } from 'rxjs'
|
||||
import * as fs from 'mz/fs'
|
||||
import * as path from 'path'
|
||||
import { Injectable, Inject } from '@angular/core'
|
||||
import { Injectable } from '@angular/core'
|
||||
import { HotkeysService, ToolbarButtonProvider, IToolbarButton, ConfigService, HostAppService, ElectronService, Logger, LogService } from 'terminus-core'
|
||||
|
||||
import { IShell, ShellProvider } from './api'
|
||||
import { TerminalService } from './services/terminal.service'
|
||||
|
||||
@Injectable()
|
||||
export class ButtonProvider extends ToolbarButtonProvider {
|
||||
private shells$ = new AsyncSubject<IShell[]>()
|
||||
private logger: Logger
|
||||
|
||||
constructor (
|
||||
@@ -17,16 +14,11 @@ export class ButtonProvider extends ToolbarButtonProvider {
|
||||
private config: ConfigService,
|
||||
log: LogService,
|
||||
hostApp: HostAppService,
|
||||
@Inject(ShellProvider) shellProviders: ShellProvider[],
|
||||
electron: ElectronService,
|
||||
hotkeys: HotkeysService,
|
||||
) {
|
||||
super()
|
||||
this.logger = log.create('newTerminalButton')
|
||||
Promise.all(shellProviders.map(x => x.provide())).then(shellLists => {
|
||||
this.shells$.next(shellLists.reduce((a, b) => a.concat(b)))
|
||||
this.shells$.complete()
|
||||
})
|
||||
hotkeys.matchedHotkey.subscribe(async (hotkey) => {
|
||||
if (hotkey === 'new-tab') {
|
||||
this.openNewTab()
|
||||
@@ -55,8 +47,8 @@ export class ButtonProvider extends ToolbarButtonProvider {
|
||||
}
|
||||
|
||||
async openNewTab (cwd?: string): Promise<void> {
|
||||
let shells = await this.shells$.first().toPromise()
|
||||
let shell = shells.find(x => x.id === this.config.store.terminal.shell) || shells[0]
|
||||
let shells = await this.terminal.shells$.first().toPromise()
|
||||
let shell = shells.find(x => x.id === this.config.store.terminal.shell)
|
||||
this.terminal.openTab(shell, cwd)
|
||||
}
|
||||
|
||||
|
@@ -1,16 +1,24 @@
|
||||
import { BehaviorSubject, Subject, Subscription } from 'rxjs'
|
||||
import 'rxjs/add/operator/bufferTime'
|
||||
import { Component, NgZone, Inject, Optional, ViewChild, HostBinding, Input } from '@angular/core'
|
||||
import { AppService, ConfigService, BaseTabComponent, ThemesService, HostAppService, HotkeysService, Platform } from 'terminus-core'
|
||||
import { AppService, ConfigService, BaseTabComponent, ElectronService, ThemesService, HostAppService, HotkeysService, Platform } from 'terminus-core'
|
||||
|
||||
import { IShell } from '../api'
|
||||
import { Session, SessionsService } from '../services/sessions.service'
|
||||
import { TerminalService } from '../services/terminal.service'
|
||||
|
||||
import { TerminalDecorator, ResizeEvent, SessionOptions } from '../api'
|
||||
import { hterm, preferenceManager } from '../hterm'
|
||||
|
||||
@Component({
|
||||
selector: 'terminalTab',
|
||||
template: '<div #content class="content" [style.opacity]="htermVisible ? 1 : 0"></div>',
|
||||
template: `
|
||||
<div
|
||||
#content
|
||||
class="content"
|
||||
[style.opacity]="htermVisible ? 1 : 0"
|
||||
></div>
|
||||
`,
|
||||
styles: [require('./terminalTab.component.scss')],
|
||||
})
|
||||
export class TerminalTabComponent extends BaseTabComponent {
|
||||
@@ -31,8 +39,10 @@ export class TerminalTabComponent extends BaseTabComponent {
|
||||
alternateScreenActive$ = new BehaviorSubject(false)
|
||||
mouseEvent$ = new Subject<Event>()
|
||||
htermVisible = false
|
||||
shell: IShell
|
||||
private bellPlayer: HTMLAudioElement
|
||||
private io: any
|
||||
private contextMenu: any
|
||||
|
||||
constructor (
|
||||
private zone: NgZone,
|
||||
@@ -41,6 +51,8 @@ export class TerminalTabComponent extends BaseTabComponent {
|
||||
private hostApp: HostAppService,
|
||||
private hotkeys: HotkeysService,
|
||||
private sessions: SessionsService,
|
||||
private electron: ElectronService,
|
||||
private terminalService: TerminalService,
|
||||
public config: ConfigService,
|
||||
@Optional() @Inject(TerminalDecorator) private decorators: TerminalDecorator[],
|
||||
) {
|
||||
@@ -142,6 +154,35 @@ export class TerminalTabComponent extends BaseTabComponent {
|
||||
}
|
||||
// TODO audible
|
||||
})
|
||||
|
||||
this.contextMenu = this.electron.remote.Menu.buildFromTemplate([
|
||||
{
|
||||
label: 'New terminal',
|
||||
click: () => {
|
||||
this.zone.run(() => {
|
||||
this.terminalService.openTab(this.shell)
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Copy',
|
||||
click: () => {
|
||||
this.zone.run(() => {
|
||||
setTimeout(() => {
|
||||
this.hterm.copySelectionToClipboard()
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Paste',
|
||||
click: () => {
|
||||
this.zone.run(() => {
|
||||
this.sendInput(this.electron.clipboard.readText())
|
||||
})
|
||||
}
|
||||
},
|
||||
])
|
||||
}
|
||||
|
||||
attachHTermHandlers (hterm: any) {
|
||||
@@ -180,6 +221,17 @@ export class TerminalTabComponent extends BaseTabComponent {
|
||||
const _onMouse = hterm.onMouse_.bind(hterm)
|
||||
hterm.onMouse_ = (event) => {
|
||||
this.mouseEvent$.next(event)
|
||||
if (event.type === 'mousedown') {
|
||||
if (event.which === 3) {
|
||||
this.contextMenu.popup({
|
||||
x: event.pageX,
|
||||
y: event.pageY,
|
||||
async: true,
|
||||
})
|
||||
event.preventDefault()
|
||||
return
|
||||
}
|
||||
}
|
||||
if (event.type === 'mousewheel') {
|
||||
if (event.ctrlKey || event.metaKey) {
|
||||
if (event.wheelDeltaY > 0) {
|
||||
|
@@ -1,25 +1,37 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { AppService, Logger, LogService } from 'terminus-core'
|
||||
import { IShell } from '../api'
|
||||
import { AsyncSubject } from 'rxjs'
|
||||
import { Injectable, Inject } from '@angular/core'
|
||||
import { AppService, Logger, LogService, ConfigService } from 'terminus-core'
|
||||
import { IShell, ShellProvider } from '../api'
|
||||
import { SessionsService } from './sessions.service'
|
||||
import { TerminalTabComponent } from '../components/terminalTab.component'
|
||||
|
||||
@Injectable()
|
||||
export class TerminalService {
|
||||
shells$ = new AsyncSubject<IShell[]>()
|
||||
private logger: Logger
|
||||
|
||||
constructor (
|
||||
private app: AppService,
|
||||
private sessions: SessionsService,
|
||||
private config: ConfigService,
|
||||
@Inject(ShellProvider) shellProviders: ShellProvider[],
|
||||
log: LogService,
|
||||
) {
|
||||
this.logger = log.create('terminal')
|
||||
Promise.all(shellProviders.map(x => x.provide())).then(shellLists => {
|
||||
this.shells$.next(shellLists.reduce((a, b) => a.concat(b)))
|
||||
this.shells$.complete()
|
||||
})
|
||||
}
|
||||
|
||||
async openTab (shell: IShell, cwd?: string): Promise<TerminalTabComponent> {
|
||||
async openTab (shell?: IShell, cwd?: string): Promise<TerminalTabComponent> {
|
||||
if (!cwd && this.app.activeTab instanceof TerminalTabComponent) {
|
||||
cwd = await this.app.activeTab.session.getWorkingDirectory()
|
||||
}
|
||||
if (!shell) {
|
||||
let shells = await this.shells$.toPromise()
|
||||
shell = shells.find(x => x.id === this.config.store.terminal.shell) || shells[0]
|
||||
}
|
||||
let env: any = Object.assign({}, process.env, shell.env || {})
|
||||
|
||||
this.logger.log(`Starting shell ${shell.name}`, shell)
|
||||
@@ -34,7 +46,7 @@ export class TerminalService {
|
||||
|
||||
return this.app.openNewTab(
|
||||
TerminalTabComponent,
|
||||
{ sessionOptions }
|
||||
{ sessionOptions, shell }
|
||||
) as TerminalTabComponent
|
||||
}
|
||||
}
|
||||
|
@@ -2,6 +2,10 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/async-lock@0.0.19":
|
||||
version "0.0.19"
|
||||
resolved "https://registry.yarnpkg.com/@types/async-lock/-/async-lock-0.0.19.tgz#4bdb7f8d9ac2826588b98068903aedbd9d95dce8"
|
||||
|
||||
"@types/deep-equal@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/deep-equal/-/deep-equal-1.0.0.tgz#9ebeaa73d1fc4791f038a5f1440e0449ea968495"
|
||||
@@ -28,6 +32,10 @@ any-promise@^1.0.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
|
||||
|
||||
async-lock@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/async-lock/-/async-lock-1.0.0.tgz#b81abbdbd2a6e516773a044b7e6917ae2001f370"
|
||||
|
||||
big.js@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.1.3.tgz#4cada2193652eb3ca9ec8e55c9015669c9806978"
|
||||
@@ -61,7 +69,7 @@ font-manager@0.2.2:
|
||||
nan "~2.2.0"
|
||||
|
||||
hterm-umdjs@1.1.3:
|
||||
version "1.1.3+1.58.sha.15ed490"
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/hterm-umdjs/-/hterm-umdjs-1.1.3.tgz#8b57bcaded5ba9541d6c8e32a82b34abb93e885e"
|
||||
|
||||
json5@^0.5.0:
|
||||
|
Reference in New Issue
Block a user