1c51efbc7d063d2f20e5204cd634124fe3d6ff30
[p5sagit/Devel-REPL.git] / lib / Devel / REPL / Plugin / History.pm
1 package Devel::REPL::Plugin::History;
2
3 use Moose::Role;
4
5 has 'history' => (
6   isa => 'ArrayRef', is => 'rw', required => 1, lazy => 1,
7   default => sub { [] }
8 );
9
10 sub push_history {
11   my ($self, $line) = @_;
12   push(@{$self->history}, $line);
13 }
14
15 around 'read' => sub {
16   my $orig = shift;
17   my ($self, @args) = @_;
18   my $line = $self->$orig(@args);
19   if (defined $line) {
20     if ($line =~ m/^!(.*)$/) {
21       my $call = $1;
22       $line = $self->history_call($call);
23       if (defined $line) {
24         $self->print($line."\n");
25       } else {
26         return "'Unable to find ${call} in history'";
27       }
28     }
29     if ($line =~ m/\S/) {
30       $self->push_history($line);
31     }
32   }
33   return $line;
34 };
35
36 sub history_call {
37   my ($self, $call) = @_;
38   if ($call =~ m/^(-?\d+)$/) { # handle !1 or !-1
39     my $idx = $1;
40     $idx-- if ($idx > 0); # !1 gets history element 0
41     my $line = $self->history->[$idx];
42     return $line;
43   }
44   my $re = qr/^\Q${call}\E/;
45   foreach my $line (reverse @{$self->history}) {
46     return $line if ($line =~ $re);
47   }
48   return;
49 };
50
51 1;