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(
path.dirname(require('electron').remote.app.getPath('exe')),
(process.platform == 'darwin') ? '../Resources' : 'resources',
(process.platform === 'darwin') ? '../Resources' : 'resources',
'builtin-plugins/node_modules',
))
nodeModule.globalPaths.unshift(path.join(

View file

@ -10,7 +10,7 @@
"awesome-typescript-loader": "3.1.2",
"cross-env": "^4.0.0",
"css-loader": "0.26.1",
"electron": "1.6.2",
"electron": "1.6.7",
"electron-builder": "^17.1.1",
"electron-builder-squirrel-windows": "^17.0.1",
"electron-osx-sign": "electron-userland/electron-osx-sign#f092181a1bffa2b3248a23ee28447a47e14a8f04",
@ -66,7 +66,7 @@
"scripts": {
"build": "webpack --progress --color",
"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",
"postinstall": "install-app-deps"
}

View file

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

View file

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

View file

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

View file

@ -36,16 +36,17 @@ export class ButtonProvider extends ToolbarButtonProvider {
'/k',
path.join(
path.dirname(this.electron.app.getPath('exe')),
(process.platform == 'darwin') ? '../Resources' : 'resources',
(process.platform === 'darwin') ? '../Resources' : 'resources',
'clink',
`clink_${process.arch}.exe`,
),
'inject',
]
}
let sessionOptions = await this.sessions.prepareNewSession({ command, args, cwd })
this.app.openNewTab(
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 { 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'
@Component({
@ -13,7 +14,8 @@ import { hterm, preferenceManager } from '../hterm'
styles: [require('./terminalTab.component.scss')],
})
export class TerminalTabComponent extends BaseTabComponent {
@Input() session: Session
session: Session
@Input() sessionOptions: SessionOptions
@ViewChild('content') content
@HostBinding('style.background-color') backgroundColor: string
hterm: any
@ -21,6 +23,7 @@ export class TerminalTabComponent extends BaseTabComponent {
sessionCloseSubscription: Subscription
bell$ = new Subject()
size$ = new ReplaySubject<ResizeEvent>(1)
resize$ = new Subject<ResizeEvent>()
input$ = new Subject<string>()
output$ = new Subject<string>()
contentUpdated$ = new Subject<void>()
@ -34,6 +37,7 @@ export class TerminalTabComponent extends BaseTabComponent {
private app: AppService,
private themes: ThemesService,
private hostApp: HostAppService,
private sessions: SessionsService,
public config: ConfigService,
@Optional() @Inject(TerminalDecorator) private decorators: TerminalDecorator[],
) {
@ -43,12 +47,28 @@ export class TerminalTabComponent extends BaseTabComponent {
this.configSubscription = config.change.subscribe(() => {
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 {
return {
type: 'app:terminal',
recoveryId: this.session.recoveryId,
recoveryId: this.sessionOptions.recoveryId,
}
}
@ -70,17 +90,6 @@ export class TerminalTabComponent extends BaseTabComponent {
this.hterm.installKeyboard()
this.io = this.hterm.io.push()
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.configure()
@ -116,6 +125,9 @@ export class TerminalTabComponent extends BaseTabComponent {
this.alternateScreenActive$.next(state)
}
hterm.primaryScreen_.syncSelectionCaret = () => null
hterm.alternateScreen_.syncSelectionCaret = () => null
const _onPaste = hterm.scrollPort_.onPaste_.bind(hterm.scrollPort_)
hterm.scrollPort_.onPaste_ = (event) => {
hterm.scrollPort_.pasteTarget_.value = event.clipboardData.getData('text/plain').trim()
@ -172,8 +184,11 @@ export class TerminalTabComponent extends BaseTabComponent {
io.onTerminalResize = (columns, rows) => {
// console.log(`Resizing to ${columns}x${rows}`)
this.zone.run(() => {
this.session.resize(columns, 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.sessionCloseSubscription.unsubscribe()
this.size$.complete()
this.resize$.complete()
this.input$.complete()
this.output$.complete()
this.contentUpdated$.complete()

View file

@ -1,5 +1,5 @@
const dataurl = require('dataurl')
export const hterm = require('hterm-commonjs')
export const hterm = require('hterm-umdjs')
hterm.hterm.defaultStorage = new hterm.lib.Storage.Memory()
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> {
if (recoveryToken.type === 'app:terminal') {
let session = await this.sessions.recover(recoveryToken.recoveryId)
if (!session) {
let sessionOptions = await this.sessions.recover(recoveryToken.recoveryId)
if (!sessionOptions) {
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 || [], {
name: 'xterm-256color',
cols: 80,
rows: 30,
cols: options.width || 80,
rows: options.height || 30,
cwd: options.cwd || process.env.HOME,
env: env,
})
@ -140,13 +140,12 @@ export class SessionsService {
this.logger = log.create('sessions')
}
async createNewSession (options: SessionOptions): Promise<Session> {
async prepareNewSession (options: SessionOptions): Promise<SessionOptions> {
if (this.persistence) {
let recoveryId = await this.persistence.startSession(options)
options = await this.persistence.attachSession(recoveryId)
}
let session = this.addSession(options)
return session
return options
}
addSession (options: SessionOptions): Session {
@ -163,14 +162,10 @@ export class SessionsService {
return session
}
async recover (recoveryId: string): Promise<Session> {
async recover (recoveryId: string): Promise<SessionOptions> {
if (!this.persistence) {
return null
}
const options = await this.persistence.attachSession(recoveryId)
if (!options) {
return null
}
return this.addSession(options)
return await this.persistence.attachSession(recoveryId)
}
}