NAME

Term::CLI - CLI interpreter based on Term::ReadLine

VERSION

version 0.057001

SYNOPSIS

 use Term::CLI;
 use Term::CLI::Command;
 use Term::CLI::Argument::Filename;
 use Data::Dumper;

 my $cli = Term::CLI->new(
    name => 'myapp',
    prompt => 'myapp> ',
    cleanup => sub {
        my ($cli) = @_;
        $cli->write_history;
            or warn "cannot write history: ".$cli->error."\n";
    },
    callback => sub {
        my ($self, %args) = @_;
        print Data::Dumper->Dump([\%args], ['args']);
        return %args;
    },
    commands => [
        Term::CLI::Command->new(
            name => 'copy',
            options => [ 'verbose!' ],
            arguments => [
                Term::CLI::Argument::Filename->new(name => 'src'),
                Term::CLI::Argument::Filename->new(name => 'dst'),
            ],
            callback => sub {
                my ($self, %args) = @_;
                print Data::Dumper->Dump([\%args], ['args']);
                return (%args, status => 0);
            }
        )
    ],
 );

 $cli->read_history;  # Read history from ~/.myapp_history
 $cli->write_history; # Write history to ~/.myapp_history

 $cli->word_delimiters(';,');
 # $cli will now recognise things like: 'copy;--verbose;a,b'

 $cli->word_delimiters(" \t\n");
 # $cli will now recognise things like: 'copy --verbose a b'

 while ( my $input = $cli->readline(skip => qr/^\s*(?:#.*)?$/) ) {
    $cli->execute_line($input);
 }

DESCRIPTION

Implement an easy-to-use command line interpreter based on Term::ReadLine(3p). Although primarily aimed at use with the Term::ReadLine::Gnu(3p) implementation, it also supports Term::ReadLine::Perl(3p).

First-time users may want to read Term::CLI::Tutorial(3p) and Term::CLI::Intro(3p) first, and peruse the example scripts in the source distribution's examples and tutorial directories.

I/O handles

By default Term::CLI will create a Term::CLI::ReadLine object (which creates a Term::ReadLine object) that reads from STDIN and writes to STDOUT.

This is notably different from the default behaviour of e.g. GNU Readline which opens the TTY separately. This may cause unexpected behaviour in case of UTF-8 I/O.

By explicitly specifying STDIN and STDOUT as the I/O handles, we force the underlying readline implementation to use the same I/O encoding as the standard I/O handles. This means that e.g. use open qw(:std :utf8) will do what you expect and enable UTF-8 input/output.

See the filehandles argument to new below for information on how to change this.

CLASS STRUCTURE

Inherits from:

Term::CLI::Base(3p).

Consumes:

Term::CLI::Role::CommandSet(3p), Term::CLI::Role::State(3p).

CONSTRUCTORS

new ( attr => VAL ... )

Create a new Term::CLI object and return a reference to it.

Valid attributes:

callback => CodeRef

Reference to a subroutine that should be called when the command is executed, or undef.

filehandles => ArrayRef

File handles to use for input and output, resp. The array can be:

    undef
    [ ]
    [ IN_FH, OUT_FH ]

If the value is either undef or an empty list, then we rely on the underlying readline's implementation to determine the I/O handles (but see I/O handles above).

cleanup => CodeRef

Reference to a subroutine that should be called when the object is destroyed (i.e. in Moo terminology, when DEMOLISH is called).

commands => ArrayRef

Reference to an array containing Term::CLI::Command object instances that describe the commands that Term::CLI recognises, or undef.

ignore_keyboard_signals => ArrayRef

Specify a list of signals for which the keyboard generation should be turned off during a readline operation.

The list of signals should be a combination of INT, QUIT, or TSTP. See also ignore_keyboard_signals in Term::CLI::ReadLine(3p). If this is not specified, QUIT keyboard generation is turned off by default.

name => Str

The application name. This is used for e.g. the history file and default command prompt.

If not given, defaults to $FindBin::Script (see FindBin(3p)).

pager => ArrayRef[Str]

The pager attribute is used by write_pager().

The value should be a command line split on words, e.g.:

    OBJ->pager( [ 'cat', '-n', '-e' ] );

If an empty list is provided, no external pager will be used, and output is printed to STDOUT directly.

See also the pager method.

prompt => Str

Prompt to display when readline is called. Defaults to the application name with > and a space appended.

skip => RegEx

Set the object's skip attribute, telling the readline method to ignore input lines that match the given RegEx. A common call value is qr{^\s+(?:#.*)$} to skip empty lines, lines with only whitespace, and comments.

history_file => Str

Specify the file to read/write input history to/from. The default is name + _history in the user's HOME directory.

history_lines => Int

Maximum number of lines to keep in the input history. Default is 1000.

INHERITED METHODS

This class inherits all the attributes and accessors of Term::CLI::Role::CommandSet(3p) and Term::CLI::Base(3p), most notably:

Accessors

has_callback

See has_callback in Term::CLI::Role::CommandSet.

callback ( [ CodeRef ] )

See callback in Term::CLI::Role::CommandSet.

has_commands

See has_commands in Term::CLI::Role::CommandSet.

commands ( [ ArrayRef ] )

See commands in Term::CLI::Role::CommandSet.

ArrayRef with Term::CLI::Command object instances.

Others

has_cleanup

Predicate function that returns whether or not the cleanup attribute has been set.

cleanup ( [ CodeRef ] )

Gets or sets a reference to a subroutine that should be called when the object is destroyed (i.e. in Moo terminology, when DEMOLISH is called).

The code is called with one parameter: the object to be destroyed. One typical use of cleanup is to ensure that the history gets saved upon exit:

  my $cli = Term::CLI->new(
    ...
    cleanup => sub {
      my ($cli) = @_;
      $cli->write_history
        or warn "cannot write history: ".$cli->error."\n";
    }
  );
find_command ( Str )

See find_command in Term::CLI::Role::CommandSet.

find_matches ( Str )

See find_matches in Term::CLI::Role::CommandSet.

METHODS

Accessors

name

The application name. See name in Term::CLI::Base.

pager ( [ ArrayRef[Str] ] )

Get or set the pager to use for write_pager().

If an empty list is provided, no external pager will be used, and output is printed to STDOUT directly.

Example:

    $help_cmd->pager([]); # Print directly to STDOUT.
    $help_cmd->pager([ 'cat', '-n' ]); # Number output lines.
prompt ( [ Str ] )

Get or set the command line prompt to display to the user.

term

Return a reference to the underlying Term::CLI::ReadLine object. See term in Term::CLI::Base.

quote_characters ( [ Str ] )

Get or set the characters that should considered quote characters for the completion and parsing/execution routines.

Default is '", that is a single quote or a double quote.

It's possible to change this, but this will interfere with the default splitting function, so if you do want custom quote characters, you should also override the split_function.

split_function ( [ CodeRef ] )

Get or set the function that is used to split a (partial) command line into words. The default function uses Text::ParseWords::parse_line. Note that this implies that it can take into account custom delimiters, but not custom quote characters.

The CodeRef is called as:

    ( ERROR, [ WORD, ... ] ) = CodeRef->( CLI_OBJ, TEXT )

The function should return a list of at least one element, an ERROR string. Subsequent elements are the words resulting from the split.

ERROR string should be empty (not undef!) if splitting was successful, otherwise it should contain a relevant error message.

word_delimiters ( [ Str ] )

Get or set the characters that are considered word delimiters in the completion and parsing/execution routines.

Default is \t\n, that is space, tab, and newline.

The first character in the string is also the character that is appended to a completed word at the command line prompt.

Output Control

write_pager
    %status = $CLI->write_pager( text => TEXT, ... );

Output the TEXT through the pager command, or STDOUT if the pager attribute is not set.

Returns the arguments it was given with the following fields set if there was an error:

status => Int

Non-zero value indicates an error.

error => Str

Erorr diagnostic.

History Control

history_lines ( [ Int ] )

Get or set the maximum number of lines to keep in the history. Default is 1000.

history_file ( [ Str ] )

Set the default file to read from/write to.

read_history ( [ Str ] )

Try to read input history from the history_file(). Returns 1 on success. On failure, it will set the error field and return undef.

If Str is given, it will try to read from that file instead. If that is successful, the history_file() attribute will be set to Str.

write_history ( [ Str ] )

Try to write the input history to the history_file(). Returns 1 on success. On failure, it will set the error field and return undef.

If Str is given, it will try to write to that file instead. If that is successful, the history_file() attribute will be set to Str.

SIGNAL HANDLING

The Term::CLI object (through Term::CLI::ReadLine) will make sure that signals are handled "correctly". This especially means that if a signal is not ignored, the terminal is left in a "sane" state before any signal handler is called or the program exits.

See also SIGNAL HANDLING in Term::CLI::ReadLine.

SEE ALSO

FindBin(3p), Moo(3p), Getopt::Long(3p), Term::CLI::Argument(3p), Term::CLI::Base(3p), Term::CLI::Command(3p), Term::CLI::Intro(3p), Term::CLI::ReadLine(3p), Term::CLI::Role::CommandSet(3p), Term::CLI::Tutorial(3p), Term::ReadLine::Gnu(3p), Term::ReadLine::Perl(3p), Term::ReadLine(3p), Text::ParseWords(3p), Types::Standard(3p).

Inspiration for the custom completion came from: https://robots.thoughtbot.com/tab-completion-in-gnu-readline. This is an excellent tutorial into the completion mechanics of the readline library, and, by extension, Term::ReadLine::Gnu(3p).

AUTHOR

Steven Bakker <sbakker@cpan.org>, 2018.

COPYRIGHT AND LICENSE

Copyright (c) 2018 Steven Bakker

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See "perldoc perlartistic."

This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.