Skip to content

readline: coerce non-string prompts, redraw on resize, pause the input on close - #3526

Open
ctate wants to merge 1 commit into
mainfrom
ctate/readline-coerce-non-91c4bc
Open

ctate wants to merge 1 commit into
mainfrom
ctate/readline-coerce-non-91c4bc

Conversation

@ctate

@ctate ctate commented Nov 11, 2026

Copy link
Copy Markdown
Collaborator
  • Move 38 readline rows and ERR_USE_AFTER_CLOSE/ERR_INVALID_CURSOR_POS from partial to supported: non-string prompts through getPrompt/getCursorPos/write, terminal resize redraw for stream and process.stdout outputs, and close()'s pause of process.stdin.
  • Add two differential corpus programs and a PTY harness test that compares the resize redraw byte for byte against Node.
  • Retire the resize-redraw and non-string-prompt limitations from the documentation and add corpus cost budgets and TS7 baselines for the new programs.

A prompt that is not a string now behaves as in Node: getPrompt()
answers the stored value, a terminal interface writes the value's
String() (valueOf before toString, a symbol throws), getCursorPos()
measures that text, and a non-terminal interface throws
ERR_INVALID_ARG_TYPE instead of writing. The prompt is coerced by the
same dynamic string addition the interface uses for prompt + line, so
the coercion is Node's.

The interface watches its output's 'resize' event and redraws the prompt
and line when it fires, byte-identically to Node, for a stream output
and for process.stdout, and removes the listener on close. Signal and
resize listeners do not keep the process alive, as in Node.

Interface.close() now pauses the input as Node's pause() does, which
lets the process exit when the last interface on process.stdin closes
while the keypress hub's 'data' listener stays registered.
@vercel

vercel Bot commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
scriptc Ready Ready Preview, v0 Nov 11, 2026 4:12am UTC

Comment on lines +6283 to +6286
while (scr_rl_resize_hooks) {
ScrRlResizeHook *h = scr_rl_resize_hooks;
scr_rl_resize_hooks = h->next;
free(h);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exiting with an unclosed terminal interface on a stream output leaks its resize callback and makes RC-audited binaries exit with code 99.

Fix on Vercel

* the last interface closes: the keypress hub's 'data' listener stays
* registered, as in Node, but a paused stdin never reads. */
if (rl->in) rl->io->pause(rl->in);
else if (rl->stdin_in) scr_stdin_pause();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Closing a stdin-backed interface now leaves subsequent interfaces unable to read because construction never resumes the paused stdin.

Fix on Vercel

This branch was successfully deployed

1 active deployment
Preview — 7e0c0b1f Deployed Nov 11, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant