mirror of
https://github.com/Eugeny/tabby.git
synced 2025-10-04 22:14:55 +00:00
.
This commit is contained in:
@@ -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())
|
||||
|
@@ -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()
|
||||
|
@@ -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,
|
||||
|
@@ -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`)
|
||||
|
Reference in New Issue
Block a user