Following this discussion on how to preserve command line history between sessions, I defined the following alias:
alias node='env NODE_NO_READLINE=1 rlwrap node'
It works perfectly for the history persistance but now, everytime I do a Ctrl-C to send node's '.break' command, rlwrap takes it too but as a SIGINT: it cleans everything and suicides (as described in its man page), thus forcing me to restart a node session (having to recall my var, funcs, requires etc), while I just wanted to '.break'...
Any way to get back the classic node behaviour?
- Ctrl-C : breaks
- Ctrl-C again (or on a blank line): exit
Avoiding SIGINT
nodechanges the meaning of CTRL-C by unsetting its interrupt characterVINTR(usually CTRL-C) to avoid the interrupt signal that it would otherwise get.After starting up,
rlwrapis sleeping all the time, until something happens on your terminal or on the pseudo-terminal (pty) used by e.g.node. This "something" can be a keypress by you, or output fromnode.Every time this happens,
rlwrapwill copynodess terminal settings (includingVINTR) ) to its own tty.However, if
nodeonly changes its terminal settings, this, by itself, won't wake uprlwrap, which will thus keep the old settings on its own tty. Transparency will then be broken: When you press CTRL-Crlwrapwill still interpret it as aSIGINT, whilenodewould have understood a.breakcommand.There ia a special, very obscure,
ptymode (EXTPROC) that allows the pty master (rlwrap) to be woken up by a slave's changes in terminal settings, but this is very un-portable. This is why, since version 0.41,rlwraphas the much less elegant--pollingoption that makes it wake up every 40 milliseconds and copy the slave's terminal settings.Forward CTRL-C
Starting with version 0.43,
rlwrapcan directly forward special keys even when in readline mode by binding such a key torlwrap-direct-keypressin~/.inputrc:However,
nodeonly gives CTRL+C special treatment when it itself uses readline (tryNODE_NO_READLINE=1 nodeand then type CTRL-C) to see what I mean)In such cases (i.e. when a command does its own line editing), one has to force
rlwrapinto readline mode:This has the unfortunate and unavoidable drawback that whanever a command asks for single keypresses (
Continue? Y/N) one has to type an extra Enter.And then there still is the problem sketched above: if the terminal's interrupt character is not changed,
nodewill never see the CTRL-C (but get aSIGINTinstead)There are two solutions. Either:
or:
Wrapping up
To make a long story short:
"\C-c": rlwrap-direct-keypressto yourinputcrlwrap --polling --always-readlineas above