This commit is contained in:
Eugene Pankov
2017-04-16 23:04:29 +02:00
parent 125ec2b81c
commit acc13087bf
18 changed files with 91 additions and 33 deletions

View File

@@ -1,7 +1,5 @@
import { Observable } from 'rxjs/Observable'
import 'rxjs/add/operator/map'
import 'rxjs/add/operator/debounceTime'
import 'rxjs/add/operator/distinctUntilChanged'
import 'rxjs'
import { Observable } from 'rxjs'
import * as fs from 'fs-promise'
const fontManager = require('font-manager')
const equal = require('deep-equal')
@@ -45,7 +43,8 @@ export class TerminalSettingsTabComponent {
.map(x => x.split(',')[0].trim())
this.fonts.sort()
})
}
if (this.hostApp.platform == Platform.Linux || this.hostApp.platform == Platform.macOS) {
this.shells = (await fs.readFile('/etc/shells', 'utf-8'))
.split('\n')
.map(x => x.trim())

View File

@@ -16,7 +16,6 @@ import { hterm, preferenceManager } from '../hterm'
export class TerminalTabComponent extends BaseTabComponent {
hterm: any
configSubscription: Subscription
focusedSubscription: Subscription
bell$ = new Subject()
size$ = new ReplaySubject<ResizeEvent>(1)
input$ = new Subject<string>()
@@ -49,8 +48,9 @@ export class TerminalTabComponent extends BaseTabComponent {
}
ngOnInit () {
this.focusedSubscription = this.focused.subscribe(() => {
this.focused$.subscribe(() => {
this.hterm.scrollPort_.focus()
this.hterm.scrollPort_.resize()
})
this.hterm = new hterm.hterm.Terminal()
@@ -123,6 +123,14 @@ export class TerminalTabComponent extends BaseTabComponent {
event.preventDefault()
}
const _resize = hterm.scrollPort_.resize.bind(hterm.scrollPort_)
hterm.scrollPort_.resize = () => {
if (!this.hasFocus) {
return
}
_resize()
}
const _onMouse_ = hterm.onMouse_.bind(hterm)
hterm.onMouse_ = (event) => {
this.mouseEvent$.next(event)
@@ -216,9 +224,7 @@ export class TerminalTabComponent extends BaseTabComponent {
this.decorators.forEach((decorator) => {
decorator.detach(this)
})
this.focusedSubscription.unsubscribe()
this.configSubscription.unsubscribe()
this.title$.complete()
this.size$.complete()
this.input$.complete()
this.output$.complete()

View File

@@ -1,10 +1,40 @@
import * as fs from 'fs-promise'
const { exec, spawn } = require('child-process-promise')
import { Injectable } from '@angular/core'
import { Logger, LogService } from 'terminus-core'
import { SessionOptions, SessionPersistenceProvider } from './api'
interface IChildProcess {
pid: number
ppid: number
command: string
}
async function listProcesses (): Promise<IChildProcess[]> {
return (await exec(`ps -A -o pid,ppid,command`)).stdout
.split('\n')
.slice(1)
.map(line => line.split(' ').filter(x => x).slice(0, 3))
.map(([pid, ppid, command]) => {
return {
pid: parseInt(pid), ppid: parseInt(ppid), command
}
})
}
@Injectable()
export class ScreenPersistenceProvider extends SessionPersistenceProvider {
private logger: Logger
constructor (
log: LogService,
) {
super()
this.logger = log.create('main')
}
async attachSession (recoveryId: any): Promise<SessionOptions> {
let lines: string[]
try {
@@ -20,8 +50,16 @@ export class ScreenPersistenceProvider extends SessionPersistenceProvider {
return null
}
lines = (await exec(`pgrep -P ${screenPID}`)).stdout.split('\n')
let recoveredTruePID = parseInt(lines[0])
let child = (await listProcesses()).find(x => x.ppid === screenPID)
if (!child) {
this.logger.error(`Could not find any children of the screen process (PID ${screenPID})!`)
}
if (child.command == 'login') {
child = (await listProcesses()).find(x => x.ppid === child.pid)
}
let recoveredTruePID = child.pid
return {
recoveryId,
@@ -36,6 +74,7 @@ export class ScreenPersistenceProvider extends SessionPersistenceProvider {
await fs.writeFile(configPath, `
escape ^^^
vbell on
deflogin off
term xterm-color
bindkey "^[OH" beginning-of-line
bindkey "^[OF" end-of-line
@@ -48,6 +87,7 @@ export class ScreenPersistenceProvider extends SessionPersistenceProvider {
`, 'utf-8')
let recoveryId = `term-tab-${Date.now()}`
let args = ['-d', '-m', '-c', configPath, '-U', '-S', recoveryId, '-T', 'xterm-256color', '--', options.command].concat(options.args || [])
this.logger.debug('Spawning screen with', args.join(' '))
await spawn('screen', args, {
cwd: options.cwd,
env: options.env || process.env,

View File

@@ -113,8 +113,8 @@ export class Session {
async getWorkingDirectory (): Promise<string> {
if (process.platform == 'darwin') {
let lines = (await exec(`lsof -p ${this.truePID} -Fn`)).split('\n')
return lines[2]
let lines = (await exec(`lsof -p ${this.truePID} -Fn`)).stdout.split('\n')
return lines[2].substring(1)
}
if (process.platform == 'linux') {
return await fs.readlink(`/proc/${this.truePID}/cwd`)