This commit is contained in:
Eugene Pankov 2017-04-17 17:27:04 +02:00
parent 919aa7c65f
commit 4d6c63a0e3
11 changed files with 74 additions and 52 deletions

View File

@ -2,7 +2,7 @@
"compilerOptions": { "compilerOptions": {
"baseUrl": "src", "baseUrl": "src",
"module": "commonjs", "module": "commonjs",
"target": "es2015", "target": "es2016",
"declaration": false, "declaration": false,
"noImplicitAny": false, "noImplicitAny": false,
"removeComments": false, "removeComments": false,
@ -22,8 +22,5 @@
"es7" "es7"
] ]
}, },
"compileOnSave": false, "exclude": ["node_modules", "dist"]
"exclude": [
"node_modules"
]
} }

View File

@ -2,7 +2,7 @@
"compilerOptions": { "compilerOptions": {
"baseUrl": "src", "baseUrl": "src",
"module": "commonjs", "module": "commonjs",
"target": "es2015", "target": "es2016",
"declaration": false, "declaration": false,
"noImplicitAny": false, "noImplicitAny": false,
"removeComments": false, "removeComments": false,
@ -22,6 +22,5 @@
"es7" "es7"
] ]
}, },
"compileOnSave": false, "exclude": ["node_modules", "dist"]
"include": ["src"]
} }

View File

@ -2,7 +2,7 @@
"compilerOptions": { "compilerOptions": {
"baseUrl": "src", "baseUrl": "src",
"module": "commonjs", "module": "commonjs",
"target": "es2015", "target": "es2016",
"declaration": false, "declaration": false,
"noImplicitAny": false, "noImplicitAny": false,
"removeComments": false, "removeComments": false,
@ -22,5 +22,5 @@
"es7" "es7"
] ]
}, },
"include": ["src"] "exclude": ["node_modules", "dist"]
} }

View File

@ -2,7 +2,7 @@
"compilerOptions": { "compilerOptions": {
"baseUrl": "./src", "baseUrl": "./src",
"module": "commonjs", "module": "commonjs",
"target": "es2015", "target": "es2016",
"declaration": false, "declaration": false,
"noImplicitAny": false, "noImplicitAny": false,
"removeComments": false, "removeComments": false,
@ -22,5 +22,5 @@
"es7" "es7"
] ]
}, },
"include": ["src"] "exclude": ["node_modules", "dist"]
} }

View File

@ -11,9 +11,10 @@
"author": "Eugene Pankov", "author": "Eugene Pankov",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@types/deep-equal": "1.0.0", "@types/deep-equal": "^1.0.0",
"@types/node": "7.0.12", "@types/node": "7.0.12",
"@types/webpack-env": "1.13.0", "@types/webpack-env": "1.13.0",
"@types/winreg": "^1.2.30",
"awesome-typescript-loader": "3.1.2", "awesome-typescript-loader": "3.1.2",
"css-loader": "^0.28.0", "css-loader": "^0.28.0",
"dataurl": "0.1.0", "dataurl": "0.1.0",
@ -38,9 +39,10 @@
}, },
"dependencies": { "dependencies": {
"child-process-promise": "2.2.1", "child-process-promise": "2.2.1",
"fs-promise": "2.0.2",
"font-manager": "0.2.2", "font-manager": "0.2.2",
"fs-promise": "2.0.2",
"hterm-commonjs": "1.0.0", "hterm-commonjs": "1.0.0",
"node-pty": "0.6.2" "node-pty": "0.6.2",
"winreg": "^1.2.3"
} }
} }

View File

@ -1,14 +1,18 @@
import 'rxjs'
import { Observable } from 'rxjs' import { Observable } from 'rxjs'
import * as fs from 'fs-promise' import * as fs from 'fs-promise'
const fontManager = require('font-manager') import * as path from 'path'
const equal = require('deep-equal') const equal = require('deep-equal')
const fontManager = require('font-manager')
const { exec } = require('child-process-promise') const { exec } = require('child-process-promise')
import { Component, Inject } from '@angular/core' import { Component, Inject } from '@angular/core'
import { ConfigService, HostAppService, Platform } from 'terminus-core' import { ConfigService, HostAppService, Platform } from 'terminus-core'
import { TerminalColorSchemeProvider, ITerminalColorScheme } from '../api' import { TerminalColorSchemeProvider, ITerminalColorScheme } from '../api'
let Registry = null
try {
Registry = require('winreg')
} catch (_) { }
interface IShell { interface IShell {
name: string name: string
@ -58,6 +62,19 @@ export class TerminalSettingsTabComponent {
if (await fs.exists(wslPath)) { if (await fs.exists(wslPath)) {
this.shells.push({ name: 'Bash on Windows', command: wslPath }) this.shells.push({ name: 'Bash on Windows', command: wslPath })
} }
let cygwinPath = await new Promise<string>(resolve => {
let reg = new Registry({ hive: Registry.HKLM, key: "\\Software\\Cygwin\\setup" })
reg.get('rootdir', (err, item) => {
if (err) {
resolve(null)
}
resolve(item.value)
})
})
if (cygwinPath) {
this.shells.push({ name: 'Cygwin', command: path.join(cygwinPath, 'bin', 'bash.exe') })
}
} }
if (this.hostApp.platform == Platform.Linux || this.hostApp.platform == Platform.macOS) { if (this.hostApp.platform == Platform.Linux || this.hostApp.platform == Platform.macOS) {
this.shells = (await fs.readFile('/etc/shells', 'utf-8')) this.shells = (await fs.readFile('/etc/shells', 'utf-8'))

View File

@ -16,6 +16,7 @@ import { hterm, preferenceManager } from '../hterm'
export class TerminalTabComponent extends BaseTabComponent { export class TerminalTabComponent extends BaseTabComponent {
hterm: any hterm: any
configSubscription: Subscription configSubscription: Subscription
sessionCloseSubscription: Subscription
bell$ = new Subject() bell$ = new Subject()
size$ = new ReplaySubject<ResizeEvent>(1) size$ = new ReplaySubject<ResizeEvent>(1)
input$ = new Subject<string>() input$ = new Subject<string>()
@ -70,7 +71,7 @@ export class TerminalTabComponent extends BaseTabComponent {
}) })
this.write(data) this.write(data)
}) })
this.session.closed$.first().subscribe(() => { this.sessionCloseSubscription = this.session.closed$.subscribe(() => {
this.app.closeTab(this) this.app.closeTab(this)
}) })
@ -225,6 +226,7 @@ export class TerminalTabComponent extends BaseTabComponent {
decorator.detach(this) decorator.detach(this)
}) })
this.configSubscription.unsubscribe() this.configSubscription.unsubscribe()
this.sessionCloseSubscription.unsubscribe()
this.size$.complete() this.size$.complete()
this.input$.complete() this.input$.complete()
this.output$.complete() this.output$.complete()
@ -232,7 +234,10 @@ export class TerminalTabComponent extends BaseTabComponent {
this.alternateScreenActive$.complete() this.alternateScreenActive$.complete()
this.mouseEvent$.complete() this.mouseEvent$.complete()
this.bell$.complete() this.bell$.complete()
}
this.session.gracefullyDestroy() async destroy () {
super.destroy()
await this.session.destroy()
} }
} }

View File

@ -56,7 +56,9 @@ export class Session {
}) })
this.pty.on('close', () => { this.pty.on('close', () => {
this.close() if (this.open) {
this.destroy()
}
}) })
} }
@ -74,41 +76,40 @@ export class Session {
this.pty.write(data) this.pty.write(data)
} }
sendSignal (signal) { kill (signal?: string) {
this.pty.kill(signal) this.pty.kill(signal)
} }
close () { async gracefullyKillProcess (): Promise<void> {
this.open = false if (process.platform == 'win32') {
this.closed$.next() this.kill()
this.pty.end() } else {
} await new Promise((resolve) => {
this.kill('SIGTERM')
gracefullyDestroy () { setImmediate(() => {
return new Promise((resolve) => { if (!this.open) {
this.sendSignal('SIGTERM') resolve()
if (!this.open) { } else {
resolve() setTimeout(() => {
this.destroy() if (this.open) {
} else { this.kill('SIGKILL')
setTimeout(() => { }
if (this.open) { resolve()
this.sendSignal('SIGKILL') }, 1000)
this.destroy()
} }
resolve() })
}, 1000) })
} }
})
} }
destroy () { async destroy (): Promise<void> {
if (open) { if (this.open) {
this.close() this.open = false
this.closed$.next()
this.destroyed$.next()
this.output$.complete()
await this.gracefullyKillProcess()
} }
this.destroyed$.next()
this.pty.destroy()
this.output$.complete()
} }
async getWorkingDirectory (): Promise<string> { async getWorkingDirectory (): Promise<string> {

View File

@ -2,7 +2,7 @@
"compilerOptions": { "compilerOptions": {
"baseUrl": "src", "baseUrl": "src",
"module": "commonjs", "module": "commonjs",
"target": "es2015", "target": "es2016",
"declaration": false, "declaration": false,
"noImplicitAny": false, "noImplicitAny": false,
"removeComments": false, "removeComments": false,
@ -22,5 +22,5 @@
"es7" "es7"
] ]
}, },
"include": ["src"] "exclude": ["node_modules", "dist"]
} }

View File

@ -41,6 +41,7 @@ module.exports = {
'path', 'path',
'node-pty', 'node-pty',
'child-process-promise', 'child-process-promise',
'winreg',
/^rxjs/, /^rxjs/,
/^@angular/, /^@angular/,
/^@ng-bootstrap/, /^@ng-bootstrap/,

View File

@ -2,7 +2,7 @@
"compilerOptions": { "compilerOptions": {
"baseUrl": "src", "baseUrl": "src",
"module": "commonjs", "module": "commonjs",
"target": "es2015", "target": "es2016",
"declaration": false, "declaration": false,
"noImplicitAny": false, "noImplicitAny": false,
"removeComments": false, "removeComments": false,
@ -14,5 +14,5 @@
"es7" "es7"
] ]
}, },
"include": ["src"] "exclude": ["node_modules", "dist"]
} }