Term-ShellUI

 view release on metacpan or  search on metacpan

lib/Term/ShellUI.pm  view on Meta::CPAN


And, of course, you can use an array of procs too.

    $term->prompt([sub {'$'}, sub {'<'}]);

=item token_chars

This argument specifies the characters that should be considered
tokens all by themselves.  For instance, if I pass
token_chars=>'=', then 'ab=123' would be parsed to ('ab', '=', '123').
Without token_chars, 'ab=123' remains a single string.

NOTE: you cannot change token_chars after the constructor has been
called!  The regexps that use it are compiled once (m//o).

=item display_summary_in_help

Usually it's easier to have the command's summary (desc) printed first,
then follow it with the documentation (doc).  However, if the doc
already contains its description (for instance, if you're reading it
from a podfile), you don't want the summary up there too.  Pass 0
to prevent printing the desc above the doc.  Defaults to 1.

=back

=cut

sub new
{
    my $type = shift;
    my %args = (
        app => $0,
        prompt => "$0> ",
        commands => undef,
        blank_repeats_cmd => 0,
        backslash_continues_command => 0,
        history_file => undef,
        history_max => 500,
        token_chars => '',
        keep_quotes => 0,
        debug_complete => 0,
        display_summary_in_help => 1,
        @_
    );

    my $self = {};
    bless $self, $type;

    $self->{done} = 0;

    $self->{parser} = Text::Shellwords::Cursor->new(
        token_chars => $args{token_chars},
        keep_quotes => $args{keep_quotes},
        debug => 0,
        error => sub { shift; $self->error(@_); },
        );

    # expand tildes in the history file
    if($args{history_file}) {
        $args{history_file} =~ s/^~([^\/]*)/$1?(getpwnam($1))[7]:
            $ENV{HOME}||$ENV{LOGDIR}||(getpwuid($>))[7]/e;
    }

    for(keys %args) {
        next if $_ eq 'app';    # this param is not a member
        $self->{$_} = $args{$_};
    }

    $self->{term} ||= new Term::ReadLine($args{'app'});
    $self->{term}->MinLine(0);  # manually call AddHistory

    my $attrs = $self->{term}->Attribs;
# there appear to be catastrophic bugs with history_word_delimiters
# it goes into an infinite loop when =,[] are in token_chars
    # $attrs->{history_word_delimiters} = " \t\n".$self->{token_chars};
    $attrs->{completion_function} = sub { completion_function($self, @_); };

    $self->{OUT} = $self->{term}->OUT || \*STDOUT;
    $self->{prevcmd} = "";  # cmd to run again if user hits return

    @{$self->{eof_exit_hooks}} = ();

    return $self;
}


=item process_a_cmd([cmd])

Runs the specified command or prompts for it if no arguments are supplied.
Returns the result or undef if no command was called.

=cut

sub process_a_cmd
{
    my ($self, $incmd) = @_;

    $self->{completeline} = "";
    my $OUT = $self->{'OUT'};

    my $rawline = "";
    if($incmd) {
        $rawline = $incmd;
    } else {
        INPUT_LOOP: for(;;) {
            my $prompt = $self->prompt();
            $prompt = $prompt->[length $rawline ? 1 : 0] if ref $prompt eq 'ARRAY';
            $prompt = $prompt->($self, $rawline) if ref $prompt eq 'CODE';
            my $newline = $self->{term}->readline($prompt);

            # EOF exits
            unless(defined $newline) {
                # If we have eof_exit_hooks let them have a say
                if(scalar(@{$self->{eof_exit_hooks}})) {
                    foreach my $sub (@{$self->{eof_exit_hooks}}) {
                        if(&$sub()) {
                            next INPUT_LOOP;
                        }
                    }
                }



( run in 1.735 second using v1.01-cache-2.11-cpan-140bd7fdf52 )