diff --git a/tabby-serial/src/api.ts b/tabby-serial/src/api.ts index 2e2f35a3..ccd4c89b 100644 --- a/tabby-serial/src/api.ts +++ b/tabby-serial/src/api.ts @@ -3,7 +3,7 @@ import { SerialPortStream } from '@serialport/stream' import { LogService, NotificationsService } from 'tabby-core' import { Subject, Observable } from 'rxjs' import { Injector, NgZone } from '@angular/core' -import { BaseSession, BaseTerminalProfile, LoginScriptsOptions, SessionMiddleware, StreamProcessingOptions, TerminalStreamProcessor } from 'tabby-terminal' +import { BaseSession, BaseTerminalProfile, LoginScriptsOptions, SessionMiddleware, StreamProcessingOptions, TerminalStreamProcessor, UTF8SplitterMiddleware } from 'tabby-terminal' import { SerialService } from './services/serial.service' export interface SerialProfile extends BaseTerminalProfile { @@ -64,6 +64,8 @@ export class SerialSession extends BaseSession { this.middleware.unshift(new SlowFeedMiddleware()) } + this.middleware.push(new UTF8SplitterMiddleware()) + this.setLoginScriptsOptions(profile.options) } diff --git a/tabby-ssh/src/session/shell.ts b/tabby-ssh/src/session/shell.ts index 6be8f6dc..29534f78 100644 --- a/tabby-ssh/src/session/shell.ts +++ b/tabby-ssh/src/session/shell.ts @@ -2,8 +2,8 @@ import { Observable, Subject } from 'rxjs' import stripAnsi from 'strip-ansi' import { ClientChannel } from 'ssh2' import { Injector } from '@angular/core' -import { LogService, UTF8Splitter } from 'tabby-core' -import { BaseSession } from 'tabby-terminal' +import { LogService } from 'tabby-core' +import { BaseSession, UTF8SplitterMiddleware } from 'tabby-terminal' import { SSHSession } from './ssh' import { SSHProfile } from '../api' @@ -13,7 +13,6 @@ export class SSHShellSession extends BaseSession { get serviceMessage$ (): Observable { return this.serviceMessage } private serviceMessage = new Subject() private ssh: SSHSession|null - private decoder = new UTF8Splitter() constructor ( injector: Injector, @@ -24,6 +23,7 @@ export class SSHShellSession extends BaseSession { this.ssh = ssh this.setLoginScriptsOptions(this.profile.options) this.ssh.serviceMessage$.subscribe(m => this.serviceMessage.next(m)) + this.middleware.push(new UTF8SplitterMiddleware()) } async start (): Promise { @@ -61,14 +61,10 @@ export class SSHShellSession extends BaseSession { }) this.shell.on('data', data => { - this.emitOutput(this.decoder.write(data)) + this.emitOutput(data) }) this.shell.on('end', () => { - const remainder = this.decoder.flush() - if (remainder.length) { - this.emitOutput(remainder) - } this.logger.info('Shell session ended') if (this.open) { this.destroy() diff --git a/tabby-terminal/src/index.ts b/tabby-terminal/src/index.ts index f41b5007..f6706875 100644 --- a/tabby-terminal/src/index.ts +++ b/tabby-terminal/src/index.ts @@ -94,6 +94,7 @@ export * from './api/interfaces' export * from './middleware/streamProcessing' export * from './middleware/loginScriptProcessing' export * from './middleware/oscProcessing' +export * from './middleware/utf8Splitter' export * from './api/middleware' export * from './session' export { LoginScriptsSettingsComponent, StreamProcessingSettingsComponent } diff --git a/tabby-terminal/src/middleware/utf8Splitter.ts b/tabby-terminal/src/middleware/utf8Splitter.ts new file mode 100644 index 00000000..651a8d55 --- /dev/null +++ b/tabby-terminal/src/middleware/utf8Splitter.ts @@ -0,0 +1,22 @@ +import { UTF8Splitter } from 'tabby-core' + +import { SessionMiddleware } from '../api/middleware' + +/** + * Ensures that the session output is chunked at UTF8 character boundaries. + */ +export class UTF8SplitterMiddleware extends SessionMiddleware { + private decoder = new UTF8Splitter() + + feedFromSession (data: Buffer): void { + super.feedFromSession(this.decoder.write(data)) + } + + close (): void { + const remainder = this.decoder.flush() + if (remainder.length) { + super.feedFromSession(remainder) + } + super.close() + } +}