Add LexEnv completion plugin. I still owe mst a refactor of the completion subsystem :)
[p5sagit/Devel-REPL.git] / lib / Devel / REPL / Plugin / Completion.pm
CommitLineData
e4ac8502 1package Devel::REPL::Plugin::Completion;
1989c3d2 2use Devel::REPL::Plugin;
3use Scalar::Util 'weaken';
4use PPI;
e4ac8502 5use namespace::clean -except => [ 'meta' ];
6
1989c3d2 7has current_matches => (
314f2293 8 is => 'rw',
9 isa => 'ArrayRef',
10 lazy => 1,
11 default => sub { [] },
1989c3d2 12);
ac71b56c 13
1989c3d2 14has match_index => (
314f2293 15 is => 'rw',
16 isa => 'Int',
17 lazy => 1,
18 default => sub { 0 },
1989c3d2 19);
e4ac8502 20
1989c3d2 21sub BEFORE_PLUGIN {
22 my ($self) = @_;
e4ac8502 23
1989c3d2 24 my $weakself = $self;
25 weaken($weakself);
ac71b56c 26
1989c3d2 27 $self->term->Attribs->{attempted_completion_function} = sub {
28 $weakself->_completion(@_);
29 };
e4ac8502 30}
31
1989c3d2 32sub _completion {
33 my ($self, $text, $line, $start, $end) = @_;
34
35 # we're discarding everything after the cursor for completion purposes
314f2293 36 # we can't just use $text because we want all the code before the cursor to
37 # matter, not just the current word
1989c3d2 38 substr($line, $end) = '';
39
40 my $document = PPI::Document->new(\$line);
41 return unless defined($document);
42
314f2293 43 $document->prune('PPI::Token::Whitespace');
44
1989c3d2 45 my @matches = $self->complete($text, $document);
ac71b56c 46
1989c3d2 47 # iterate through the completions
48 return $self->term->completion_matches($text, sub {
49 my ($text, $state) = @_;
50
51 if (!$state) {
52 $self->current_matches(\@matches);
53 $self->match_index(0);
54 }
55 else {
56 $self->match_index($self->match_index + 1);
ac71b56c 57 }
58
1989c3d2 59 return $self->current_matches->[$self->match_index];
60 });
61}
62
63sub complete {
64 return ();
65}
e4ac8502 66
671;
1989c3d2 68