This commit is contained in:
Eugene Pankov
2017-07-24 14:48:16 +02:00
parent 932ed9b8f2
commit 9312db1fc6
17 changed files with 106 additions and 28 deletions

View File

@@ -41,6 +41,7 @@
"hterm-umdjs": "1.1.3",
"mz": "^2.6.0",
"node-pty": "0.6.8",
"ps-node": "^0.1.6",
"runes": "^0.4.2",
"winreg": "^1.2.3"
},

View File

@@ -1,6 +1,7 @@
import { Observable } from 'rxjs'
import { TerminalTabComponent } from './components/terminalTab.component'
export { TerminalTabComponent }
export { IChildProcess } from './services/sessions.service'
export abstract class TerminalDecorator {
// tslint:disable-next-line no-empty

View File

@@ -1,4 +1,3 @@
const dataurl = require('dataurl')
import { BehaviorSubject, Subject, Subscription } from 'rxjs'
import 'rxjs/add/operator/bufferTime'
import { Component, NgZone, Inject, Optional, ViewChild, HostBinding, Input } from '@angular/core'
@@ -297,12 +296,7 @@ export class TerminalTabComponent extends BaseTabComponent {
`
}
css += config.appearance.css
preferenceManager.set('user-css', dataurl.convert({
data: css,
mimetype: 'text/css',
charset: 'utf8',
}))
this.hterm.setCSS(css)
this.hterm.setBracketedPaste(config.terminal.bracketedPaste)
}
@@ -345,6 +339,14 @@ export class TerminalTabComponent extends BaseTabComponent {
}
}
async canClose (): Promise<boolean> {
let children = await this.session.getChildProcesses()
if (children.length === 0) {
return true
}
return confirm(`"${children[0].command}" is still running. Close?`)
}
private setFontSize () {
preferenceManager.set('font-size', this.config.store.terminal.fontSize * Math.pow(1.1, this.zoom))
}

View File

@@ -22,6 +22,16 @@ preferenceManager.set('color-palette-overrides', {
hterm.hterm.Terminal.prototype.showOverlay = () => null
hterm.hterm.Terminal.prototype.setCSS = function (css) {
const doc = this.scrollPort_.document_
if (!doc.querySelector('#user-css')) {
const node = doc.createElement('style')
node.id = 'user-css'
doc.head.appendChild(node)
}
doc.querySelector('#user-css').innerText = css
}
const oldCharWidthDisregardAmbiguous = hterm.lib.wc.charWidthDisregardAmbiguous
hterm.lib.wc.charWidthDisregardAmbiguous = codepoint => {
if ((codepoint >= 0x1f300 && codepoint <= 0x1f64f) ||

View File

@@ -2,7 +2,6 @@ import { Injectable } from '@angular/core'
import { TerminalDecorator } from './api'
import { TerminalTabComponent } from './components/terminalTab.component'
@Injectable()
export class PathDropDecorator extends TerminalDecorator {
attach (terminal: TerminalTabComponent): void {

View File

@@ -64,12 +64,13 @@ export class ScreenPersistenceProvider extends SessionPersistenceProvider {
recoveryId,
recoveredTruePID$: truePID$.asObservable(),
command: 'screen',
args: ['-r', recoveryId],
args: ['-d', '-r', recoveryId],
}
}
async extractShellPID (screenPID: number): Promise<number> {
let child = (await listProcesses()).find(x => x.ppid === screenPID)
let processes = await listProcesses()
let child = processes.find(x => x.ppid === screenPID)
if (!child) {
throw new Error(`Could not find any children of the screen process (PID ${screenPID})!`)
@@ -77,7 +78,7 @@ export class ScreenPersistenceProvider extends SessionPersistenceProvider {
if (child.command === 'login') {
await delay(1000)
child = (await listProcesses()).find(x => x.ppid === child.pid)
child = processes.find(x => x.ppid === child.pid)
}
return child.pid

View File

@@ -1,12 +1,20 @@
import * as nodePTY from 'node-pty'
const psNode = require('ps-node')
// import * as nodePTY from 'node-pty'
let nodePTY
import * as fs from 'mz/fs'
import { Subject } from 'rxjs'
import { Injectable } from '@angular/core'
import { Logger, LogService } from 'terminus-core'
import { Logger, LogService, ElectronService } from 'terminus-core'
import { exec } from 'mz/child_process'
import { SessionOptions, SessionPersistenceProvider } from '../api'
export interface IChildProcess {
pid: number
ppid: number
command: string
}
export class Session {
open: boolean
name: string
@@ -101,6 +109,20 @@ export class Session {
this.pty.kill(signal)
}
async getChildProcesses (): Promise<IChildProcess[]> {
if (!this.truePID) {
return []
}
return new Promise<IChildProcess[]>((resolve, reject) => {
psNode.lookup({ ppid: this.truePID }, (err, processes) => {
if (err) {
return reject(err)
}
resolve(processes as IChildProcess[])
})
})
}
async gracefullyKillProcess (): Promise<void> {
if (process.platform === 'win32') {
this.kill()
@@ -157,8 +179,10 @@ export class SessionsService {
constructor (
private persistence: SessionPersistenceProvider,
electron: ElectronService,
log: LogService,
) {
nodePTY = electron.remoteRequirePluginModule('terminus-terminal', 'node-pty', global as any)
this.logger = log.create('sessions')
}

View File

@@ -3,6 +3,10 @@
"exclude": ["node_modules", "dist"],
"compilerOptions": {
"baseUrl": "src",
"declarationDir": "dist"
"declarationDir": "dist",
"paths": {
"terminus-*": ["terminus-*"],
"*": ["app/node_modules/*"]
}
}
}

View File

@@ -44,6 +44,7 @@ module.exports = {
]
},
externals: [
'electron',
'fs',
'font-manager',
'path',

View File

@@ -32,6 +32,10 @@ big.js@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.1.3.tgz#4cada2193652eb3ca9ec8e55c9015669c9806978"
connected-domain@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/connected-domain/-/connected-domain-1.0.0.tgz#bfe77238c74be453a79f0cb6058deeb4f2358e93"
dataurl@0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/dataurl/-/dataurl-0.1.0.tgz#1f4734feddec05ffe445747978d86759c4b33199"
@@ -98,10 +102,22 @@ object-assign@^4.0.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
ps-node@^0.1.6:
version "0.1.6"
resolved "https://registry.yarnpkg.com/ps-node/-/ps-node-0.1.6.tgz#9af67a99d7b1d0132e51a503099d38a8d2ace2c3"
dependencies:
table-parser "^0.1.3"
runes@^0.4.2:
version "0.4.2"
resolved "https://registry.yarnpkg.com/runes/-/runes-0.4.2.tgz#1ddc1ea41de769cb32fc068a64fbbc45cd21052e"
table-parser@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/table-parser/-/table-parser-0.1.3.tgz#0441cfce16a59481684c27d1b5a67ff15a43c7b0"
dependencies:
connected-domain "^1.0.0"
thenify-all@^1.0.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"