function withVimHistoryKeys
withVimHistoryKeys(stdin: NodeJS.ReadStream): NodeJS.ReadStream

stdin, with Ctrl-K and Ctrl-J walking history — a NEW stream, which is what to read instead.

Rewritten bytes rather than a keypress listener, for two reasons a listener cannot get around. Ctrl-K already means kill-to-end-of-line, and a second listener does not replace readline's — it runs as well, so the line would be shredded on the way to the previous entry. And Ctrl-J is not a distinguishable key at all: it arrives as \n, which readline reads as Enter and every multi-line paste is full of. Binding it by name would stop pastes submitting.

The paste is what the single-byte test is for. A keystroke arrives on its own; a paste arrives as a chunk, so a \n with company is left exactly as it was and still submits its line.

What comes back stands in for the TTY it wraps — readline needs isTTY and setRawMode to put the terminal in the mode this depends on, and neither belongs to a plain PassThrough.

import { PassThrough } from 'node:stream';
import { withVimHistoryKeys } from './index.ts';

const stdin = Object.assign(new PassThrough(), { setRawMode: () => {} });
withVimHistoryKeys(stdin as unknown as NodeJS.ReadStream).isTTY; // true — readline must believe it

Parameters

stdin: NodeJS.ReadStream

Return Type

NodeJS.ReadStream

Usage

import { withVimHistoryKeys } from "lib/commands/repl/index.ts";