make "perl -c script/re.pl" not start up the REPL
[p5sagit/Devel-REPL.git] / lib / Devel / REPL / Plugin / History.pm
1 use strict;
2 use warnings;
3 package Devel::REPL::Plugin::History;
4
5 use Devel::REPL::Plugin;
6 use namespace::autoclean;
7
8 has 'history' => (
9    isa => 'ArrayRef', is => 'rw',
10    lazy => 1,
11    default => sub { [] }
12 );
13
14 # lazy so ReadLineHistory Plugin can set this
15 has 'have_readline_history' => (
16    is => 'rw',
17    lazy => 1,
18    default => sub { 0 }
19 );
20
21 sub push_history {
22    my ($self, $line) = @_;
23    # Push history is not needed if we have Term::ReadLine
24    # support.  We put the test inside push_history() in case
25    # someone has modified it in their code.
26    if ($self->have_readline_history) {
27       # update history to keep consistent with Term::ReadLine
28       $self->history( [ $self->term->GetHistory ] );
29    } else {
30       # not used with Term::ReadLine history support
31       push(@{$self->history}, $line);
32    }
33 }
34
35 around 'read' => sub {
36    my $orig = shift;
37    my ($self, @args) = @_;
38    my $line = $self->$orig(@args);
39    if (defined $line) {
40       if ($line =~ m/^!(.*)$/) {
41          my $call = $1;
42          $line = $self->history_call($call);
43          if (defined $line) {
44             $self->print($line."\n");
45          } else {
46             return "'Unable to find ${call} in history'";
47          }
48       }
49       if ($line =~ m/\S/) {
50          $self->push_history($line);
51       }
52    }
53    return $line;
54 };
55
56 sub history_call {
57    my ($self, $call) = @_;
58    if ($call =~ m/^(-?\d+)$/) { # handle !1 or !-1
59       my $idx = $1;
60       $idx-- if ($idx > 0); # !1 gets history element 0
61       my $line = $self->history->[$idx];
62       return $line;
63    }
64    my $re = qr/^\Q${call}\E/;
65    foreach my $line (reverse @{$self->history}) {
66       return $line if ($line =~ $re);
67    }
68    return;
69 };
70
71 1;
72
73 __END__
74
75 =head1 NAME
76
77 Devel::REPL::Plugin::History - Keep track of all input, provide shortcuts !1, !-1
78
79 =cut
80