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 )