Comments:"rlwrap | Ithaca"
URL:http://ithaca.arpinum.org/2013/01/20/rlwrap.html
New York, NY· 2013-01-20
Problem
Recently I’ve been working with REPLs a lot. In many cases, the
REPL has Readline support built in. This means that you can use
the Up and Down arrows to scroll through the history of the commands you’ve
entered, and often you will even be able to auto-complete language builtins
using Tab. If you are already comfortable with Readline from your shell,
then you will be able to use Ctrl-a
and the like immediately in your REPL
of choice. In all these ways and more, Readline makes you far more
productive.
Some REPLs, however, have no support for Readline. That means that if you enter an Up arrow, you get garbage output like this:
$ sml
Standard ML of New Jersey v110.75 [built: Fri Jan 11 10:32:43 2013]
- ^[[A
Solution
Luckily, there’s a handy and simple solution for cases like this:
rlwrap
. Simply install rlwrap
via your operating system’s
package manager (or manually), and then invoke the REPL via rlwrap
:
$ rlwrap sml
(Edit: On OSX, you definitely want to use a package manager to install rlwrap – for example, Homebrew or MacPorts– since you’re likely to have trouble installing it otherwise. The problem is that newer versions of OSX don’t use GNU Readline. Thanks to a Hacker News commenter for pointing this out to me.)
At this point, even if you do nothing else, the REPL is now at least able
to handle Up and Down arrows to scroll through history, and you can use
basic Readline commands like Ctrl-a
and Ctrl-e
to go to the start and
end of the line respectively, Ctrl-u
to delete back to the prompt (and
save the deleted material), Ctrl-y
to paste saved text back into the
prompt and so on. One other nice thing is that rlwrap
saves history per
command across invocations. That means that the next time you use that
same REPL, your previous commands are still in rlwrap
’s history. Lovely.
But Wait: There’s More
What I’ve covered is already great, but rlwrap
can do even better. You
can customize its behavior in various ways. I’m going to run through one
customization that’s fast and simple, but very powerful. When you invoke
rlwrap
, you can feed it a file filled with additional completions.
rlwrap
reads the file before starting, splits the file into words and
then supports Tab-completion for all those additional words. For example,
if you create a file with all of SML’s keywords, then you can load
those into rlwrap
when you start SML’s REPL:
rlwrap -f keywords sml
Now your SMLREPL will autocomplete those keywords using the Tab key.
“Sure,” you say, “but that’s a little annoying.” You think it’s a pain to
enter -f <filename>
every time, and it also means you must keep track of
where that file is, and so on and so forth.
No problem: rlwrap
has you covered. Create a directory somewhere and set
an environment variable RLWRAP_HOME
in your shell to point to that
directory. For example:
mkdir ~/.rlwrap
# Added to my .bashrc
export RLWRAP_HOME="$HOME/.rlwrap"
Now simply save your keywords file in that directory as
$RLWRAP_HOME/.<command>_completions
. rlwrap
will now automagically load
those completions every time you call rlwrap command
. (I’ve gone a little
fast here. For further details see man rlwrap
, particularly the
section on files.)
Conclusion
I’m embarrassed to admit that I had not heard of rlwrap
until this
weekend. But I’m awfully glad I met it. I see hours of happy yak-shaving in
my future as I customize it. Most importantly, now my life in the REPLs
for SML, Lua and Chicken Scheme, all of which are very minimal, will be
far more productive.