From 5c053c40ed4513645e49fec95911e2e88b3e5862 Mon Sep 17 00:00:00 2001 From: Ian Thomas Date: Tue, 3 Dec 2024 08:36:53 +0000 Subject: [PATCH] Support multi-character inputs (escape sequences) whilst command running (#80) --- src/commands/wasm_command_runner.ts | 9 +++++++++ test/tests/shell.test.ts | 14 ++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/commands/wasm_command_runner.ts b/src/commands/wasm_command_runner.ts index d4e5693..16fed47 100644 --- a/src/commands/wasm_command_runner.ts +++ b/src/commands/wasm_command_runner.ts @@ -17,10 +17,19 @@ export abstract class WasmCommandRunner implements ICommandRunner { const start = Date.now(); const wasmModule = this.wasmLoader.getModule(this.moduleName()); + let _getCharBuffer: number[] = []; + // Functions for monkey-patching. function getChar(tty: any) { + if (_getCharBuffer.length > 0) { + return _getCharBuffer.shift()!; + } + const utf16codes = stdin.readChar(); const utf16 = utf16codes[0]; + if (utf16codes.length > 1) { + _getCharBuffer = utf16codes.slice(1); + } if (stdin.isTerminal()) { if (utf16 === 10) { diff --git a/test/tests/shell.test.ts b/test/tests/shell.test.ts index 67d58bc..6b0bcd3 100644 --- a/test/tests/shell.test.ts +++ b/test/tests/shell.test.ts @@ -79,6 +79,20 @@ test.describe('Shell', () => { expect(output).toMatch(/^wc\r\na b\r\nc {6}1 {7}3 {7}5\r\n/); }); + test('should support terminal stdin of an ansi escape sequence', async ({ page }) => { + const output = await page.evaluate(async () => { + const { shell, output } = await globalThis.cockle.shellSetupEmpty(); + const EOT = String.fromCharCode(4); + const downArrow = '\x1B[B'; + await Promise.all([ + shell.inputLine('wc'), + globalThis.cockle.terminalInput(shell, ['a', downArrow, 'b', EOT]) + ]); + return output.text; + }); + expect(output).toMatch(/^wc\r\nab {6}0 {7}1 {7}5\r\n/); + }); + test('should support terminal stdin more than once', async ({ page }) => { const output = await page.evaluate(async () => { const { shell, output } = await globalThis.cockle.shellSetupEmpty();