r61423@onn: sartak | 2008-06-02 16:00:33 -0400
[p5sagit/Devel-REPL.git] / lib / Devel / REPL / Plugin / History.pm
1 package Devel::REPL::Plugin::History;
2
3 use Devel::REPL::Plugin;
4 use namespace::clean -except => [ 'meta' ];
5
6 has 'history' => (
7   isa => 'ArrayRef', is => 'rw', required => 1, lazy => 1,
8   default => sub { [] }
9 );
10
11 sub push_history {
12   my ($self, $line) = @_;
13   push(@{$self->history}, $line);
14 }
15
16 around 'read' => sub {
17   my $orig = shift;
18   my ($self, @args) = @_;
19   my $line = $self->$orig(@args);
20   if (defined $line) {
21     if ($line =~ m/^!(.*)$/) {
22       my $call = $1;
23       $line = $self->history_call($call);
24       if (defined $line) {
25         $self->print($line."\n");
26       } else {
27         return "'Unable to find ${call} in history'";
28       }
29     }
30     if ($line =~ m/\S/) {
31       $self->push_history($line);
32     }
33   }
34   return $line;
35 };
36
37 sub history_call {
38   my ($self, $call) = @_;
39   if ($call =~ m/^(-?\d+)$/) { # handle !1 or !-1
40     my $idx = $1;
41     $idx-- if ($idx > 0); # !1 gets history element 0
42     my $line = $self->history->[$idx];
43     return $line;
44   }
45   my $re = qr/^\Q${call}\E/;
46   foreach my $line (reverse @{$self->history}) {
47     return $line if ($line =~ $re);
48   }
49   return;
50 };
51
52 1;
53
54 __END__
55
56 =head1 NAME
57
58 Devel::REPL::Plugin::History - Keep track of all input, provide shortcuts !1, !-1
59
60 =cut
61