Editing Input

Problem

You want a user to be able to edit a line before sending it to you for reading.

Solution

Use the standard Term::ReadLine library along with the Term::ReadLine::Gnu module from CPAN:

use Term::ReadLine;

$term = Term::ReadLine->new("APP DESCRIPTION");
$OUT = $term->OUT || *STDOUT;

$term->addhistory($fake_line);
$line = $term->readline(PROMPT);

print $OUT "Any program output\n";

Discussion

The program in Example 15.4 acts as a crude shell. It reads a line and passes it to the shell to execute. The readline method reads a line from the terminal, with editing and history recall. It automatically adds the user’s line to the history.

Example 15-4. vbsh

#!/usr/bin/perl -w
# vbsh -  very bad shell
use strict;

use Term::ReadLine;
use POSIX qw(:sys_wait_h);

my $term = Term::ReadLine->new("Simple Shell");
my $OUT = $term->OUT() || *STDOUT;
my $cmd;

while (defined ($cmd = $term->readline('$ ') )) {
    my @output = `$cmd`;
    my $exit_value  = $? >> 8;
    my $signal_num  = $? & 127;
    my $dumped_core = $? & 128;
    printf $OUT "Program terminated with status %d from signal %d%s\n",
           $exit_value, $signal_num, 
           $dumped_core ? " (core dumped)" : "";
    print @output;
    $term->addhistory($cmd);
}

If you want to seed the history with your own functions, use the addhistory method:

$term->addhistory($seed_line);

You can’t seed with more than one line at a time. To remove a line from the history, use the remove_history method, which takes an index into the history list. 0 is the first (least recent) entry, ...

Get Perl Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.