diff --git a/src/bun/mod.ts b/src/bun/mod.ts index 74db1ab..cc7a4c2 100644 --- a/src/bun/mod.ts +++ b/src/bun/mod.ts @@ -2,34 +2,14 @@ * The main entrypoint when using Bun as the runtime */ -import { getTermios } from '../common/termios'; -import {ctrl_key, is_control} from "../common/strings"; +import { getTermios } from "../common/termios.ts"; +export * from './terminal_io.ts'; -export async function main(): Promise { +export async function init() { const t = await getTermios(); - t.enableRawMode(); - const decoder = new TextDecoder(); - for await (const chunk of Bun.stdin.stream()) { - const char = String(decoder.decode(chunk)); - - if (char === ctrl_key('q')) { - t.disableRawMode(); - return 0; - } - - if (is_control(char)) { - console.log(char.codePointAt(0) + '\r'); - } else { - console.log(`${char} ('${char.codePointAt(0)}')\r`); - } - - } - - process.on('exit', (code) => { - console.log(`Process exited with code ${code}`); + process.on('exit', () => { + console.info('Disabling raw mode'); t.disableRawMode(); - }); - - return -1; + }) } \ No newline at end of file diff --git a/src/bun/terminal_io.ts b/src/bun/terminal_io.ts index e69de29..6491efd 100644 --- a/src/bun/terminal_io.ts +++ b/src/bun/terminal_io.ts @@ -0,0 +1,8 @@ +/** + * Wrap the runtime-specific hook into stdin + */ +export async function* inputLoop() { + for await (const chunk of Bun.stdin.stream()) { + yield chunk; + } +} \ No newline at end of file diff --git a/src/common/ansi.ts b/src/common/ansi.ts new file mode 100644 index 0000000..9209096 --- /dev/null +++ b/src/common/ansi.ts @@ -0,0 +1,2 @@ +export enum Ansi { +} diff --git a/src/common/mod.ts b/src/common/mod.ts index 08a2152..c97aad4 100644 --- a/src/common/mod.ts +++ b/src/common/mod.ts @@ -1,10 +1,35 @@ import { importForRuntime } from './runtime.ts'; +import { getTermios } from './termios.ts'; +import { ctrl_key, is_control } from './strings.ts'; export * from './runtime.ts'; export * from './strings.ts'; export type { ITestBase } from './test_base.ts'; export async function main() { - const { main } = await importForRuntime('./mod.ts'); - await main(); -} + const t = await getTermios(); + t.enableRawMode(); + const { inputLoop, init } = await importForRuntime('mod.ts'); + + // Set up handlers to disable raw mode for each runtime + await init(); + + for await (const chunk of inputLoop()) { + const decoder = new TextDecoder(); + const char = String(decoder.decode(chunk)); + + if (char === ctrl_key('q')) { + t.disableRawMode(); + return 0; + } + + if (is_control(char)) { + console.log(char.codePointAt(0) + '\r'); + } else { + console.log(`${char} ('${char.codePointAt(0)}')\r`); + } + } + + t.disableRawMode(); + return -1; +} \ No newline at end of file diff --git a/src/deno/mod.ts b/src/deno/mod.ts index 276e0fc..b9962cb 100644 --- a/src/deno/mod.ts +++ b/src/deno/mod.ts @@ -1,28 +1,15 @@ /** * The main entrypoint when using Deno as the runtime */ -import { getTermios } from '../common/termios.ts'; -import { ctrl_key, is_control } from '../common/strings.ts'; +import {getTermios} from "../common/termios.ts"; -export async function main(): Promise { +export * from './terminal_io.ts'; + +export async function init() { const t = await getTermios(); - t.enableRawMode(); - const decoder = new TextDecoder(); - for await (const chunk of Deno.stdin.readable) { - const char = String(decoder.decode(chunk)); - - if (char === ctrl_key('q')) { - t.disableRawMode(); - return 0; - } - - if (is_control(char)) { - console.log(char.codePointAt(0) + '\r'); - } else { - console.log(`${char} ('${char.codePointAt(0)}')\r`); - } - } - - return -1; + globalThis.onbeforeunload = (): void => { + console.log('Disabling raw mode'); + t.disableRawMode(); + }; } diff --git a/src/deno/terminal_io.ts b/src/deno/terminal_io.ts index e69de29..792862d 100644 --- a/src/deno/terminal_io.ts +++ b/src/deno/terminal_io.ts @@ -0,0 +1,8 @@ +/** + * Wrap the runtime-specific hook into stdin + */ +export async function* inputLoop() { + for await (const chunk of Deno.stdin.readable) { + yield chunk; + } +}