1package Shell::Base; 2 3# ---------------------------------------------------------------------- 4# Shell::Base - A generic class to build line-oriented command interpreters. 5# $Id: Base.pm,v 1.5 2004/08/26 20:01:47 dlc Exp $ 6# ---------------------------------------------------------------------- 7# Copyright (C) 2003 darren chamberlain <darren@cpan.org> 8# 9# This module is free software; you can redistribute it and/or 10# modify it under the same terms as Perl itself. 11# ---------------------------------------------------------------------- 12 13use strict; 14use vars qw( $VERSION $REVISION $PROMPT 15 $RE_QUIT $RE_HELP $RE_SHEBANG 16 ); 17 18use Carp qw(carp croak); 19use Env qw($PAGER $SHELL $COLUMNS); 20use IO::File; 21use File::Basename qw(basename); 22use Term::Size qw(chars); 23use Text::Shellwords qw(shellwords); 24 25$VERSION = 0.05; # $Date: 2004/08/26 20:01:47 $ 26$REVISION = sprintf "%d.%02d", q$Revision: 1.5 $ =~ /(\d+)\.(\d+)/; 27$RE_QUIT = '(?i)^\s*(exit|quit|logout)' unless defined $RE_QUIT; 28$RE_HELP = '(?i)^\s*(help|\?)' unless defined $RE_HELP; 29$RE_SHEBANG = '^\s*!\s*$' unless defined $RE_SHEBANG; 30 31# ---------------------------------------------------------------------- 32# import() 33# 34# The default import method, called when the class is use'd. This 35# sets the default prompt, which can be overridden by a subclass as 36# necessary. 37# 38# There is a pseudo-function called "shell" that can be imported by 39# classes which use a Shell::Base-originated class: 40# 41# use My::Shell qw(shell); 42# 43# shell(); 44# 45# Tests: t/import.t 46# ---------------------------------------------------------------------- 47sub import { 48 my $class = shift; 49 50 if (@_ && grep /^shell$/, @_) { 51 # Requested as use Shell::Base qw(shell), or 52 # from the command line as -MShell::Base=shell 53 # Install the shell function into the caller's 54 # namespace. However, there is no shell 55 # function; we create one here. shell would 56 # be invoked by the caller as: 57 # 58 # shell(@args); 59 # 60 # i.e., without a package, so we need to pass 61 # a package in. A closure will do nicely. 62 63 no strict qw(refs); 64 my $caller = caller; 65 *{"$caller\::shell"} = sub { 66 $class->new(@_)->run(); 67 }; 68 } 69 70 $PROMPT = "($class) \$ " unless defined $PROMPT; 71} 72 73# ---------------------------------------------------------------------- 74# new(\%args) 75# 76# Basic constructor. 77# 78# new() calls initialization methods: 79# 80# - init_rl 81# 82# o Initializes the Term::ReadLine instance 83# 84# - init_rcfiles 85# 86# o Initializes rc files (anything in RCFILES) 87# 88# - init_help 89# 90# o Initializes the list of help methods 91# 92# - init_completions 93# 94# o Initializes the list of tab-completable commands 95# 96# - init 97# 98# o Subclass-specific intializations. 99# 100# Tests: t/new.t 101# All tests instantiate objects, so new is tested indirectly 102# by all tests. 103# ---------------------------------------------------------------------- 104sub new { 105 my $class = shift; 106 my $args = UNIVERSAL::isa($_[0], 'HASH') ? shift : { @_ }; 107 108 my @size = chars(); 109 my $self = bless { 110 ARGS => $args, 111 COMPLETIONS => undef, # tab completion 112 CONFIG => { }, 113 HELPS => undef, # help methods 114 HISTFILE => undef, # history file 115 PAGER => undef, # pager 116 PROMPT => $PROMPT, # default prompt 117 TERM => undef, # Term::ReadLine instance 118 SIZE => \@size, # Terminal size 119 COLUMNS => $size[0], 120 ROWS => $size[1], 121 } => $class; 122 123 $self->init_rl($args); 124 $self->init_rcfiles($args); 125 $self->init_completions($args); 126 $self->init_help($args); 127 $self->init($args); 128 129 return $self; 130} 131 132# ---------------------------------------------------------------------- 133# init_rl(\%args) 134# 135# Initialize Term::ReadLine. Subclasses can override this method if 136# readline support is not needed or wanted. 137# 138# Tests: t/init_rl.t 139# ---------------------------------------------------------------------- 140sub init_rl { 141 my ($self, $args) = @_; 142 my ($term, $attr); 143 144 require Term::ReadLine; 145 $self->term($term = Term::ReadLine->new(ref $self)); 146 147 # Setup default tab-completion function. 148 $attr = $term->Attribs; 149 $attr->{completion_function} = sub { $self->complete(@_) }; 150 151 if (my $histfile = $args->{ HISTFILE }) { 152 $self->histfile($histfile); 153 $term->ReadHistory($histfile); 154 } 155 156 return $self; 157} 158 159# ---------------------------------------------------------------------- 160# init_rcfiles(\%args) 161# 162# Initialize rc files, which are in name = value format. The RCFILES 163# member of %args should contain a reference to a rc files. These 164# will be read in the order defined, and all elements defined within 165# will be present in $self->{ CONFIG }, and accessible via $self->config. 166# 167# test: t/init_rcfiles.t 168# XXX Refactor this into init_rcfiles and parse_rcfile! 169# ---------------------------------------------------------------------- 170sub init_rcfiles { 171 my ($self, $args) = @_; 172 my (@rcfiles, $rcfile); 173 174 return unless defined $args->{ RCFILES }; 175 176 # Ensure we have an array 177 $args->{ RCFILES } = [ $args->{ RCFILES } ] 178 unless ref($args->{ RCFILES }) eq 'ARRAY'; 179 180 @rcfiles = @{ $args->{ RCFILES } }; 181 182 for $rcfile (@rcfiles) { 183 _merge_hash($self->{ CONFIG }, 184 scalar $self->parse_rcfile($rcfile)); 185 } 186} 187 188# ---------------------------------------------------------------------- 189# parse_rcfile($filename) 190# 191# Parses a config file, and returns a hash of config values. 192# 193# test: t/parse_rcfile.t 194# ---------------------------------------------------------------------- 195sub parse_rcfile { 196 my ($self, $rcfile) = @_; 197 my %config = (); 198 199 my $buffer = ""; 200 my $rc = IO::File->new($rcfile) 201 or next; 202 203 while (defined(my $line = <$rc>)) { 204 chomp $line; 205 $line =~ s/#.*$//; 206 207 if (length $buffer && length $line) { 208 $line = $buffer . $line; 209 } 210 211 # Line continuation 212 if ($line =~ s/\\$//) { 213 $buffer = $line; 214 next; 215 } else { 216 $buffer = ''; 217 } 218 219 next unless length $line; 220 221 my ($name, $value) = $line =~ /^\s*(.*?)\s*(?:=>?\s*(.*))?$/; 222 $name = lc $name; 223 unless (defined $value) { 224 if ($name =~ s/^no//) { 225 $value = 0; 226 } 227 else { 228 $value = 1; 229 } 230 } 231 $config{ $name } = $value; 232 } 233 234 return wantarray ? %config : \%config; 235} 236 237# ---------------------------------------------------------------------- 238# init_help() 239# 240# Initializes the internal HELPS list, which is a list of all the 241# help_foo methods defined within the current class, and all the 242# classes from which the current class inherits from. 243# 244# Tests: t/init_help.t 245# ---------------------------------------------------------------------- 246sub init_help { 247 my $self = shift; 248 my $class = ref $self || $self; 249 my %uniq = (); 250 251 no strict qw(refs); 252 $self->helps( 253 grep { ++$uniq{$_} == 1 } 254 map { s/^help_//; $_ } 255 grep /^help_/, 256 map({ %{"$_\::"} } @{"$class\::ISA"}), 257 keys %{"$class\::"}); 258} 259 260# ---------------------------------------------------------------------- 261# init_completions() 262# 263# Initializes the internal COMPLETIONS list, which is used by the 264# complete method, which is, in turn, used by Term::ReadLine to 265# do tab-compleion. 266# 267# Tests: t/init_completions.t 268# ---------------------------------------------------------------------- 269sub init_completions { 270 my $self = shift; 271 my $class = ref $self || $self; 272 my %uniq = (); 273 274 no strict qw(refs); 275 $self->completions( 276 sort 277 "help", 278 grep { ++$uniq{$_} == 1 } 279 map { s/^do_//; $_ } 280 grep /^do_/, 281 map({ %{"$_\::"} } @{"$class\::ISA"}), 282 keys %{"$class\::"}); 283} 284 285# ---------------------------------------------------------------------- 286# init(\%args) 287# 288# Basic init method; subclasses can override this as needed. This is 289# the place to do any subclass-specific initialization. 290# 291# Command completion is initialized here, so subclasses should call 292# $self->SUPER::init(@_) within overridden init methods if they want 293# this completion to be setup. 294# 295# Tests: none (why?) 296# ---------------------------------------------------------------------- 297sub init { 298 my ($self, $args) = @_; 299 300 return $self; 301} 302 303# ---------------------------------------------------------------------- 304# run() 305# 306# run is the main() of the interpreter. Its duties are: 307# 308# - Print the results of $self->intro(), if defined, 309# via $self->print() 310# 311# - Get a line of input, via $self->term->readline. 312# This begins the run loop. 313# 314# o Pass this line to $self->precmd for massaging 315# 316# o Pass this line to $self->parseline for splitting into 317# (command_name, variable assignments, arguments) 318# 319# o Check contents of command_name; there are a few special 320# cases: 321# 322# + If the line is a help line (matches $RE_HELP), then 323# call $self->help(@args) 324# 325# + If the line is a quit line (matches $RE_QUIT), then 326# call $self->quit() 327# 328# + If the line is a bang (matches $RE_SHEBANG), then 329# invoke $self->do_shell() 330# 331# + Otherwise, attempt to invoke $self->do_$command_name 332# 333# o The output from whichever of the above is chosen will be 334# passed to $self->postcmd for final processing 335# 336# o If the output from $self->postcmd is not undefined, it 337# will be printed via $self->print() 338# 339# o The prompt is reset, and control returns to the top of 340# the run loop. 341# 342# Tests: none (Dunno how, without requiring Expect (yuck)) 343# ---------------------------------------------------------------------- 344sub run { 345 my $self = shift; 346 my ($prompt, $blurb); 347 348 $prompt = $self->prompt; 349 $blurb = $self->intro; 350 351 352 if (defined $blurb) { 353 chomp $blurb; 354 $self->print("$blurb\n"); 355 } 356 357 while (defined (my $line = $self->readline($prompt))) { 358 my (@args, $cmd, $env, $output); 359 360 $line = $self->precmd($line); 361 362 ($cmd, $env, @args) = $self->parseline($line); 363 local %ENV = (%ENV, %$env); 364 365 if (! length($cmd)) { 366 $output = $self->emptycommand(); 367 } 368 elsif ($cmd =~ /$RE_HELP/) { 369 $output = $self->help(@args); 370 } 371 elsif ($cmd =~ /$RE_QUIT/) { 372 $self->quit; 373 } 374 else { 375 if ($cmd =~ /$RE_SHEBANG/) { 376 $cmd = "shell"; 377 } 378 eval { 379 my $meth = "do_$cmd"; 380 $output = $self->$meth(@args); 381 }; 382 if ($@) { 383 $output = sprintf "%s: Bad command or filename", $self->progname; 384 my $err = $@; 385 chomp $err; 386 warn "$output ($err)\n"; 387 eval { 388 $output = $self->default($cmd, @args); 389 }; 390 } 391 } 392 393 $output = $self->postcmd($output); 394 $output =~ s/\n*$//; 395 396 chomp $output; 397 $self->print("$output\n") if defined $output; 398 399 # In case precmd or postcmd modified the prompt, 400 # we recollect it before displaying it. 401 $prompt = $self->prompt(); 402 } 403 404 $self->quit(); 405} 406 407# ---------------------------------------------------------------------- 408# readline() 409# 410# Calls readline on the internal Term::ReadLine instance. Provided 411# as a separate method within Shell::Base so that subclasses which 412# do not want to use Term::ReadLine don't have to. 413# 414# Tests: none (how?) 415# ---------------------------------------------------------------------- 416sub readline { 417 my ($self, $prompt) = @_; 418 return $self->term->readline($prompt); 419} 420 421# ---------------------------------------------------------------------- 422# print(@data) 423# 424# This method is here to that subclasses can redirect their output 425# stream without having to do silly things like tie STDOUT (although 426# they still can if they want, by overriding this method). 427# 428# Tests: none 429# ---------------------------------------------------------------------- 430sub print { 431 my ($self, @stuff) = @_; 432 my $OUT = $self->term->Attribs->{'outstream'}; 433 434 CORE::print $OUT @stuff; 435} 436 437# ---------------------------------------------------------------------- 438# quit([$status]) 439# 440# Exits the interpreter with $status as the exit status (0 by default). 441# If $self->outro() returns a defined value, it is printed here. 442# 443# Tests: none 444# ---------------------------------------------------------------------- 445sub quit { 446 my ($self, $status) = @_; 447 $status = 0 unless defined $status; 448 449 my $blurb = $self->outro(); 450 $self->print("$blurb\n") if defined $blurb; 451 452 if (my $h = $self->histfile) { 453 # XXX Can this be better encapsulated? 454 $self->term->WriteHistory($h); 455 } 456 457 exit($status); 458} 459 460 461# ---------------------------------------------------------------------- 462# precmd($line) 463# 464# This is called immediately before parseline(), to give the subclass 465# first crack at manipulating the input line. This might be a good 466# place to do, for example, tilde-expansion, or some other kind of 467# variable pre-processing. 468# 469# Tests: t/pre,postcmd.t 470# ---------------------------------------------------------------------- 471sub precmd { 472 my ($self, $line) = @_; 473 return $line; 474} 475 476# ---------------------------------------------------------------------- 477# postcmd($output) 478# 479# This is called immediately before $output is passed to print, to 480# give the class one last chance to manipulate the text before it is 481# sent to the output stream. 482# 483# Tests: t/pre,postcmd.t 484# ---------------------------------------------------------------------- 485sub postcmd { 486 my ($self, $output) = @_; 487 return $output; 488} 489 490# ---------------------------------------------------------------------- 491# default($cmd, @args) 492# 493# What to do by default, i.e., when there is no matching do_foo method. 494# 495# Tests: t/default.t 496# ---------------------------------------------------------------------- 497sub default { 498 my ($self, $cmd, @args) = @_; 499 my $class = ref $self || $self; 500 return "$class->$cmd(@args) called, but do_$cmd is not defined!"; 501} 502 503# ---------------------------------------------------------------------- 504# emptycommand() 505# 506# What to do when an empty command is issued 507# ---------------------------------------------------------------------- 508sub emptycommand { 509 my $self = shift; 510 return; 511} 512 513# ---------------------------------------------------------------------- 514# prompt_no() 515# 516# Returns the command number in the history. 517# 518# Tests: t/prompt_no.t 519# ---------------------------------------------------------------------- 520sub prompt_no { 521 my $self = shift; 522 return $self->term->where_history(); 523} 524 525# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 526# Some general purpose methods. Subclasses may wish to override some 527# of these, but many of them (version, progname) are probably ok as is. 528# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 529 530# ---------------------------------------------------------------------- 531# version() 532# 533# Returns the version number. 534# ---------------------------------------------------------------------- 535sub version { 536 return $VERSION; 537} 538 539# ---------------------------------------------------------------------- 540# do_version() 541# 542# Example command method. 543# 544# Tests: t/version.t 545# ---------------------------------------------------------------------- 546sub do_version { 547 my $self = shift; 548 return sprintf "%s v%s", $self->progname, $self->version; 549} 550 551sub help_version { 552 return "Display the version." 553} 554 555# ---------------------------------------------------------------------- 556# progname() 557# 558# Returns the name of the program in question. Defaults to 559# basename($0) or the classname of the caller. 560# 561# Tests: t/progname.t 562# ---------------------------------------------------------------------- 563sub progname { 564 my $self = shift; 565 return basename($0) || ref $self || $self; 566} 567 568# ---------------------------------------------------------------------- 569# intro() 570# 571# Introduction text, printed when the interpreter starts up. The 572# default is to print the GPL-recommended introduction. I would 573# hope that modules that utilize Shell::Base would create intro() 574# methods that incorporate this, if possible: 575# 576# sub intro { 577# my $self = shift; 578# my $default_intro = $self->SUPER::intro(); 579# 580# return "My Intro\n$default_intro"; 581# } 582# 583# Tests: t/intro.t 584# ---------------------------------------------------------------------- 585sub intro { 586 # No default intro 587 return "" 588} 589 590# ---------------------------------------------------------------------- 591# outro() 592# 593# Similar to intro(), but called from within quit(), immediately 594# before exit is called. 595# 596# Tests: t/outro.t 597# ---------------------------------------------------------------------- 598sub outro { 599 my $self = shift; 600 return sprintf "Thanks for using %s!", $self->progname; 601} 602 603# ---------------------------------------------------------------------- 604# parseline($line) 605# 606# parseline splits a line into three components: 607# 608# 1. Command 609# 610# 2. Environment variable additions 611# 612# 3. Arguments 613# 614# returns an array that looks like: 615# 616# ($cmd, \%env, @args) 617# 618# %env comes from environment variable assignments that occur at 619# the beginning of the line: 620# 621# FOO=bar cmd opt1 opt2 622# 623# In this case $env{FOO} = "bar". 624# 625# This parseline method doesn't handle pipelines gracefully; pipes 626# ill treated like any other token. 627# 628# Tests: t/parseline.t 629# ---------------------------------------------------------------------- 630sub parseline { 631 my ($self, $line) = @_; 632 my ($cmd, %env, @args); 633 634 @args = shellwords($line); 635 %env = (); 636 637 while (@args) { 638 if ($args[0] =~ /=/) { 639 my ($n, $v) = split /=/, shift(@args), 2; 640 $env{$n} = $v || ""; 641 } 642 else { 643 $cmd = shift @args; 644 last; 645 } 646 } 647 648 return (($cmd or ""), \%env, @args); 649} 650 651# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 652# Generic accessors 653# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 654 655# ---------------------------------------------------------------------- 656# args([$arg]) 657# 658# Returns the hash ref of configuration arguments. If passed a single 659# value, then that configuration value will be returned. 660# 661# Tests: t/args.t 662# ---------------------------------------------------------------------- 663sub args { 664 my $self = shift; 665 if (@_) { 666 return $self->{ ARGS }->{ $_[0] } 667 || $self->{ ARGS }->{ uc $_[0] }; 668 } 669 return $self->{ ARGS }; 670} 671 672# ---------------------------------------------------------------------- 673# config([$arg]) 674# 675# Returns the hash reference of configuration parameters read from 676# the rc file(s). 677# 678# Tests: t/init_rcfiles.t 679# ---------------------------------------------------------------------- 680sub config { 681 my $self = shift; 682 if (@_) { 683 return $self->{ CONFIG }->{ $_[0] }; 684 } 685 return $self->{ CONFIG }; 686} 687 688 689# ---------------------------------------------------------------------- 690# term() 691# 692# Returns the Term::ReadLine instance. Useful if the subclass needs 693# do something like modify attributes on the instance. 694# 695# Tests: t/term.t 696# ---------------------------------------------------------------------- 697sub term { 698 my $self = shift; 699 $self->{ TERM } = shift if (@_); 700 return $self->{ TERM }; 701} 702 703# ---------------------------------------------------------------------- 704# histfile([$histfile]) 705# 706# Gets/set the history file. 707# 708# Tests: t/histfile.t 709# ---------------------------------------------------------------------- 710sub histfile { 711 my $self = shift; 712 $self->{ HISTFILE } = shift if (@_); 713 return $self->{ HISTFILE }; 714} 715 716 717# ---------------------------------------------------------------------- 718# prompt([$prompt[, @args]]) 719# 720# The prompt can be modified using this method. For example, multiline 721# commands (which much be handled by the subclass) might modify the 722# prompt, e.g., PS1 and PS2 in bash. If $prompt is a coderef, it is 723# executed with $self and @args: 724# 725# $self->{ PROMPT } = &$prompt($self, @args); 726# 727# Tests: t/prompt.t 728# ---------------------------------------------------------------------- 729sub prompt { 730 my $self = shift; 731 if (@_) { 732 my $p = shift; 733 if (ref($p) eq 'CODE') { 734 $self->{ PROMPT } = &$p($self, @_); 735 } 736 else { 737 $self->{ PROMPT } = $p; 738 } 739 } 740 return $self->{ PROMPT }; 741} 742 743# ---------------------------------------------------------------------- 744# pager([$pager]) 745# 746# It is possible that each time through the loop in run() might need 747# to be passed through a pager; this method exists to figure out what 748# that pager should be. 749# 750# Tests: t/pager.t 751# ---------------------------------------------------------------------- 752sub pager { 753 my $self = shift; 754 755 if (@_) { 756 $self->{ PAGER } = shift; 757 } 758 759 unless (defined $self->{ PAGER }) { 760 $self->{ PAGER } = $PAGER || "less"; 761 $self->{ PAGER } = "more" unless -x $self->{ PAGER }; 762 } 763 764 return $self->{ PAGER }; 765} 766 767 768# ---------------------------------------------------------------------- 769# help([$topic[, @args]]) 770# 771# Displays help. With $topic, it attempts to call $self->help_$topic, 772# which is expected to return a string. Without $topic, it lists the 773# available help topics, which is a list of methods that begin with 774# help_; these names are massaged with s/^help_// before being displayed. 775# ---------------------------------------------------------------------- 776sub help { 777 my ($self, $topic, @args) = @_; 778 my @ret; 779 780 if ($topic) { 781 if (my $sub = $self->can("help_$topic")) { 782 push @ret, $self->$sub(@_); 783 } 784 else { 785 push @ret, 786 "Sorry, no help available for `$topic'."; 787 } 788 } 789 790 else { 791 my @helps = $self->helps; 792 if (@helps) { 793 push @ret, 794 "Help is available for the following topics:", 795 "===========================================", 796 map({ " * $_" } @helps), 797 "==========================================="; 798 } 799 else { 800 my $me = $self->progname; 801 push @ret, "No help available for $me.", 802 "Please complain to the author!"; 803 } 804 } 805 806 return join "\n", @ret; 807} 808 809 810# ---------------------------------------------------------------------- 811# helps([@helps]) 812# 813# Returns or sets a list of possible help functions. 814# ---------------------------------------------------------------------- 815sub helps { 816 my $self = shift; 817 818 if (@_) { 819 $self->{ HELPS } = \@_; 820 } 821 822 return @{ $self->{ HELPS } }; 823} 824 825# ---------------------------------------------------------------------- 826# complete(@_) 827# 828# Command completion -- this method is designed to be assigned as: 829# 830# $term->Attribs->{completion_function} = sub { $self->complete(@_) }; 831# 832# Note the silly setup -- it will be called as a function, without 833# any references to $self, so we need to force $self into the equation 834# using a closure. 835# ---------------------------------------------------------------------- 836sub complete { 837 my ($self, $word, $line, $pos) = @_; 838 #warn "Completing '$word' in '$line' (pos $pos)"; 839 840 # This is grossly suboptimal, and only completes on 841 # defined keywords. A better idea is to: 842 # 1. If subtr($line, ' ') is less than $pos, 843 # then we are completing a command 844 # (the current method does this correctly) 845 # 2. Otherwise, we are completing something else. 846 # By default, this should defer to regular filename 847 # completion. 848 return grep { /$word/ } $self->completions; 849} 850 851sub completions { 852 my $self = shift; 853 854 if (@_) { 855 $self->{ COMPLETIONS } = \@_; 856 } 857 858 return @{ $self->{ COMPLETIONS } }; 859} 860 861# ---------------------------------------------------------------------- 862# _do_shell 863# 864# An example do_shell method. This can be used in subclasses like: 865# sub do_shell { shift->_do_shell(@_) } 866# ---------------------------------------------------------------------- 867sub _do_shell { 868 my ($self, @args) = @_; 869 my $sh = $SHELL || '/bin/sh'; 870 871 unless (system($sh, @args) == 0) { 872 carp "Problem executing $sh: $!"; 873 } 874 875 # No return value! 876 return; 877} 878 879# ---------------------------------------------------------------------- 880# An example predefined command: warranty. This also, 881# incidentally, fulfills the GPL recommended requirements. 882# ---------------------------------------------------------------------- 883sub do_warranty { 884 my $self = shift; 885 886 require Text::Wrap; 887 # To prevent "used only once" warnings. 888 local $Text::Wrap::columns = 889 $Text::Wrap::columns = $COLUMNS || '72'; 890 891 return Text::Wrap::wrap('', '', sprintf 892'Because %s is licensed free of charge, there is no warranty for the ' . 893'program, to the extent permitted by applicable law. Except when ' . 894'otherwise stated in writing the copyright holders and/or other parties ' . 895'provide the program "as is" without warranty of any kind, either ' . 896'expressed or implied, including, but not limited to, the implied ' . 897'warranties of merchantability and fitness for a particular purpose. ' . 898'The entire risk as to the quality and performance of the program is ' . 899'with you. Should the program prove defective, you assume the cost of ' . 900'all necessary servicing, repair or correction.', $self->progname); 901} 902 903# Helper function 904sub _merge_hash { 905 my ($merge_to, $merge_from) = @_; 906 $merge_to->{$_} = $merge_from->{$_} 907 for keys %$merge_from; 908} 909 910__END__ 911 912=head1 NAME 913 914Shell::Base - A generic class to build line-oriented command interpreters. 915 916=head1 SYNOPSIS 917 918 package My::Shell; 919 920 use Shell::Base; 921 use base qw(Shell::Base); 922 923 sub do_greeting { 924 return "Hello!" 925 } 926 927=head1 DESCRIPTION 928 929Shell::Base is a base class designed for building command line 930programs. It defines a number of useful defaults, simplifies adding 931commands and help, and integrates well with Term::ReadLine. 932 933After writing several REP (Read-Eval-Print) loops in Perl, I found 934myself wishing for something a little more convenient than starting 935with: 936 937 while(1) { 938 my $line = <STDIN>; 939 last unless defined $line; 940 941 chomp $line; 942 if ($line =~ /^... 943 944=head2 Features 945 946Shell::Base provides simple access to many of the things I always 947write into my REP's, as well as support for many thing that I always 948intend to, but never find time for: 949 950=over 4 951 952=item readline support 953 954Shell::Base provides simple access to the readline library via 955Term::ReadLine, including built-in tab-completion and easy integration 956with the history file features. 957 958If a subclass does want or need Term::ReadLine support, then it can be 959replaced in subclasses by overriding a few methods. See L<"Using 960Shell::Base Without readline">, below. 961 962=item Trivial to add commands 963 964Adding commands to your shell is as simple as creating methods: the 965command C<foo> is dispatched to C<do_foo>. In addition, there are 966hooks for unknown commands and for when the user just hits 967E<lt>ReturnE<gt>, both of which a subclass can override. 968 969=item Integrated help system 970 971Shell::Base makes it simple to integrate online help within alongside 972your command methods. Help for a command C<foo> can be retrieved with 973C<help foo>, with the addition of one method. In addition, a general 974C<help> command lists all possible help commands; this list is 975generated at run time, so there's no possibility of forgetting to add 976help methods to the list of available topics. 977 978=item Pager integration 979 980Output can be sent through the user's default pager (as defined by 981$ENV{'PAGER'}, with a reasonable default) or dumped directly to 982STDOUT. 983 984=item Customizable output stream(s) 985 986Printing is handled through a print() method, which can be overridden 987in a subclass to send output anywhere. 988 989=item Pre- and post-processing methods 990 991Input received from readline() can be processed before it is 992parsed, and output from command methods can be post-processed before 993it is sent to print(). 994 995=item Automatic support for RC files 996 997A simple RC-file parser is built in, which handles name = value type 998configuration files. This parser handles comments, whitespace, 999multiline definitions, boolean and (name, value) option types, and 1000multiple files (e.g., F</etc/foorc>, F<$HOME/.foorc>). 1001 1002=back 1003 1004Shell::Base was originally based, conceptually, on Python's C<cmd.Cmd> 1005class, though it has expanded far beyond what C<Cmd> offers. 1006 1007=head1 METHODS 1008 1009There are two basic types of methods: methods that control how a 1010Shell::Base-derived object behaves, and methods that add command to 1011the shell. 1012 1013All aspects of a Shell::Base-derived object are available via 1014accessors, from the Term::ReadLine instance to data members, to make 1015life easier for subclass implementors. 1016 1017I<NB:> The following list isn't really in any order! 1018 1019=over 4 1020 1021=item new 1022 1023The constructor is called C<new>, and should be inherited from 1024Shell::Base (and not overridden). C<new> should be called with a 1025reference to a hash of name => value parameters: 1026 1027 my %options = (HISTFILE => glob("~/.myshell_history"), 1028 OPTION_1 => $one, 1029 OPTION_2 => $two); 1030 1031 my $shell = My::Shell->new(\%options); 1032 1033C<new> calls a number of initializing methods, each of which will be 1034called with a reference to the passed in hash of parameters as the 1035only argument: 1036 1037=over 1038 1039=item init_rl(\%args) 1040 1041C<init_rl> initializes the Term::ReadLine instance. If a subclass 1042does not intend to use Term::ReadLine, this method can be overridden. 1043(There are other methods that need to be overridden to eliminate 1044readline completely; see L<"Using Shell::Base Without readline"> for 1045more details.) 1046 1047The completion method, C<complete>, is set here, though the list of 1048possible completions is generated in the C<init_completions> method. 1049 1050If a HISTFILE parameter is passed to C<init_rl>, then the internal 1051Term::ReadLine instance will attempt to use that file for history 1052functions. See L<Term::ReadLine::Gnu/"History Functions"> for more 1053details. 1054 1055=item init_rcfiles(\%args) 1056 1057C<init_rcfiles> treats each element in the RCFILES array (passed into 1058the contructor) as a configuration file, and attempts to read and 1059parse it. See L<"RC Files">, below. 1060 1061=item init_help(\%args) 1062 1063C<init_help> generates the list of available help topics, which is all 1064methods that match the pattern C<^help_>, by default. Once this list 1065is generated, it is stored using the C<helps> method (see L<"helps">). 1066 1067=item init_completions(\%args) 1068 1069C<init_completions> creates the list of methods that are 1070tab-completable, and sets them using the C<completions> method. By 1071default, it finds all methods that begin with C<^do_> in the current 1072class and superclass(es). 1073 1074The default completion method, C<complete>, chooses completions from 1075this list based on the line and word being completed. See 1076L<"complete">. 1077 1078=item init(\%args) 1079 1080A general purpose C<init> method, designed to be overridden by 1081subclasses. The default C<init> method in Shell::Base does nothing. 1082 1083In general, subclass-specific initializations should go in this 1084method. 1085 1086=back 1087 1088A subclass's C<init> method should be carful about deleting from the 1089hash that they get as a parameter -- items removed from the hash are 1090really gone. At the same time, items can be added to the hash, and 1091will persist. The original parameters can be retrieved at run time 1092using the C<args> method. 1093 1094Similarly, configuration data parsed from RCFILES can be retrieved 1095using the C<config> method. 1096 1097=item run 1098 1099The main "loop" of the program is a method called C<run> -- all other 1100methods are called in preparation for the call to C<run>, or are 1101called from within C<run>. C<run> takes no parameters, and does not 1102return. 1103 1104 $shell = My::Shell->new(); 1105 $shell->run(); 1106 1107At the top of the loop, C<run> prints the value of $self->intro, if it 1108is defined: 1109 1110 my $intro = $self->intro(); 1111 $self->print("$intro\n") 1112 if defined $intro; 1113 1114C<run> does several things for each iteration of the REP loop that are 1115worth noting: 1116 1117=over 4 1118 1119=item * 1120 1121Reads a line of input using $self->readline(), passing the value of 1122$self->prompt(): 1123 1124 $line = $self->readline($self->prompt); 1125 1126=item * 1127 1128Passes that line through $self->precmd(), for possible manipulation: 1129 1130 $line = $self->precmd($line); 1131 1132=item * 1133 1134Parses the line: 1135 1136 ($cmd, $env, @args) = $self->parseline($line); 1137 1138See L<"parseline"> for details about C<parseline>, and what $cmd, 1139$env, and @args are. 1140 1141=item * 1142 1143Update environment variables with entries from %$env, for the command 1144$cmd only. 1145 1146=item * 1147 1148Checks the contents of $cmd; there are a few special cases: 1149 1150=over 4 1151 1152=item * 1153 1154If $cmd matches $Shell::Base::RE_QUIT, the method C<quit> 1155is invoked: 1156 1157 $output = $self->quit(); 1158 1159$RE_QUIT is C<^(?i)\s*(quit|exit|logout)> by default 1160 1161=item * 1162 1163Otherwise, if $cmd matches $Shell::Base::RE_HELP, the method C<help> 1164is invoked, with @args as parameters: 1165 1166 $output = $self->help(@args); 1167 1168$RE_HELP is C<^(?i)\s*(help|\?)> by default. 1169 1170=item * 1171 1172Otherwise, if $cmd matches $Shell::Base::RE_SHEBANG, the method 1173C<do_shell> is invoked, with @args as parameters: 1174 1175 $output = $self->do_shell(@args); 1176 1177$RE_SHEBANG is C<^\s*!\s*$> by default. 1178 1179=item * 1180 1181Otherwise, the command C<do_$cmd> is invoked, with @args as 1182parameters: 1183 1184 my $method = "do_$cmd"; 1185 $output = $self->$method(@args); 1186 1187=back 1188 1189=item * 1190 1191$output is passed to $self->postcmd() for postprocessing: 1192 1193 $output = $self->postcmd($output); 1194 1195=item * 1196 1197Finally, if $output is not C<undef>, it is passed to $self->print(), 1198with a newline appended: 1199 1200 $self->print("$output\n") 1201 if defined $output; 1202 1203=back 1204 1205When the main loop ends, usually through the C<exit> or C<quit> 1206commands, or when the user issues CTRL-D, C<run> calls the C<quit> 1207method. 1208 1209=item args([$what]) 1210 1211The original hash of arguments passed into the constructor is stored 1212in the instance, and can be retrieved using the args method, which is 1213an accessor only (though the hash returned by C<args> is live, and 1214changes will propogate). 1215 1216If C<args> is passed a value, then the value associated with that key 1217will be returned. An example: 1218 1219 my $shell = My::Shell->new(FOO => "foo", BAR => "bar"); 1220 1221 my $foo = $shell->args("FOO"); # $foo contains "foo" 1222 my $bar = $shell->args("BAR"); # $bar contains "bar" 1223 my $baz = $shell->args("BAZ"); # $baz is undefined 1224 my $args = $shell->args(); # $args is a ref to the whole hash 1225 1226As a convenience, if a specified argument is not found, it is 1227uppercased, and then tried again, so: 1228 1229 my $foo = $shell->args("FOO"); 1230 1231and 1232 1233 my $foo = $shell->args("foo"); 1234 1235are identical if there is a C<FOO> arg and no C<foo> arg. 1236 1237=item config([$what]) 1238 1239Configuration data gleaned from RCFILES can be retrieved using the 1240C<config> method. C<config> behaves similarly to the C<args> method. 1241 1242=item helps 1243 1244When called without arguments, C<helps> returns a list of all the 1245available help_foo methods, as a list. 1246 1247When called with arguments, C<helps> uses these arguments to set the 1248current list of help methods. 1249 1250This is the method called by C<init_help> to fill in the list of 1251available help methods, and C<help> when it needs to figure out the 1252available help topics. 1253 1254=item completions 1255 1256Similar to C<helps>, except that completions returns or sets the list 1257of completions possible when the user hits E<lt>tabE<gt>. 1258 1259=item print 1260 1261The C<print> method, well, prints its data. C<print> is a method so 1262that subclasses can override it; here is a small example class, 1263C<Tied::Shell>, that wraps around a Tie::File instance, in which all 1264data is printed to the Tie::File instance, as well as to the normal 1265place. This makes it ideal for (e.g.) logging sessions: 1266 1267 package Tied::Shell; 1268 1269 use Shell::Base; 1270 use Tie::File; 1271 1272 use strict; 1273 use base qw(Shell::Base); 1274 1275 sub init { 1276 my ($self, $args) = @_; 1277 my @file; 1278 1279 tie @file, 'Tie::File', $args->{ FILENAME }; 1280 1281 $self->{ TIEFILE } = \@file; 1282 } 1283 1284 # Append to self, then call SUPER::print 1285 sub print { 1286 my ($self, @lines) = @_; 1287 push @{ $self->{ TIEFILE } }, @lines; 1288 1289 return $self->SUPER::print(@lines); 1290 } 1291 1292 sub quit { 1293 my $self = shift; 1294 untie @{ $self->{ TIEFILE } }; 1295 $self->SUPER::quit(@_); 1296 } 1297 1298(See L<Tie::File> for the appropriate details.) 1299 1300=item readline 1301 1302The C<readline> method is a wrapper for $self->term->readline; it is 1303called at the top of the REP loop within C<run> to get the next line 1304of input. C<readline> is it's own method so that subclasses which do 1305not use Term::ReadLine can override it specifically. A very basic, 1306non-readline C<readline> could look like: 1307 1308 sub readline { 1309 my ($self, $prompt) = @_; 1310 my $line; 1311 1312 print $prompt; 1313 chomp($line = <STDIN>); 1314 1315 return $line; 1316 } 1317 1318As implied by the example, C<readline> will be passed the prompt to be 1319displayed, which should be a string (it will be treated like one). 1320 1321A good example of when this might be overridden would be on systems 1322that prefer to use C<editline> instead of GNU readline, using the 1323C<Term::EditLine> module (e.g., NetBSD): 1324 1325 # Initialize Term::EditLine 1326 sub init_rl { 1327 my ($self, $args) = @_; 1328 1329 require Term::EditLine; 1330 $self->{ TERM } = Term::EditLine->new(ref $self); 1331 1332 return $self; 1333 } 1334 1335 # Return the Term::EditLine instance 1336 sub term { 1337 my $self = shift; 1338 return $self->{ TERM }; 1339 } 1340 1341 # Get a line of input 1342 sub readline { 1343 my ($self, $prompt) = @_; 1344 my $line; 1345 my $term = $self->term; 1346 1347 $term->set_prompt($prompt); 1348 $line = $term->gets(); 1349 $term->history_enter($line); 1350 1351 return $line; 1352 } 1353 1354=item default 1355 1356When an unknown command is received, the C<default> method is invoked, 1357with ($cmd, @args) as the arguments. The default C<default> method 1358simply returns an error string, but this can of course be overridden 1359in a subclass: 1360 1361 sub default { 1362 my ($self, @cmd) = @_; 1363 my $output = `@cmd`; 1364 chomp $output; # everything is printed with an extra "\n" 1365 return $output; 1366 } 1367 1368=item precmd 1369 1370C<precmd> is called after a line of input is read, but before it is 1371parsed. C<precmd> will be called with $line as the sole argument, and 1372it is expected to return a string suitable for splitting with 1373C<parseline>. Any amount of massaging can be done to $line, of 1374course. 1375 1376The default C<precmd> method does nothing: 1377 1378 sub precmd { 1379 my ($self, $line) = @_; 1380 return $line; 1381 } 1382 1383This would be a good place to handle things tilde-expansion: 1384 1385 sub precmd { 1386 my ($self, $line) = @_; 1387 $line =~ s{~([\w\d_-]*)} 1388 { $1 ? (getpwnam($1))[7] : $ENV{HOME} }e; 1389 return $line; 1390 } 1391 1392=item postcmd 1393 1394C<postcmd> is called immediately before any output is printed. 1395C<postcmd> will be passed a scalar containing the output of whatever 1396command C<run> invoked. C<postcmd> is expected to return a string 1397suitable for printing; if the return of C<postcmd> is undef, then 1398nothing will be printed. 1399 1400The default C<postcmd> method does nothing: 1401 1402 sub postcmd { 1403 my ($self, $output) = @_; 1404 return $output; 1405 } 1406 1407You can do fun output filtering here: 1408 1409 use Text::Bastardize; 1410 my $bastard = Text::Bastardize->new; 1411 sub postcmd { 1412 my ($self, $output) = @_; 1413 1414 $bastard->charge($output); 1415 1416 return $bastard->k3wlt0k() 1417 } 1418 1419Or translation: 1420 1421 use Text::Iconv; 1422 my $converter; 1423 sub postcmd { 1424 my ($self, $output) = @_; 1425 1426 unless (defined $converter) { 1427 # Read these values from the config files 1428 my $from_lang = $self->config("from_lang"); 1429 my $to_lang = $self->config("to_lang"); 1430 1431 $converter = Text::Iconv->new($from_lang, $to_lang); 1432 1433 # Return undef on error, don't croak 1434 $converter->raise_error(0); 1435 } 1436 1437 # Fall back to unconverted output, not croak 1438 return $completer->convert($output) || $output; 1439 } 1440 1441Or put the tildes back in: 1442 1443 sub postcmd { 1444 my ($self, $line) = @_; 1445 $line =~ s{(/home/([^/ ]+))} 1446 { -d $1 ? "~$2" : $1 }ge; 1447 return $line; 1448 } 1449 1450=item pager 1451 1452The C<pager> method attempts to determine what the user's preferred 1453pager is, and return it. This can be used within an overridden 1454C<print> method, for example, to send everything through a pager: 1455 1456 sub print { 1457 my ($self, @stuff) = @_; 1458 my $pager = $self->pager; 1459 1460 open my $P, "|$pager" or carp "Can't open $pager: $!"; 1461 CORE::print $P @stuff; 1462 close $P; 1463 } 1464 1465Note the explicit use of CORE::print, to prevent infinite recursion. 1466 1467=item parseline 1468 1469A line is divided into ($command, %env, @args) using 1470$self->parseline(). A command C<foo> is dispatched to a method 1471C<do_foo>, with @args passed as an array, and with %ENV updated to 1472include %env. 1473 1474If there is no C<do_foo> method for a command C<foo>, then the method 1475C<default> will be called. Subclasses can override the C<default> 1476method. 1477 1478%ENV is localized and updated with the contents of %env for the 1479current command. %env is populated in a similar fashion to how 1480F</bin/sh> does; the command: 1481 1482 FOO=bar baz 1483 1484Invokes the C<do_baz> method with $ENV{'FOO'} = "bar". 1485 1486Shell::Base doesn't (currently) do anything interesting with 1487pipelines; the command: 1488 1489 foo | bar 1490 1491will be parsed by parseline() as: 1492 1493 ("foo", {}, "|", "bar") 1494 1495rather than as two separate connected commands. Support for pipelines 1496in on the TODO list. 1497 1498=item prompt 1499 1500Gets or sets the current prompt. The default prompt is: 1501 1502 sprintf "(%s) \$ ", __PACKAGE__; 1503 1504The prompt method can be overridden, of course, possibly using 1505something like C<String::Format>: 1506 1507 use Cwd; 1508 use File::Basename qw(basename); 1509 use Net::Domain qw(hostfqdn); 1510 use String::Format qw(stringf); 1511 use Sys::Hostname qw(hostname); 1512 1513 sub prompt { 1514 my $self = shift; 1515 my $fmt = $self->{ PROMPT_FMT }; 1516 return stringf $fmt => { 1517 '$' => $$, 1518 'w' => cwd, 1519 'W' => basename(cwd), 1520 '0' => $self->progname, 1521 '!' => $self->prompt_no, 1522 'u' => scalar getpwuid($<), 1523 'g' => scalar getgrgid($(), 1524 'c' => ref($self), 1525 'h' => hostname, 1526 'H' => hostfqdn, 1527 }; 1528 } 1529 1530Then $self->{ PROMPT_FMT } can be set to, for example, C<%u@%h %w %%>, 1531which might yield a prompt like: 1532 1533 darren@tumbleweed /tmp/Shell-Base % 1534 1535(See L<String::Format> for the appropriate details.) 1536 1537The value passed to C<prompt> can be a code ref; if so, it is invoked 1538with $self and any additional arguments passed to C<prompt> as the 1539arguments: 1540 1541 $self->prompt(\&func, @stuff); 1542 1543Will call: 1544 1545 &$func($self, @stuff); 1546 1547and use the return value as the prompt string. 1548 1549=item intro / outro 1550 1551Text that is displayed when control enters C<run> (C<intro>) and 1552C<quit> (C<outro>). If the method returns a non-undef result, it will 1553be passed to $self->print(). 1554 1555=item quit 1556 1557The C<quit> method currently handles closing the history file; if it 1558is overridden, $self->SUPER::quit() should be called, so that the 1559history file will be written out. 1560 1561The results of $self->outro() will be passed to $self->print() as 1562well. 1563 1564=back 1565 1566=head2 Methods That Add Commands 1567 1568Any command that run() doesn't recognize will be treated as a command; 1569a method named C<do_$command> will be invoked, in an eval block. 1570Remember that a line is parsed into ($command, %env, @args); 1571C<do_$command> will be invoked with @args as @_, and %ENV updated to 1572include the contents of %env. The effect is similar to: 1573 1574 my ($command, $env, @args) = $self->parseline($line); 1575 my $method = "do_$command"; 1576 local %ENV = (%ENV, %$env); 1577 1578 my $output = $self->$method(@args); 1579 1580$output will be passed to $self->print() if it is defined. 1581 1582Here is method that implements the C<env> command: 1583 1584 sub do_env { 1585 my ($self, @args) = @_; 1586 my @output; 1587 1588 for (keys %ENV) { 1589 push @output, "$_=$ENV{$_}"; 1590 } 1591 1592 return join "\n", @output; 1593 } 1594 1595And here is an C<rm> command: 1596 1597 sub do_rm { 1598 my ($self, @files) = @_; 1599 my ($file, @errors); 1600 1601 for $file (@files) { 1602 unlink $file 1603 or push @errors, $file; 1604 } 1605 1606 if (@errors) { 1607 return "Couldn't delete " . join ", ", @errors; 1608 } 1609 1610 return; 1611 } 1612 1613=head1 MISCELLANEOUS 1614 1615=head2 Quick Imports 1616 1617If Shell::Base, or any Shell::Base subclass that does not does 1618implement an C<import> method, is invoked as: 1619 1620 use My::Shell qw(shell); 1621 1622a function named C<shell> is installed in the calling package. This 1623C<shell> function is very simple, and turns this: 1624 1625 shell(%args); 1626 1627into this: 1628 1629 My::Shell->new(%args)->run(); 1630 1631This is most useful for one-liners: 1632 1633 $ perl -MMy::Shell=shell -e shell 1634 1635=head2 RC Files 1636 1637The rcfile parser is simple, and parses (name, value) tuples from 1638config files, according to these rules: 1639 1640=over 4 1641 1642=item Definitions 1643 1644Most definitions are in name = value format: 1645 1646 foo = bar 1647 baz = quux 1648 1649Boolean defitions in the form 1650 1651 wiffle 1652 1653are allowed, and define C<wiffle> as 1. Any definition without an = 1654is considered a boolean definition. Boolean definitions in the form 1655C<I<no>wiffle> define C<wiffle> as 0: 1656 1657 nowiffle 1658 1659=item Comments 1660 1661Everything after a # is considered a comment, and is stripped from 1662the line immediately 1663 1664=item Whitespace 1665 1666Whitespace is (mostly) ignored. The following are equivalent: 1667 1668 foo=bar 1669 foo = bar 1670 1671Whitespace after the beginning of the value is I<not> ignored: 1672 1673 foo = bar baz quux 1674 1675C<foo> contains C<bar baz quux>. 1676 1677=item Line continuations 1678 1679Lines ending with \ are continued on the next line: 1680 1681 form_letter = Dear %s,\ 1682 How are you today? \ 1683 Love, \ 1684 %s 1685 1686=back 1687 1688=head2 Using Shell::Base Without readline 1689 1690The appropriate methods to override in this case are: 1691 1692=over 4 1693 1694=item init_rl 1695 1696The readline initialization method. 1697 1698=item term 1699 1700Returns the Term::ReadLine instance; primarily used by the other methods 1701listed in this section. 1702 1703=item readline 1704 1705Returns the next line of input. Will be passed 1 argument, the 1706prompt to display. See L<"readline"> for an example of overriding 1707C<readline>. 1708 1709=item print 1710 1711Called with the data to be printed. By default, this method prints 1712to $self->term->OUT, but subclasses that aren't using Term::ReadLine 1713will want to provide a useful alternative. One possibily might be: 1714 1715 sub print { 1716 my ($self, @print_me) = @_; 1717 CORE::print(@print_me); 1718 } 1719 1720Another good example was given above, in L<"pager">: 1721 1722 sub print { 1723 my ($self, @stuff) = @_; 1724 my $pager = $self->pager; 1725 1726 open my $P, "|$pager" or carp "Can't open $pager: $!"; 1727 CORE::print $P @stuff; 1728 close $P; 1729 } 1730 1731=back 1732 1733=head1 NOTES 1734 1735Some parts of this API will likely change in the future. In an 1736upcoming version, C<do_$foo> methods will mostly likely be expected to 1737return a ($status, $output) pair rather than simply $output. Any API 1738changes that are likely to break existing applications will be noted. 1739 1740=head1 TODO 1741 1742=over 4 1743 1744=item abbreviations 1745 1746Add abbreviation support, by default via Text::Abbrev, but 1747overriddable, so that a shell can have (for example), \x type 1748commands, or /x type commands. This can currently be done by 1749overriding the precmd() method or parseline() methods; for example, 1750this parseline() method strips a leading C</>, for IRC-like commands 1751(C</foo>, C</bar>) 1752 1753 sub parseline { 1754 my ($self, $line) = @_; 1755 my ($cmd, $env, @args) = $self->SUPER::parseline($line); 1756 1757 $cmd =~ s:^/::; 1758 return ($cmd, $env, @args); 1759 } 1760 1761Another way to implement abbreviations would be to override the 1762C<complete> method. 1763 1764=item command pipelines 1765 1766I have some ideas about how to implement pipelines, but, since I have 1767yet to look at the code in any existing shells, I might be completely 1768insane and totally on the wrong track. I therefore reserve the right 1769to not implement this feature now, until I've looked at how some 1770proper shells implement pipelines. 1771 1772=back 1773 1774=head1 AUTHOR 1775 1776darren chamberlain E<lt>darren@cpan.orgE<gt> 1777 1778=head1 REVISION 1779 1780This documentation describes C<Shell::Base>, $Revision: 1.5 $. 1781 1782=head1 COPYRIGHT 1783 1784Copyright (C) 2003 darren chamberlain. All Rights Reserved. 1785 1786This module is free software; you can redistribute it and/or 1787modify it under the same terms as Perl itself. 1788 1789