File Coverage

blib/lib/Shell/Base.pm
Criterion Covered Total %
statement 176 257 68.4
branch 45 78 57.6
condition 14 31 45.1
subroutine 36 50 72.0
pod 24 34 70.5
total 295 450 65.5


line stmt bran cond sub pod time code
1             package 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
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              
13 21     21   9204185 use strict;
  21         54  
  21         1014  
14 21         2433 use vars qw( $VERSION $REVISION $PROMPT
15             $RE_QUIT $RE_HELP $RE_SHEBANG
16 21     21   2169 );
  21         51  
17              
18 21     21   117 use Carp qw(carp croak);
  21         41  
  21         2134  
19 21     21   31170 use Env qw($PAGER $SHELL $COLUMNS);
  21         2703179  
  21         143  
20 21     21   28650 use IO::File;
  21         1269230  
  21         4032  
21 21     21   230 use File::Basename qw(basename);
  21         47  
  21         2649  
22 21     21   23509 use Term::Size qw(chars);
  21         437819  
  21         1642  
23 21     21   20232 use Text::Shellwords qw(shellwords);
  21         61255  
  21         4062  
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             # ----------------------------------------------------------------------
47             sub import {
48 48     48   23234 my $class = shift;
49              
50 48 100 66     331 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 21     21   163 no strict qw(refs);
  21         49  
  21         19298  
64 10         20 my $caller = caller;
65 10         41 *{"$caller\::shell"} = sub {
66 0     0   0 $class->new(@_)->run();
67 10         42 };
68             }
69            
70 48 100       33673 $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             # ----------------------------------------------------------------------
104             sub new {
105 16     16 1 7546 my $class = shift;
106 16 100       151 my $args = UNIVERSAL::isa($_[0], 'HASH') ? shift : { @_ };
107              
108 16         283 my @size = chars();
109 16         241 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 16         91 $self->init_rl($args);
124 13         396 $self->init_rcfiles($args);
125 13         249 $self->init_completions($args);
126 13         340 $self->init_help($args);
127 13         556 $self->init($args);
128              
129 13         163 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             # ----------------------------------------------------------------------
140             sub init_rl {
141 16     16 1 38 my ($self, $args) = @_;
142 16         33 my ($term, $attr);
143              
144 16         17975 require Term::ReadLine;
145 16         67079 $self->term($term = Term::ReadLine->new(ref $self));
146              
147             # Setup default tab-completion function.
148 16         215 $attr = $term->Attribs;
149 16     0   452 $attr->{completion_function} = sub { $self->complete(@_) };
  0         0  
150              
151 16 100       156 if (my $histfile = $args->{ HISTFILE }) {
152 3         22 $self->histfile($histfile);
153 3         1295 $term->ReadHistory($histfile);
154             }
155              
156 13         187 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             # ----------------------------------------------------------------------
170             sub init_rcfiles {
171 13     13 1 889 my ($self, $args) = @_;
172 13         37 my (@rcfiles, $rcfile);
173              
174 13 100       92 return unless defined $args->{ RCFILES };
175              
176             # Ensure we have an array
177             $args->{ RCFILES } = [ $args->{ RCFILES } ]
178 1 50       5 unless ref($args->{ RCFILES }) eq 'ARRAY';
179              
180 1         2 @rcfiles = @{ $args->{ RCFILES } };
  1         12  
181              
182 1         5 for $rcfile (@rcfiles) {
183             _merge_hash($self->{ CONFIG },
184 1         6 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             # ----------------------------------------------------------------------
195             sub parse_rcfile {
196 2     2 0 785 my ($self, $rcfile) = @_;
197 2         5 my %config = ();
198              
199 2         7 my $buffer = "";
200 2 50       35 my $rc = IO::File->new($rcfile)
201             or next;
202              
203 2         330 while (defined(my $line = <$rc>)) {
204 48         62 chomp $line;
205 48         108 $line =~ s/#.*$//;
206              
207 48 100 66     123 if (length $buffer && length $line) {
208 4         8 $line = $buffer . $line;
209             }
210              
211             # Line continuation
212 48 100       100 if ($line =~ s/\\$//) {
213 4         6 $buffer = $line;
214 4         12 next;
215             } else {
216 44         61 $buffer = '';
217             }
218              
219 44 100       140 next unless length $line;
220              
221 14         97 my ($name, $value) = $line =~ /^\s*(.*?)\s*(?:=>?\s*(.*))?$/;
222 14         25 $name = lc $name;
223 14 100       33 unless (defined $value) {
224 2 100       12 if ($name =~ s/^no//) {
225 1         1 $value = 0;
226             }
227             else {
228 1         2 $value = 1;
229             }
230             }
231 14         73 $config{ $name } = $value;
232             }
233              
234 2 100       49 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             # ----------------------------------------------------------------------
246             sub init_help {
247 14     14 1 1665 my $self = shift;
248 14   33     91 my $class = ref $self || $self;
249 14         38 my %uniq = ();
250              
251 21     21   417 no strict qw(refs);
  21         51  
  21         3785  
252 15         123 $self->helps(
253 15         91 grep { ++$uniq{$_} == 1 }
254 15         48 map { s/^help_//; $_ }
  3         285  
255             grep /^help_/,
256 3         7 map({ %{"$_\::"} } @{"$class\::ISA"}),
  14         66  
  14         764  
257 14         39 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             # ----------------------------------------------------------------------
269             sub init_completions {
270 13     13 1 54 my $self = shift;
271 13   33     104 my $class = ref $self || $self;
272 13         53 my %uniq = ();
273              
274 21     21   115 no strict qw(refs);
  21         33  
  21         59728  
275 26         494 $self->completions(
276             sort
277             "help",
278 26         142 grep { ++$uniq{$_} == 1 }
279 26         104 map { s/^do_//; $_ }
  3         1483  
280             grep /^do_/,
281 3         6 map({ %{"$_\::"} } @{"$class\::ISA"}),
  13         232  
  13         1895  
282 13         39 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             # ----------------------------------------------------------------------
297             sub init {
298 13     13 1 34 my ($self, $args) = @_;
299              
300 13         29 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             # ----------------------------------------------------------------------
344             sub run {
345 0     0 1 0 my $self = shift;
346 0         0 my ($prompt, $blurb);
347              
348 0         0 $prompt = $self->prompt;
349 0         0 $blurb = $self->intro;
350              
351            
352 0 0       0 if (defined $blurb) {
353 0         0 chomp $blurb;
354 0         0 $self->print("$blurb\n");
355             }
356              
357 0         0 while (defined (my $line = $self->readline($prompt))) {
358 0         0 my (@args, $cmd, $env, $output);
359              
360 0         0 $line = $self->precmd($line);
361              
362 0         0 ($cmd, $env, @args) = $self->parseline($line);
363 0         0 local %ENV = (%ENV, %$env);
364              
365 0 0       0 if (! length($cmd)) {
    0          
    0          
366 0         0 $output = $self->emptycommand();
367             }
368             elsif ($cmd =~ /$RE_HELP/) {
369 0         0 $output = $self->help(@args);
370             }
371             elsif ($cmd =~ /$RE_QUIT/) {
372 0         0 $self->quit;
373             }
374             else {
375 0 0       0 if ($cmd =~ /$RE_SHEBANG/) {
376 0         0 $cmd = "shell";
377             }
378 0         0 eval {
379 0         0 my $meth = "do_$cmd";
380 0         0 $output = $self->$meth(@args);
381             };
382 0 0       0 if ($@) {
383 0         0 $output = sprintf "%s: Bad command or filename", $self->progname;
384 0         0 my $err = $@;
385 0         0 chomp $err;
386 0         0 warn "$output ($err)\n";
387 0         0 eval {
388 0         0 $output = $self->default($cmd, @args);
389             };
390             }
391             }
392              
393 0         0 $output = $self->postcmd($output);
394 0         0 $output =~ s/\n*$//;
395              
396 0         0 chomp $output;
397 0 0       0 $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 0         0 $prompt = $self->prompt();
402             }
403              
404 0         0 $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             # ----------------------------------------------------------------------
416             sub readline {
417 0     0 1 0 my ($self, $prompt) = @_;
418 0         0 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             # ----------------------------------------------------------------------
430             sub print {
431 0     0 1 0 my ($self, @stuff) = @_;
432 0         0 my $OUT = $self->term->Attribs->{'outstream'};
433              
434 0         0 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             # ----------------------------------------------------------------------
445             sub quit {
446 0     0 1 0 my ($self, $status) = @_;
447 0 0       0 $status = 0 unless defined $status;
448              
449 0         0 my $blurb = $self->outro();
450 0 0       0 $self->print("$blurb\n") if defined $blurb;
451              
452 0 0       0 if (my $h = $self->histfile) {
453             # XXX Can this be better encapsulated?
454 0         0 $self->term->WriteHistory($h);
455             }
456              
457 0         0 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             # ----------------------------------------------------------------------
471             sub precmd {
472 1     1 1 445 my ($self, $line) = @_;
473 1         8 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             # ----------------------------------------------------------------------
485             sub postcmd {
486 1     1 1 2 my ($self, $output) = @_;
487 1         7 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             # ----------------------------------------------------------------------
497             sub default {
498 2     2 1 507 my ($self, $cmd, @args) = @_;
499 2   33     11 my $class = ref $self || $self;
500 2         16 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             # ----------------------------------------------------------------------
508             sub emptycommand {
509 0     0 0 0 my $self = shift;
510 0         0 return;
511             }
512              
513             # ----------------------------------------------------------------------
514             # prompt_no()
515             #
516             # Returns the command number in the history.
517             #
518             # Tests: t/prompt_no.t
519             # ----------------------------------------------------------------------
520             sub prompt_no {
521 0     0 0 0 my $self = shift;
522 0         0 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             # ----------------------------------------------------------------------
535             sub version {
536 2     2 0 642 return $VERSION;
537             }
538              
539             # ----------------------------------------------------------------------
540             # do_version()
541             #
542             # Example command method.
543             #
544             # Tests: t/version.t
545             # ----------------------------------------------------------------------
546             sub do_version {
547 1     1 0 358 my $self = shift;
548 1         6 return sprintf "%s v%s", $self->progname, $self->version;
549             }
550              
551             sub help_version {
552 1     1 0 8 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             # ----------------------------------------------------------------------
563             sub progname {
564 6     6 0 1937 my $self = shift;
565 6   33     316 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             # ----------------------------------------------------------------------
585             sub intro {
586             # No default intro
587 0     0 1 0 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             # ----------------------------------------------------------------------
598             sub outro {
599 0     0 1 0 my $self = shift;
600 0         0 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             # ----------------------------------------------------------------------
630             sub parseline {
631 5     5 1 4038 my ($self, $line) = @_;
632 5         5 my ($cmd, %env, @args);
633              
634 5         13 @args = shellwords($line);
635 5         540 %env = ();
636              
637 5         11 while (@args) {
638 7 100       16 if ($args[0] =~ /=/) {
639 2         8 my ($n, $v) = split /=/, shift(@args), 2;
640 2   50     9 $env{$n} = $v || "";
641             }
642             else {
643 5         5 $cmd = shift @args;
644 5         7 last;
645             }
646             }
647              
648 5   50     27 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             # ----------------------------------------------------------------------
663             sub args {
664 23     23 1 6591 my $self = shift;
665 23 100       69 if (@_) {
666             return $self->{ ARGS }->{ $_[0] }
667 21   66     198 || $self->{ ARGS }->{ uc $_[0] };
668             }
669 2         32 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             # ----------------------------------------------------------------------
680             sub config {
681 10     10 1 1550 my $self = shift;
682 10 50       25 if (@_) {
683 10         81 return $self->{ CONFIG }->{ $_[0] };
684             }
685 0         0 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             # ----------------------------------------------------------------------
697             sub term {
698 17     17 1 404072 my $self = shift;
699 17 100       605 $self->{ TERM } = shift if (@_);
700 17         348 return $self->{ TERM };
701             }
702              
703             # ----------------------------------------------------------------------
704             # histfile([$histfile])
705             #
706             # Gets/set the history file.
707             #
708             # Tests: t/histfile.t
709             # ----------------------------------------------------------------------
710             sub histfile {
711 3     3 0 14 my $self = shift;
712 3 50       909 $self->{ HISTFILE } = shift if (@_);
713 3         13 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             # ----------------------------------------------------------------------
729             sub prompt {
730 6     6 1 21 my $self = shift;
731 6 100       25 if (@_) {
732 2         6 my $p = shift;
733 2 100       12 if (ref($p) eq 'CODE') {
734 1         7 $self->{ PROMPT } = &$p($self, @_);
735             }
736             else {
737 1         5 $self->{ PROMPT } = $p;
738             }
739             }
740 6         70 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             # ----------------------------------------------------------------------
752             sub pager {
753 4     4 1 16 my $self = shift;
754              
755 4 100       14 if (@_) {
756 1         2 $self->{ PAGER } = shift;
757             }
758              
759 4 100       92 unless (defined $self->{ PAGER }) {
760 3   100     60 $self->{ PAGER } = $PAGER || "less";
761 3 50       157 $self->{ PAGER } = "more" unless -x $self->{ PAGER };
762             }
763              
764 4         45 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             # ----------------------------------------------------------------------
776             sub help {
777 0     0 1 0 my ($self, $topic, @args) = @_;
778 0         0 my @ret;
779              
780 0 0       0 if ($topic) {
781 0 0       0 if (my $sub = $self->can("help_$topic")) {
782 0         0 push @ret, $self->$sub(@_);
783             }
784             else {
785 0         0 push @ret,
786             "Sorry, no help available for `$topic'.";
787             }
788             }
789              
790             else {
791 0         0 my @helps = $self->helps;
792 0 0       0 if (@helps) {
793 0         0 push @ret,
794             "Help is available for the following topics:",
795             "===========================================",
796 0         0 map({ " * $_" } @helps),
797             "===========================================";
798             }
799             else {
800 0         0 my $me = $self->progname;
801 0         0 push @ret, "No help available for $me.",
802             "Please complain to the author!";
803             }
804             }
805              
806 0         0 return join "\n", @ret;
807             }
808              
809              
810             # ----------------------------------------------------------------------
811             # helps([@helps])
812             #
813             # Returns or sets a list of possible help functions.
814             # ----------------------------------------------------------------------
815             sub helps {
816 16     16 1 48 my $self = shift;
817              
818 16 100       340 if (@_) {
819 14         76 $self->{ HELPS } = \@_;
820             }
821              
822 16         31 return @{ $self->{ HELPS } };
  16         88  
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             # ----------------------------------------------------------------------
836             sub complete {
837 0     0 0 0 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 0         0 return grep { /$word/ } $self->completions;
  0         0  
849             }
850              
851             sub completions {
852 14     14 1 50 my $self = shift;
853              
854 14 100       96 if (@_) {
855 13         48 $self->{ COMPLETIONS } = \@_;
856             }
857              
858 14         30 return @{ $self->{ COMPLETIONS } };
  14         289  
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             # ----------------------------------------------------------------------
867             sub _do_shell {
868 0     0   0 my ($self, @args) = @_;
869 0   0     0 my $sh = $SHELL || '/bin/sh';
870              
871 0 0       0 unless (system($sh, @args) == 0) {
872 0         0 carp "Problem executing $sh: $!";
873             }
874              
875             # No return value!
876 0         0 return;
877             }
878              
879             # ----------------------------------------------------------------------
880             # An example predefined command: warranty. This also,
881             # incidentally, fulfills the GPL recommended requirements.
882             # ----------------------------------------------------------------------
883             sub do_warranty {
884 0     0 0 0 my $self = shift;
885              
886 0         0 require Text::Wrap;
887             # To prevent "used only once" warnings.
888 0   0     0 local $Text::Wrap::columns =
889             $Text::Wrap::columns = $COLUMNS || '72';
890              
891 0         0 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
904             sub _merge_hash {
905 1     1   3 my ($merge_to, $merge_from) = @_;
906             $merge_to->{$_} = $merge_from->{$_}
907 1         21 for keys %$merge_from;
908             }
909              
910             __END__