make plugins be M::I features so dependencies are optional
[p5sagit/Devel-REPL.git] / lib / Devel / REPL / Plugin / CompletionDriver / Methods.pm
1 package Devel::REPL::Plugin::CompletionDriver::Methods;
2 use Devel::REPL::Plugin;
3 use namespace::clean -except => [ 'meta' ];
4
5 sub BEFORE_PLUGIN {
6     my $self = shift;
7     for (qw/Completion FindVariable/) {
8         $self->load_plugin($_);
9     }
10 }
11
12 around complete => sub {
13   my $orig = shift;
14   my ($self, $text, $document) = @_;
15
16   my $last = $self->last_ppi_element($document);
17   my $incomplete = '';
18
19   # handle an incomplete method name, and back up to the ->
20   if ($last->isa('PPI::Token::Word')) {
21       my $previous = $last->sprevious_sibling
22         or return $orig->(@_);
23       $previous->isa('PPI::Token::Operator') && $previous->content eq '->'
24         or return $orig->(@_);
25       $incomplete = $last->content;
26       $last = $previous;
27   }
28
29   # require a -> here
30   return $orig->(@_)
31     unless $last->isa('PPI::Token::Operator')
32         && $last->content eq '->';
33
34   # ..which is preceded by a word (class name)
35   my $previous = $last->sprevious_sibling
36     or return $orig->(@_);
37   $previous->isa('PPI::Token::Word') || $previous->isa('PPI::Token::Symbol')
38     or return $orig->(@_);
39   my $class;
40
41   # we have a variable, need to look up its class
42   if ($previous->isa('PPI::Token::Symbol')) {
43     my $object_ref = $self->find_variable($previous->content)
44       or return $orig->(@_);
45     $class = blessed($$object_ref)
46       or return $orig->(@_);
47   }
48   else  {
49     $class = $previous->content;
50   }
51
52   # now we have $class->$incomplete
53
54   my $metaclass = Class::MOP::Class->initialize($class);
55
56   my $re = qr/^\Q$incomplete/;
57
58   return $orig->(@_),
59          grep { $_ =~ $re }
60          map  { $_->{name} }
61          $metaclass->compute_all_applicable_methods;
62 };
63
64 1;
65
66 __END__
67
68 =head1 NAME
69
70 Devel::REPL::Plugin::CompletionDriver::Methods - Complete class or object method names
71
72 =head1 AUTHOR
73
74 Shawn M Moore, C<< <sartak at gmail dot com> >>
75
76 =cut
77