Add documentation/copyright
[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;
d9ba19d2 53
54__END__
55
56=head1 NAME
57
58Devel::REPL::Plugin::MultiLine::PPI - read lines until all blocks are closed
59
60=head1 SYNOPSIS
61
62 #!/usr/bin/perl
63
64 use lib './lib';
65 use Devel::REPL;
66
67 my $repl = Devel::REPL->new;
68 $repl->load_plugin('LexEnv');
69 $repl->load_plugin('History');
70 $repl->load_plugin('MultiLine::PPI');
71 $repl->run;
72
73=head1 DESCRIPTION
74
75Plugin that will collect lines until you have no unfinished structures. This
76lets you write subroutines, C<if> statements, loops, etc. more naturally.
77
78For example, without a MultiLine plugin,
79
80 $ my $x = 3;
81 3
82 $ if ($x == 3) {
83
84will throw a compile error, because that C<if> statement is incomplete. With a
85MultiLine plugin,
86
87 $ my $x = 3;
88 3
89 $ if ($x == 3) {
90
91 > print "OH NOES!"
92
93 > }
94 OH NOES
95 1
96
97you may write the code across multiple lines, such as in C<irb> and C<python>.
98
99This module uses L<PPI>. This plugin is named C<MultiLine::PPI> because someone
100else may conceivably implement similar behavior some other less
101dependency-heavy way.
102
103=head1 SEE ALSO
104
105C<Devel::REPL>
106
107=head1 AUTHOR
108
109Shawn M Moore, C<< <sartak at gmail dot com> >>
110
111=head1 COPYRIGHT AND LICENSE
112
113Copyright (C) 2007 by Shawn M Moore
114
115This library is free software; you can redistribute it and/or modify
116it under the same terms as Perl itself.
117
118=cut