File Coverage

blib/lib/Zoidberg/Fish/ReadLine.pm
Criterion Covered Total %
statement 15 123 12.2
branch 0 54 0.0
condition 0 25 0.0
subroutine 5 24 20.8
pod 2 7 28.5
total 22 233 9.4


line stmt bran cond sub pod time code
1             package Zoidberg::Fish::ReadLine;
2              
3             our $VERSION = '0.981';
4              
5 1     1   1177 use strict;
  1         3  
  1         44  
6 1     1   6 use vars qw/$AUTOLOAD $PS1 $PS2/;
  1         2  
  1         66  
7 1     1   4 use Zoidberg::Fish;
  1         3  
  1         23  
8             use Zoidberg::Utils
9 1     1   5 qw/:error message debug/; # T:RL:Zoid also has output()
  1         2  
  1         8  
10              
11             our @ISA = qw/Zoidberg::Fish/;
12              
13 1     1   937 eval 'use Env::PS1 qw/$PS1 $PS2 $RPS1/; 1'
  1         6156  
  1         8  
14             or eval 'use Env qw/$PS1 $PS2 $RPS1/; 1'
15             or ( our ($PS1, $PS2, $RPS1) = ("zoid-$Zoidberg::VERSION> ", "> ", undef) );
16              
17             sub init {
18 0     0 1   my $self = shift;
19              
20             # let's see what we have available
21 0 0 0       unless ($ENV{PERL_RL} and $ENV{PERL_RL} !~ /zoid/i) {
22 0           eval 'require Term::ReadLine::Zoid';
23 0 0         unless ($@) { # load RL zoid
24 0 0         $ENV{PERL_RL} = 'Zoid' unless defined $ENV{PERL_RL};
25 0           $ENV{PERL_RL} =~ /^(\S+)/;
26 0           push @ISA, 'Term::ReadLine::'.$1; # could be a subclass of T:RL:Zoid
27 0           $self->_init('zoid');
28 0           @$self{'rl', 'rl_z'} = ($self, 1);
29 0           $$self{config}{PS2} = \$PS2;
30 0           $$self{config}{RPS1} = \$RPS1;
31             # FIXME support RL:Z shell() option
32             # FIXME what if config/PS1 was allready set to a string ?
33             }
34             else {
35 0           debug $@;
36             }
37             }
38              
39 0 0         unless ($$self{rl_z}) { # load other RL
40 0           eval 'require Term::ReadLine';
41 0 0         error 'No ReadLine available' if $@;
42 0           $$self{rl} = Term::ReadLine->new('zoid');
43 0           $$self{rl_z} = 0;
44 0           message 'Using '.$$self{rl}->ReadLine(). " for input\n"
45             . 'we suggest you use Term::ReadLine::Zoid'; # officially nag-ware now :)
46 0 0         if ($$self{rl}->can('GetHistory')) {
47             *GetHistory = sub { # define more intelligent GetHistory
48 0     0     my @hist = $$self{rl}->GetHistory;
49 0           Zoidberg::Utils::output(\@hist);
50             }
51 0           }
52 0 0   0     else { *GetHistory = sub { return wantarray ? () : [] } }
  0            
53 0 0         if ($$self{rl}->can('SetHistory')) {
  0 0          
54             *SetHistory = sub { # define more intelligent SetHistory
55 0     0     my ($self, @hist) = @_;
56 0 0 0       @hist = @{$hist[0]} if @hist == 1 and ref $hist[0];
  0            
57 0           $$self{rl}->SetHistory(@hist);
58             }
59 0           }
60             elsif (my ($s) = grep {$$self{rl}->can($_)} qw/addhistory AddHistory/) {
61             *SetHistory = sub { # define more intelligent SetHistory
62 0     0     my ($self, @hist) = @_;
63 0 0 0       @hist = @{$hist[0]} if @hist == 1 and ref $hist[0];
  0            
64 0           $$self{rl}->$s($_) for @hist;
65             }
66 0           }
67             else {
68 0     0     *SetHistory = sub { undef };
  0            
69 0           $$self{no_real_hist}++;
70             }
71              
72 0 0         if (my ($s) = grep {$$self{rl}->can($_)} qw/addhistory AddHistory/) {
  0            
73 0     0     *AddHistory = sub { $$self{rl}->$s(@_) }
74 0           }
75 0     0     else { *AddHistory = sub {} }
  0            
76             }
77             else { *GetHistory = sub {
78 0     0     my $self = shift;
79 0           my $ref = $self->SUPER::GetHistory(@_); # force scalar context
80 0           Zoidberg::Utils::output($ref);
81 0           };
82             }
83            
84             ## hook history
85 0 0         unless ($$self{no_real_hist}) {
86 0           $self->SetHistory( $$self{shell}->builtin(qw/history --read/) );
87 0           $self->add_events('prompt', 'history_reset');
88 0           $$self{rl}->Attribs->{autohistory} = 0;
89             }
90              
91             ## completion
92 0 0         my $compl = $$self{rl_z} ? 'complete' : 'completion_function' ;
93             $$self{rl}->Attribs->{completion_function} = sub {
94 0     0     return $$self{shell}->builtin($compl, @_);
95 0           };
96              
97             ## Env::PS1
98 0 0 0 0     $Env::PS1::map{m} ||= sub { $$self{settings}{mode} || '-' };
  0            
99 0   0 0     $Env::PS1::map{j} ||= sub { scalar @{$$self{shell}{jobs}} };
  0            
  0            
100 0   0       $Env::PS1::map{v} ||= $Zoidberg::VERSION;
101             }
102              
103             sub wrap_rl {
104 0     0 0   my ($self, $prompt, $preput, $cont) = @_;
105 0 0 0       $prompt ||= $$self{rl_z} ? \$PS1 : $PS1;
106 0           my $line;
107             {
108 0 0         local $SIG{TSTP} = 'DEFAULT' unless $$self{shell}{settings}{login};
  0            
109 0           $line = $$self{rl}->readline($prompt, $preput);
110             }
111 0           $$self{last_line} = $line;
112 0           Zoidberg::Utils::output($line);
113             }
114              
115             sub wrap_rl_more {
116 0     0 0   my ($self, $prompt, $preput) = @_;
117 0           my $line;
118 0 0         if ($$self{rl_z}) { $line = $self->continue() }
  0            
119             else {
120 0 0 0       $prompt ||= $$self{rl_z} ? \$PS2 : $PS2;
121 0           $line = $$self{last_line} . $self->wrap_rl($prompt, $preput)
122             }
123 0           $$self{last_line} = $line;
124 0           Zoidberg::Utils::output($line);
125             }
126              
127             sub prompt { # log on prompt event
128 0     0 0   my $self = shift;
129 0           $self->AddHistory( $$self{shell}{previous_cmd} );
130             }
131              
132             sub beat {
133 0 0   0 0   $_[0]{shell}->reap_jobs() if $_[0]{settings}{notify};
134 0           $_[0]->broadcast('beat');
135             }
136              
137             sub select {
138 0     0 1   my ($self, @items) = @_;
139 0 0         @items = @{$items[0]} if ref $items[0];
  0            
140 0           my $len = length scalar @items;
141 0           Zoidberg::Utils::message(
142 0           [map { sprintf("%${len}u) ", $_ + 1) . $items[$_] } 0 .. $#items] );
143 0           SELECT_ASK:
144             my $re = $self->ask('#? ');
145 0 0         return undef unless $re;
146 0 0         unless ($re =~ /^\d+([,\s]+\d+)*$/) {
147 0           complain 'Invalid input: '.$re;
148 0           goto SELECT_ASK;
149             }
150 0           my @re = map $items[$_-1], split /\D+/, $re;
151 0 0 0       if (@re > 1 and ! wantarray) {
152 0           complain 'Please select just one item';
153 0           goto SELECT_ASK;
154             }
155 0           Zoidberg::Utils::output( @re );
156             }
157              
158             sub history_reset { # event exported by Log
159 0     0 0   my $self = shift;
160 0 0         unless ($$self{no_real_hist}) {
161 0           $self->SetHistory( $$self{shell}->builtin(qw/history --read/) );
162             }
163             }
164              
165             our $ERROR_CALLER;
166              
167             sub AUTOLOAD {
168 0     0     my $self = shift;
169 0           $AUTOLOAD =~ s/^.*:://;
170 0 0         return if $AUTOLOAD eq 'DESTROY';
171 0 0         if ( $$self{rl}->can( $AUTOLOAD ) ) { $$self{rl}->$AUTOLOAD(@_) }
  0            
172             else {
173 0           local $ERROR_CALLER = 1;
174 0           error "No such method Zoidberg::Fish::ReadLine::$AUTOLOAD()";
175             }
176             }
177              
178             1;
179              
180             __END__