Add variable names to the completion list by using $self->lexical_environement
[p5sagit/Devel-REPL.git] / lib / Devel / REPL / Plugin / Completion.pm
CommitLineData
e4ac8502 1package Devel::REPL::Plugin::Completion;
2
3use Moose::Role;
4use namespace::clean -except => [ 'meta' ];
5
ac71b56c 6
e4ac8502 7# push the given string in the completion list
8sub push_completion
9{
10 my ($self, $string) = @_;
11 $self->term->Attribs->{completion_entry_function} =
12 $self->term->Attribs->{list_completion_function};
13 push @{$self->term->Attribs->{completion_word}}, $string;
14};
15
16# return the namespace of the module given
17sub get_namespace
18{
19 my ($self, $module) = @_;
20 my $namespace;
21 eval '$namespace = \%'.$module.'::';
22 return $namespace;
23}
24
25# we wrap the run method to init the completion list
26# with filenames found in the current dir and init
27# the completion list.
28# yes, this is our 'init the plugin' stuff actually
29sub BEFORE_PLUGIN
30{
31 my ($self) = @_;
32 # set the completion function
33 $self->term->Attribs->{completion_entry_function} =
34 $self->term->Attribs->{list_completion_function};
e4ac8502 35 $self->term->Attribs->{completion_word} = [];
ac71b56c 36
e4ac8502 37 # now put each file in curdir in the completion list
38 my $curdir = File::Spec->curdir();
39 if (opendir(CURDIR, $curdir)) {
40 while (my $file = readdir(CURDIR)) {
41 next if $file =~ /^\.+$/; # we skip "." and ".."
42 $self->push_completion($file);
43 }
44 }
45 closedir(CURDIR);
46}
47
e4ac8502 48# wrap the eval one to catch each 'use' statement in order to
49# load the namespace in the completion list (module functions and friends)
50# we do that around the eval method cause we want the module to be actually loaded.
51around 'eval' => sub {
52 my $orig = shift;
53 my ($self, $line) = @_;
54 my @ret = $self->$orig($line);
ac71b56c 55
56 # the namespace of the loaded module
e4ac8502 57 if ($line =~ /use\s+(\S+)/) {
58 my $module = $1;
59 foreach my $keyword (keys %{$self->get_namespace($module)}) {
60 $self->push_completion($keyword);
61 }
62 }
ac71b56c 63
64 # parses the lexical environment for new variables to add to
65 # the completion list
66 my $lex = $self->lexical_environment;
67 foreach my $var (keys %{$lex->get_context('_')}) {
68 $var = substr($var, 1); # we drop the variable idiom as it confuses the completion
69 $self->push_completion($var) unless
70 grep /^${var}$/, @{$self->term->Attribs->{completion_word}};
71 }
72
e4ac8502 73 return @ret;
74};
75
761;