Add Devel::REPL::Plugin::MutliLine::PPI
[p5sagit/Devel-REPL.git] / lib / Devel / REPL / Plugin / MultiLine / PPI.pm
CommitLineData
9cdb543b 1package Devel::REPL::Plugin::MultiLine::PPI;
2
3use Moose::Role;
4use PPI;
5use namespace::clean -except => [ 'meta' ];
6
7has 'continuation_prompt' => (
8 is => 'rw', required => 1, lazy => 1,
9 default => sub { '> ' }
10);
11
12around 'read' => sub {
13 my $orig = shift;
14 my ($self, @args) = @_;
15 my $line = $self->$orig(@args);
16
17 if (defined $line) {
18 while (needs_continuation($line)) {
19 my $orig_prompt = $self->prompt;
20 $self->prompt($self->continuation_prompt);
21
22 my $append = $self->read(@args);
23 $line .= $append if defined($append);
24
25 $self->prompt($orig_prompt);
26
27 # ^D means "shut up and eval already"
28 return $line if !defined($append);
29 }
30 }
31 return $line;
32};
33
34sub needs_continuation
35{
36 my $line = shift;
37 my $document = PPI::Document->new(\$line);
38 return 0 if !defined($document);
39
40 # this could use more logic, such as returning 1 on s/foo/ba<Enter>
41 my $unfinished_structure = sub
42 {
43 my ($document, $element) = @_;
44 return 0 unless $element->isa('PPI::Structure');
45 return 1 unless $element->start && $element->finish;
46 return 0;
47 };
48
49 return $document->find_any($unfinished_structure);
50}
51
521;