1
1
mirror of https://github.com/Eugeny/tabby.git synced 2024-12-25 03:22:58 +03:00
This commit is contained in:
Eugene Pankov 2017-05-14 13:45:14 +02:00
parent 791822be12
commit c0f7cd9a7a
10 changed files with 56 additions and 40 deletions

View File

@ -20,7 +20,7 @@ if (process.env.DEV) {
nodeModule.globalPaths.unshift(path.join( nodeModule.globalPaths.unshift(path.join(
path.dirname(require('electron').remote.app.getPath('exe')), path.dirname(require('electron').remote.app.getPath('exe')),
(process.platform == 'darwin') ? '../Resources' : 'resources', (process.platform === 'darwin') ? '../Resources' : 'resources',
'builtin-plugins/node_modules', 'builtin-plugins/node_modules',
)) ))
nodeModule.globalPaths.unshift(path.join( nodeModule.globalPaths.unshift(path.join(

View File

@ -10,7 +10,7 @@
"awesome-typescript-loader": "3.1.2", "awesome-typescript-loader": "3.1.2",
"cross-env": "^4.0.0", "cross-env": "^4.0.0",
"css-loader": "0.26.1", "css-loader": "0.26.1",
"electron": "1.6.2", "electron": "1.6.7",
"electron-builder": "^17.1.1", "electron-builder": "^17.1.1",
"electron-builder-squirrel-windows": "^17.0.1", "electron-builder-squirrel-windows": "^17.0.1",
"electron-osx-sign": "electron-userland/electron-osx-sign#f092181a1bffa2b3248a23ee28447a47e14a8f04", "electron-osx-sign": "electron-userland/electron-osx-sign#f092181a1bffa2b3248a23ee28447a47e14a8f04",
@ -66,7 +66,7 @@
"scripts": { "scripts": {
"build": "webpack --progress --color", "build": "webpack --progress --color",
"watch": "webpack --progress --color --watch", "watch": "webpack --progress --color --watch",
"start": "cross-env DEV=1 electron app --debug", "start": "cross-env DEV=1 electron --js-flags='--ignition' app --debug",
"lint": "tslint -c tslint.json -t stylish terminus-*/src/**/*.ts terminus-*/src/*.ts app/src/*.ts", "lint": "tslint -c tslint.json -t stylish terminus-*/src/**/*.ts terminus-*/src/*.ts app/src/*.ts",
"postinstall": "install-app-deps" "postinstall": "install-app-deps"
} }

View File

@ -1,3 +1,4 @@
import { Observable } from 'rxjs'
import { Inject, Injectable } from '@angular/core' import { Inject, Injectable } from '@angular/core'
import { TerminalDecorator, TerminalTabComponent } from 'terminus-terminal' import { TerminalDecorator, TerminalTabComponent } from 'terminus-terminal'
@ -10,10 +11,11 @@ export class LinkHighlighterDecorator extends TerminalDecorator {
} }
attach (terminal: TerminalTabComponent): void { attach (terminal: TerminalTabComponent): void {
return
terminal.contentUpdated$ terminal.contentUpdated$
.debounceTime(1000) .throttle(() => Observable.from([500]))
.subscribe(() => { .subscribe(() => {
this.insertLinks(terminal.hterm.screen_) //this.insertLinks(terminal.hterm.screen_)
}) })
} }

View File

@ -42,7 +42,7 @@
"dependencies": { "dependencies": {
"font-manager": "0.2.2", "font-manager": "0.2.2",
"fs-promise": "2.0.2", "fs-promise": "2.0.2",
"hterm-commonjs": "1.0.0", "hterm-umdjs": "1.1.3",
"mz": "^2.6.0", "mz": "^2.6.0",
"node-pty": "0.6.2", "node-pty": "0.6.2",
"winreg": "^1.2.3" "winreg": "^1.2.3"

View File

@ -20,6 +20,8 @@ export interface SessionOptions {
args?: string[] args?: string[]
cwd?: string cwd?: string
env?: any env?: any
width?: number
height?: number
recoveryId?: string recoveryId?: string
recoveredTruePID$?: Observable<number> recoveredTruePID$?: Observable<number>
} }

View File

@ -36,16 +36,17 @@ export class ButtonProvider extends ToolbarButtonProvider {
'/k', '/k',
path.join( path.join(
path.dirname(this.electron.app.getPath('exe')), path.dirname(this.electron.app.getPath('exe')),
(process.platform == 'darwin') ? '../Resources' : 'resources', (process.platform === 'darwin') ? '../Resources' : 'resources',
'clink', 'clink',
`clink_${process.arch}.exe`, `clink_${process.arch}.exe`,
), ),
'inject', 'inject',
] ]
} }
let sessionOptions = await this.sessions.prepareNewSession({ command, args, cwd })
this.app.openNewTab( this.app.openNewTab(
TerminalTabComponent, TerminalTabComponent,
{ session: await this.sessions.createNewSession({ command, args, cwd }) } { sessionOptions }
) )
} }

View File

@ -1,10 +1,11 @@
import { BehaviorSubject, ReplaySubject, Subject, Subscription } from 'rxjs' import { Observable, BehaviorSubject, ReplaySubject, Subject, Subscription } from 'rxjs'
import 'rxjs/add/operator/bufferTime'
import { Component, NgZone, Inject, Optional, ViewChild, HostBinding, Input } from '@angular/core' import { Component, NgZone, Inject, Optional, ViewChild, HostBinding, Input } from '@angular/core'
import { AppService, ConfigService, BaseTabComponent, ThemesService, HostAppService, Platform } from 'terminus-core' import { AppService, ConfigService, BaseTabComponent, ThemesService, HostAppService, Platform } from 'terminus-core'
import { Session } from '../services/sessions.service' import { Session, SessionsService } from '../services/sessions.service'
import { TerminalDecorator, ResizeEvent } from '../api' import { TerminalDecorator, ResizeEvent, SessionOptions } from '../api'
import { hterm, preferenceManager } from '../hterm' import { hterm, preferenceManager } from '../hterm'
@Component({ @Component({
@ -13,7 +14,8 @@ import { hterm, preferenceManager } from '../hterm'
styles: [require('./terminalTab.component.scss')], styles: [require('./terminalTab.component.scss')],
}) })
export class TerminalTabComponent extends BaseTabComponent { export class TerminalTabComponent extends BaseTabComponent {
@Input() session: Session session: Session
@Input() sessionOptions: SessionOptions
@ViewChild('content') content @ViewChild('content') content
@HostBinding('style.background-color') backgroundColor: string @HostBinding('style.background-color') backgroundColor: string
hterm: any hterm: any
@ -21,6 +23,7 @@ export class TerminalTabComponent extends BaseTabComponent {
sessionCloseSubscription: Subscription sessionCloseSubscription: Subscription
bell$ = new Subject() bell$ = new Subject()
size$ = new ReplaySubject<ResizeEvent>(1) size$ = new ReplaySubject<ResizeEvent>(1)
resize$ = new Subject<ResizeEvent>()
input$ = new Subject<string>() input$ = new Subject<string>()
output$ = new Subject<string>() output$ = new Subject<string>()
contentUpdated$ = new Subject<void>() contentUpdated$ = new Subject<void>()
@ -34,6 +37,7 @@ export class TerminalTabComponent extends BaseTabComponent {
private app: AppService, private app: AppService,
private themes: ThemesService, private themes: ThemesService,
private hostApp: HostAppService, private hostApp: HostAppService,
private sessions: SessionsService,
public config: ConfigService, public config: ConfigService,
@Optional() @Inject(TerminalDecorator) private decorators: TerminalDecorator[], @Optional() @Inject(TerminalDecorator) private decorators: TerminalDecorator[],
) { ) {
@ -43,12 +47,28 @@ export class TerminalTabComponent extends BaseTabComponent {
this.configSubscription = config.change.subscribe(() => { this.configSubscription = config.change.subscribe(() => {
this.configure() this.configure()
}) })
this.resize$.first().subscribe(async (resizeEvent) => {
this.session = this.sessions.addSession(
Object.assign({}, this.sessionOptions, resizeEvent)
)
this.session.output$.bufferTime(10).subscribe((datas) => {
let data = datas.join('')
this.zone.run(() => {
this.output$.next(data)
})
this.write(data)
})
this.sessionCloseSubscription = this.session.closed$.subscribe(() => {
this.app.closeTab(this)
})
this.session.releaseInitialDataBuffer()
})
} }
getRecoveryToken (): any { getRecoveryToken (): any {
return { return {
type: 'app:terminal', type: 'app:terminal',
recoveryId: this.session.recoveryId, recoveryId: this.sessionOptions.recoveryId,
} }
} }
@ -70,17 +90,6 @@ export class TerminalTabComponent extends BaseTabComponent {
this.hterm.installKeyboard() this.hterm.installKeyboard()
this.io = this.hterm.io.push() this.io = this.hterm.io.push()
this.attachIOHandlers(this.io) this.attachIOHandlers(this.io)
this.session.output$.subscribe((data) => {
this.zone.run(() => {
this.output$.next(data)
})
this.write(data)
})
this.sessionCloseSubscription = this.session.closed$.subscribe(() => {
this.app.closeTab(this)
})
this.session.releaseInitialDataBuffer()
} }
this.hterm.decorate(this.content.nativeElement) this.hterm.decorate(this.content.nativeElement)
this.configure() this.configure()
@ -116,6 +125,9 @@ export class TerminalTabComponent extends BaseTabComponent {
this.alternateScreenActive$.next(state) this.alternateScreenActive$.next(state)
} }
hterm.primaryScreen_.syncSelectionCaret = () => null
hterm.alternateScreen_.syncSelectionCaret = () => null
const _onPaste = hterm.scrollPort_.onPaste_.bind(hterm.scrollPort_) const _onPaste = hterm.scrollPort_.onPaste_.bind(hterm.scrollPort_)
hterm.scrollPort_.onPaste_ = (event) => { hterm.scrollPort_.onPaste_ = (event) => {
hterm.scrollPort_.pasteTarget_.value = event.clipboardData.getData('text/plain').trim() hterm.scrollPort_.pasteTarget_.value = event.clipboardData.getData('text/plain').trim()
@ -172,8 +184,11 @@ export class TerminalTabComponent extends BaseTabComponent {
io.onTerminalResize = (columns, rows) => { io.onTerminalResize = (columns, rows) => {
// console.log(`Resizing to ${columns}x${rows}`) // console.log(`Resizing to ${columns}x${rows}`)
this.zone.run(() => { this.zone.run(() => {
this.session.resize(columns, rows)
this.size$.next({ width: columns, height: rows }) this.size$.next({ width: columns, height: rows })
this.resize$.next({ width: columns, height: rows })
if (this.session) {
this.session.resize(columns, rows)
}
}) })
} }
} }
@ -230,6 +245,7 @@ export class TerminalTabComponent extends BaseTabComponent {
this.configSubscription.unsubscribe() this.configSubscription.unsubscribe()
this.sessionCloseSubscription.unsubscribe() this.sessionCloseSubscription.unsubscribe()
this.size$.complete() this.size$.complete()
this.resize$.complete()
this.input$.complete() this.input$.complete()
this.output$.complete() this.output$.complete()
this.contentUpdated$.complete() this.contentUpdated$.complete()

View File

@ -1,5 +1,5 @@
const dataurl = require('dataurl') const dataurl = require('dataurl')
export const hterm = require('hterm-commonjs') export const hterm = require('hterm-umdjs')
hterm.hterm.defaultStorage = new hterm.lib.Storage.Memory() hterm.hterm.defaultStorage = new hterm.lib.Storage.Memory()
export const preferenceManager = new hterm.hterm.PreferenceManager('default') export const preferenceManager = new hterm.hterm.PreferenceManager('default')

View File

@ -15,11 +15,11 @@ export class RecoveryProvider extends TabRecoveryProvider {
async recover (recoveryToken: any): Promise<void> { async recover (recoveryToken: any): Promise<void> {
if (recoveryToken.type === 'app:terminal') { if (recoveryToken.type === 'app:terminal') {
let session = await this.sessions.recover(recoveryToken.recoveryId) let sessionOptions = await this.sessions.recover(recoveryToken.recoveryId)
if (!session) { if (!sessionOptions) {
return return
} }
this.app.openNewTab(TerminalTabComponent, { session }) this.app.openNewTab(TerminalTabComponent, { sessionOptions })
} }
} }
} }

View File

@ -34,8 +34,8 @@ export class Session {
} }
this.pty = nodePTY.spawn(options.command, options.args || [], { this.pty = nodePTY.spawn(options.command, options.args || [], {
name: 'xterm-256color', name: 'xterm-256color',
cols: 80, cols: options.width || 80,
rows: 30, rows: options.height || 30,
cwd: options.cwd || process.env.HOME, cwd: options.cwd || process.env.HOME,
env: env, env: env,
}) })
@ -140,13 +140,12 @@ export class SessionsService {
this.logger = log.create('sessions') this.logger = log.create('sessions')
} }
async createNewSession (options: SessionOptions): Promise<Session> { async prepareNewSession (options: SessionOptions): Promise<SessionOptions> {
if (this.persistence) { if (this.persistence) {
let recoveryId = await this.persistence.startSession(options) let recoveryId = await this.persistence.startSession(options)
options = await this.persistence.attachSession(recoveryId) options = await this.persistence.attachSession(recoveryId)
} }
let session = this.addSession(options) return options
return session
} }
addSession (options: SessionOptions): Session { addSession (options: SessionOptions): Session {
@ -163,14 +162,10 @@ export class SessionsService {
return session return session
} }
async recover (recoveryId: string): Promise<Session> { async recover (recoveryId: string): Promise<SessionOptions> {
if (!this.persistence) { if (!this.persistence) {
return null return null
} }
const options = await this.persistence.attachSession(recoveryId) return await this.persistence.attachSession(recoveryId)
if (!options) {
return null
}
return this.addSession(options)
} }
} }