X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=p5sagit%2FDevel-REPL.git;a=blobdiff_plain;f=lib%2FDevel%2FREPL%2FPlugin%2FCompletionDriver%2FGlobals.pm;fp=lib%2FDevel%2FREPL%2FPlugin%2FCompletionDriver%2FGlobals.pm;h=798ba510be3a65650ddfc6ada53bda93536d4440;hp=0000000000000000000000000000000000000000;hb=908733a9f76e870c4518684ccd9c20ea692fd98c;hpb=16d29e4242cfb095bdcd65a16fb3b4d4d0013240 diff --git a/lib/Devel/REPL/Plugin/CompletionDriver/Globals.pm b/lib/Devel/REPL/Plugin/CompletionDriver/Globals.pm new file mode 100644 index 0000000..798ba51 --- /dev/null +++ b/lib/Devel/REPL/Plugin/CompletionDriver/Globals.pm @@ -0,0 +1,51 @@ +package Devel::REPL::Plugin::CompletionDriver::Globals; +use Devel::REPL::Plugin; +use namespace::clean -except => [ 'meta' ]; + +around complete => sub { + my $orig = shift; + my ($self, $text, $document) = @_; + + my $last = $self->last_ppi_element($document); + + return $orig->(@_) + unless $last->isa('PPI::Token::Symbol'); + + my $sigil = substr($last, 0, 1, ''); + my $re = qr/^\Q$last/; + + my @package_fragments = split qr/::|'/, $last; + + # split drops the last fragment if it's empty + push @package_fragments, '' if $last =~ /(?:'|::)$/; + + # the beginning of the variable, or an incomplete package name + my $incomplete = pop @package_fragments; + + # recurse for the complete package fragments + my $stash = \%::; + for (@package_fragments) { + $stash = $stash->{"$_\::"}; + } + + # collect any variables from this stash + my @found = grep { /$re/ } + map { join '::', @package_fragments, $_ } + keys %$stash; + + # check to see if it's an incomplete package name, and add its variables + # so Devel is completed correctly + for my $key (keys %$stash) { + next unless $key =~ /::$/; # only look at deeper packages + next unless $key =~ /^\Q$incomplete/; # only look at matching packages + push @found, + map { join '::', @package_fragments, $_ } + map { "$key$_" } # $key already has trailing :: + keys %{ $stash->{$key} }; + } + + return $orig->(@_), @found; +}; + +1; +