Commit | Line | Data |
e4ac8502 |
1 | package Devel::REPL::Plugin::Completion; |
1989c3d2 |
2 | use Devel::REPL::Plugin; |
3 | use Scalar::Util 'weaken'; |
4 | use PPI; |
e4ac8502 |
5 | use namespace::clean -except => [ 'meta' ]; |
6 | |
1989c3d2 |
7 | has current_matches => ( |
8 | is => 'rw', |
9 | isa => 'ArrayRef', |
10 | lazy => 1, |
11 | default => sub { [] }, |
12 | ); |
ac71b56c |
13 | |
1989c3d2 |
14 | has match_index => ( |
15 | is => 'rw', |
16 | isa => 'Int', |
17 | lazy => 1, |
18 | default => sub { 0 }, |
19 | ); |
e4ac8502 |
20 | |
1989c3d2 |
21 | sub 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 |
32 | sub _completion { |
33 | my ($self, $text, $line, $start, $end) = @_; |
34 | |
35 | # we're discarding everything after the cursor for completion purposes |
36 | substr($line, $end) = ''; |
37 | |
38 | my $document = PPI::Document->new(\$line); |
39 | return unless defined($document); |
40 | |
41 | my @matches = $self->complete($text, $document); |
ac71b56c |
42 | |
1989c3d2 |
43 | # iterate through the completions |
44 | return $self->term->completion_matches($text, sub { |
45 | my ($text, $state) = @_; |
46 | |
47 | if (!$state) { |
48 | $self->current_matches(\@matches); |
49 | $self->match_index(0); |
50 | } |
51 | else { |
52 | $self->match_index($self->match_index + 1); |
ac71b56c |
53 | } |
54 | |
1989c3d2 |
55 | return $self->current_matches->[$self->match_index]; |
56 | }); |
57 | } |
58 | |
59 | sub complete { |
60 | return (); |
61 | } |
e4ac8502 |
62 | |
63 | 1; |
1989c3d2 |
64 | |