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?
node
changes the meaning of CTRL-C by unsetting its interrupt character VINTR
(usually CTRL-C) to avoid the interrupt signal that it would otherwise get.
After starting up, rlwrap
is 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 from node
.
Every time this happens, rlwrap
will copy nodes
s terminal settings (including VINTR
) ) to its own tty.
However, if node
only changes its terminal settings, this, by itself, won't wake up rlwrap
, which will thus keep the old settings on its own tty. Transparency will then be broken: When you press CTRL-C rlwrap
will still interpret it as a SIGINT
, while node
would have understood a .break
command.
There ia a special, very obscure, pty
mode (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, rlwrap
has the much less elegant --polling
option that makes it wake up every 40 milliseconds and copy the slave's terminal settings.
Starting with version 0.43, rlwrap
can directly forward special keys even when in readline mode by binding
such a key to rlwrap-direct-keypress
in ~/.inputrc
:
$if node
"\C-c": rlwrap-direct-keypress
$endif
However, node
only gives CTRL+C special treatment when it itself uses readline (try NODE_NO_READLINE=1 node
and 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 rlwrap
into readline mode:
$ rlwrap --always-readline node
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, node
will never see the CTRL-C (but get a SIGINT
instead)
There are two solutions. Either:
stty intr undef # disable interrupt character
rlwrap --always-readline node
stty intr '^c' # re-enable CTRL-C
or:
rlwrap --polling --always-readline node # --polling means: continually wake up and wacth node's interrupt character
To make a long story short:
"\C-c": rlwrap-direct-keypress
to your inputc
rlwrap --polling --always-readline
as aboveIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With