c2e1c74c0e21d5e7f34e6cb70c5cb7be8664e72a
[p5sagit/Devel-REPL.git] / lib / Devel / REPL / Plugin / CompletionDriver / Globals.pm
1 use strict;
2 use warnings;
3 package Devel::REPL::Plugin::CompletionDriver::Globals;
4 use Devel::REPL::Plugin;
5 use namespace::autoclean;
6
7 sub BEFORE_PLUGIN {
8     my $self = shift;
9     $self->load_plugin('Completion');
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
18   return $orig->(@_)
19     unless $last->isa('PPI::Token::Symbol')
20         || $last->isa('PPI::Token::Word');
21
22   my $sigil = $last =~ s/^[\$\@\%\&\*]// ? $1 : undef;
23   my $re = qr/^\Q$last/;
24
25   my @package_fragments = split qr/::|'/, $last;
26
27   # split drops the last fragment if it's empty
28   push @package_fragments, '' if $last =~ /(?:'|::)$/;
29
30   # the beginning of the variable, or an incomplete package name
31   my $incomplete = pop @package_fragments;
32
33   # recurse for the complete package fragments
34   my $stash = \%::;
35   for (@package_fragments) {
36     $stash = $stash->{"$_\::"};
37   }
38
39   # collect any variables from this stash
40   my @found = grep { /$re/ }
41               map  { join '::', @package_fragments, $_ }
42               keys %$stash;
43
44   # check to see if it's an incomplete package name, and add its variables
45   # so Devel<TAB> is completed correctly
46   for my $key (keys %$stash) {
47       next unless $key =~ /::$/;            # only look at deeper packages
48       next unless $key =~ /^\Q$incomplete/; # only look at matching packages
49       push @found,
50         map { join '::', @package_fragments, $_ }
51         map { "$key$_" } # $key already has trailing ::
52         keys %{ $stash->{$key} };
53   }
54
55   return $orig->(@_), @found;
56 };
57
58 1;
59
60 __END__
61
62 =head1 NAME
63
64 Devel::REPL::Plugin::CompletionDriver::Globals - Complete global variables, packages, namespaced functions
65
66 =head1 AUTHOR
67
68 Shawn M Moore, C<< <sartak at gmail dot com> >>
69
70 =cut
71