From ac1ec9b75fe15b4e076e096822365ece24977204 Mon Sep 17 00:00:00 2001 From: "Sebastian (Tiedtke) Huckleberry" Date: Wed, 12 Feb 2025 08:18:59 -0800 Subject: [PATCH] ANSI sequences need to be interpreted for TUIs (#1956) --- src/extension/executors/runner/index.ts | 6 +--- src/extension/terminal/terminalState.ts | 39 +++++++++---------------- 2 files changed, 14 insertions(+), 31 deletions(-) diff --git a/src/extension/executors/runner/index.ts b/src/extension/executors/runner/index.ts index d33883ef2..bb939e238 100644 --- a/src/extension/executors/runner/index.ts +++ b/src/extension/executors/runner/index.ts @@ -40,7 +40,7 @@ import { getServerRunnerVersion, isNotebookTerminalEnabledForCell, } from '../../../utils/configuration' -import { ITerminalState, XTermState } from '../../terminal/terminalState' +import { ITerminalState } from '../../terminal/terminalState' import { toggleTerminal } from '../../commands' import { closeTerminalByEnvID, openTerminalByEnvID } from '../task' import { @@ -280,10 +280,6 @@ export const executeRunner: IKernelRunner = async ({ let mimeType = cellMimeType if (interactive) { - if (terminalState instanceof XTermState) { - terminalState.resetBuffer() - } - if (revealNotebookTerminal) { program.registerTerminalWindow('notebook') await program.setActiveTerminalWindow('notebook') diff --git a/src/extension/terminal/terminalState.ts b/src/extension/terminal/terminalState.ts index 3889957fe..10fba6f8f 100644 --- a/src/extension/terminal/terminalState.ts +++ b/src/extension/terminal/terminalState.ts @@ -1,4 +1,5 @@ import { Terminal as XTerm } from '@xterm/headless' +import { SerializeAddon } from '@xterm/addon-serialize' import { OutputType } from '../../constants' import { RunnerExitReason, RunProgramOptions } from '../runner' @@ -30,26 +31,19 @@ export class XTermState implements ITerminalState { readonly outputType = OutputType.terminal protected xterm: XTerm + private serializer: SerializeAddon private processInfo: IProcessInfoState | undefined private programOptions: RunProgramOptions | undefined - protected buffer: RingBuffer - private textDecoder = new TextDecoder() constructor(readonly capacity: number) { - this.buffer = this.resetBuffer() - // TODO: lines/cols this.xterm = new XTerm({ allowProposedApi: true, + scrollback: capacity, }) - } - - setProgramOptions(programOptions: RunProgramOptions): void { - this.programOptions = programOptions - } - getProgramOptions(): RunProgramOptions | undefined { - return this.programOptions + this.serializer = new SerializeAddon() + this.xterm.loadAddon(this.serializer) } setProcessInfo(processInfo?: IProcessInfoState) { @@ -60,27 +54,20 @@ export class XTermState implements ITerminalState { return this.processInfo } - serialize(): string { - return this.buffer.getAll().join('') + setProgramOptions(programOptions: RunProgramOptions): void { + this.programOptions = programOptions } - write(data: string | Uint8Array): void { - this.xterm.write(data) - this.addToBuffer(data) + getProgramOptions(): RunProgramOptions | undefined { + return this.programOptions } - addToBuffer(data: string | Uint8Array): void { - if (typeof data === 'string') { - this.buffer.push(data) - } else { - this.buffer.push(this.textDecoder.decode(data)) - } + serialize(): string { + return this.serializer.serialize({ scrollback: this.capacity }) } - resetBuffer(): RingBuffer { - // capacity is items vs lines because we don't handle line breaks - this.buffer = new RingBuffer(this.capacity) - return this.buffer + write(data: string | Uint8Array): void { + this.xterm.write(data) } input(data: string, wasUserInput: boolean): void {