3 package Devel::REPL::Plugin::MultiLine::PPI;
4 # ABSTRACT: Read lines until all blocks are closed
6 our $VERSION = '1.003027';
8 use Devel::REPL::Plugin;
10 use namespace::autoclean;
12 has 'continuation_prompt' => (
15 default => sub { '> ' }
24 around 'read' => sub {
26 my ($self, @args) = @_;
27 my $line = $self->$orig(@args);
30 return $self->continue_reading_if_necessary($line, @args);
36 sub continue_reading_if_necessary {
37 my ( $self, $line, @args ) = @_;
39 while ($self->line_needs_continuation($line)) {
40 my $orig_prompt = $self->prompt;
41 $self->prompt($self->continuation_prompt);
43 $self->line_depth($self->line_depth + 1);
44 my $append = $self->read(@args);
45 $self->line_depth($self->line_depth - 1);
47 $line .= "\n$append" if defined($append);
49 $self->prompt($orig_prompt);
51 # ^D means "shut up and eval already"
52 return $line if !defined($append);
58 sub line_needs_continuation
63 # add this so we can test whether the document ends in PPI::Statement::Null
66 my $document = PPI::Document->new(\$line);
67 return 0 if !defined($document);
69 # adding ";" to a complete document adds a PPI::Statement::Null. we added a ;;
70 # so if it doesn't end in null then there's probably something that's
72 return 0 if $document->child(-1)->isa('PPI::Statement::Null');
74 # this could use more logic, such as returning 1 on s/foo/ba<Enter>
75 my $unfinished_structure = sub
77 my ($document, $element) = @_;
78 return 0 unless $element->isa('PPI::Structure');
79 return 1 unless $element->finish;
83 return $document->find_any($unfinished_structure);
96 my $repl = Devel::REPL->new;
97 $repl->load_plugin('LexEnv');
98 $repl->load_plugin('History');
99 $repl->load_plugin('MultiLine::PPI');
104 Plugin that will collect lines until you have no unfinished structures. This
105 lets you write subroutines, C<if> statements, loops, etc. more naturally.
107 For example, without a MultiLine plugin,
113 will throw a compile error, because that C<if> statement is incomplete. With a
126 you may write the code across multiple lines, such as in C<irb> and C<python>.
128 This module uses L<PPI>. This plugin is named C<MultiLine::PPI> because someone
129 else may conceivably implement similar behavior some other less
130 dependency-heavy way.
138 Shawn M Moore, C<< <sartak at gmail dot com> >>
140 =head1 COPYRIGHT AND LICENSE
142 Copyright (C) 2007 by Shawn M Moore
144 This library is free software; you can redistribute it and/or modify
145 it under the same terms as Perl itself.