mirror of
https://github.com/Eugeny/tabby.git
synced 2025-06-24 05:19:57 +00:00
95 lines
3.4 KiB
TypeScript
95 lines
3.4 KiB
TypeScript
import { Observable, Subject } from 'rxjs'
|
|
import { Logger } from 'tabby-core'
|
|
import { LoginScriptProcessor, LoginScriptsOptions } from './middleware/loginScriptProcessing'
|
|
import { OSCProcessor } from './middleware/oscProcessing'
|
|
import { SessionMiddlewareStack } from './api/middleware'
|
|
|
|
/**
|
|
* A session object for a [[BaseTerminalTabComponent]]
|
|
* Extend this to implement custom I/O and process management for your terminal tab
|
|
*/
|
|
export abstract class BaseSession {
|
|
open: boolean
|
|
readonly oscProcessor = new OSCProcessor()
|
|
readonly middleware = new SessionMiddlewareStack()
|
|
protected output = new Subject<string>()
|
|
protected binaryOutput = new Subject<Buffer>()
|
|
protected closed = new Subject<void>()
|
|
protected destroyed = new Subject<void>()
|
|
protected loginScriptProcessor: LoginScriptProcessor | null = null
|
|
protected reportedCWD?: string
|
|
private initialDataBuffer = Buffer.from('')
|
|
private initialDataBufferReleased = false
|
|
|
|
get output$ (): Observable<string> { return this.output }
|
|
get binaryOutput$ (): Observable<Buffer> { return this.binaryOutput }
|
|
get closed$ (): Observable<void> { return this.closed }
|
|
get destroyed$ (): Observable<void> { return this.destroyed }
|
|
|
|
constructor (protected logger: Logger) {
|
|
this.middleware.push(this.oscProcessor)
|
|
this.oscProcessor.cwdReported$.subscribe(cwd => {
|
|
this.reportedCWD = cwd
|
|
})
|
|
|
|
this.middleware.outputToTerminal$.subscribe(data => {
|
|
if (!this.initialDataBufferReleased) {
|
|
this.initialDataBuffer = Buffer.concat([this.initialDataBuffer, data])
|
|
} else {
|
|
this.output.next(data.toString())
|
|
this.binaryOutput.next(data)
|
|
}
|
|
})
|
|
|
|
this.middleware.outputToSession$.subscribe(data => this.write(data))
|
|
}
|
|
|
|
feedFromTerminal (data: Buffer): void {
|
|
this.middleware.feedFromTerminal(data)
|
|
}
|
|
|
|
protected emitOutput (data: Buffer): void {
|
|
this.middleware.feedFromSession(data)
|
|
}
|
|
|
|
releaseInitialDataBuffer (): void {
|
|
this.initialDataBufferReleased = true
|
|
this.output.next(this.initialDataBuffer.toString())
|
|
this.binaryOutput.next(this.initialDataBuffer)
|
|
this.initialDataBuffer = Buffer.from('')
|
|
}
|
|
|
|
setLoginScriptsOptions (options: LoginScriptsOptions): void {
|
|
const newProcessor = new LoginScriptProcessor(this.logger, options)
|
|
if (this.loginScriptProcessor) {
|
|
this.middleware.replace(this.loginScriptProcessor, newProcessor)
|
|
} else {
|
|
this.middleware.push(newProcessor)
|
|
}
|
|
this.loginScriptProcessor = newProcessor
|
|
}
|
|
|
|
async destroy (): Promise<void> {
|
|
if (this.open) {
|
|
this.logger.info('Destroying')
|
|
this.open = false
|
|
this.closed.next()
|
|
this.destroyed.next()
|
|
await this.gracefullyKillProcess()
|
|
}
|
|
this.middleware.close()
|
|
this.closed.complete()
|
|
this.destroyed.complete()
|
|
this.output.complete()
|
|
this.binaryOutput.complete()
|
|
}
|
|
|
|
abstract start (options: unknown): Promise<void>
|
|
abstract resize (columns: number, rows: number): void
|
|
abstract write (data: Buffer): void
|
|
abstract kill (signal?: string): void
|
|
abstract gracefullyKillProcess (): Promise<void>
|
|
abstract supportsWorkingDirectory (): boolean
|
|
abstract getWorkingDirectory (): Promise<string|null>
|
|
}
|