X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=p5sagit%2FDevel-REPL.git;a=blobdiff_plain;f=lib%2FDevel%2FREPL%2FPlugin%2FMultiLine%2FPPI.pm;fp=lib%2FDevel%2FREPL%2FPlugin%2FMultiLine%2FPPI.pm;h=177484f2b7263053cb9056126f142d56cf589051;hp=0000000000000000000000000000000000000000;hb=9cdb543b6b32b570d8e2fb5cd1a69673fc378a92;hpb=fb1f68748abc529c6ebb39708316ad6954d32d7b diff --git a/lib/Devel/REPL/Plugin/MultiLine/PPI.pm b/lib/Devel/REPL/Plugin/MultiLine/PPI.pm new file mode 100644 index 0000000..177484f --- /dev/null +++ b/lib/Devel/REPL/Plugin/MultiLine/PPI.pm @@ -0,0 +1,52 @@ +package Devel::REPL::Plugin::MultiLine::PPI; + +use Moose::Role; +use PPI; +use namespace::clean -except => [ 'meta' ]; + +has 'continuation_prompt' => ( + is => 'rw', required => 1, lazy => 1, + default => sub { '> ' } +); + +around 'read' => sub { + my $orig = shift; + my ($self, @args) = @_; + my $line = $self->$orig(@args); + + if (defined $line) { + while (needs_continuation($line)) { + my $orig_prompt = $self->prompt; + $self->prompt($self->continuation_prompt); + + my $append = $self->read(@args); + $line .= $append if defined($append); + + $self->prompt($orig_prompt); + + # ^D means "shut up and eval already" + return $line if !defined($append); + } + } + return $line; +}; + +sub needs_continuation +{ + my $line = shift; + my $document = PPI::Document->new(\$line); + return 0 if !defined($document); + + # this could use more logic, such as returning 1 on s/foo/ba + my $unfinished_structure = sub + { + my ($document, $element) = @_; + return 0 unless $element->isa('PPI::Structure'); + return 1 unless $element->start && $element->finish; + return 0; + }; + + return $document->find_any($unfinished_structure); +} + +1;