GNU Readline

Probably my favorite library ever is GNU Readline. Among other things, it allows us to write interactive software that effortlessly accommodates everyone's preferred keybindings. While it may have failed to stop the pointless bickering, it has let the rest of us ignore it if we choose.

It handles all the dicey bits of letting a user hit backspace and whatnot while they're entering data. My favorite part is that it lets the user configure it to their liking. While the editor wars may be stupid, there is one aspect we can't ignore: once a user has a set of keybindings imprinted in their brain, it becomes difficult to use any other keybindings. If you use readline, it not only handles all the difficult parts of interactive input (that, honestly, you don't want to have to think about), it also allows your users to choose their favorite keybindings. It's a win-win!

Readline is a C library, but here's how you might use it from Perl.

#!/usr/bin/env perl

use v5.32;
use warnings;
use Term::ReadLine;

my $term = Term::ReadLine->new('Number Game');

my $MIN = 1;
my $MAX = 100;

my $answer = $MIN + int rand $MAX;

my $prompt = "Guess a number between $MIN and $MAX: ";

while (my $guess = $term->readline($prompt))  {
    say 'Right!' and last if $guess == $answer;
    say 'Too low.' if $guess < $answer;
    say 'Too high.' if $guess > $answer;
    $term->addhistory($guess);
}

It prompts the user for input, lets them edit it to their hearts content, and then reads it in when they're ready. That's a lot of complicated stuff (and I didn't even mention the history).

But Perl will do some of this work itself. To make the above program use GNU Readline, we have to install Term::ReadLine::Gnu. We don't have to change the above code at all…Term::ReadLine just works better if we have Term::ReadLine::Gnu installed.

On Debian, we first have to install the header files for GNU Readline

sudo apt install libreadline-dev

Now we can install the Perl module

cpanm Term::ReadLine::Gnu

Also, I like to turn off the "ornaments" (underlining and whatnot).

export "PERL_RL= o=0"

Now running the program looks like this

❯ ./number-game 
Guess a number between 1 and 100: 50
Too low.
Guess a number between 1 and 100: 75
Too high.
Guess a number between 1 and 100: 62
Too low.
Guess a number between 1 and 100: 68
Too high.
Guess a number between 1 and 100: 65
Right!

But, of course, I can typo that "50" and not end up with something like "500^H" or whatever. More importantly, users of this program can choose between Emacs keybindings and vi keybindings just by changing their INPUTRC file. Moreover, they can make some totally custom keybindings that I've never even heard of. I, the programmer, don't even have to know about it. The users configure my software to their liking. Everybody wins.