Adding the Compeltion plugin
[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
6# push the given string in the completion list
7sub push_completion
8{
9 my ($self, $string) = @_;
10 $self->term->Attribs->{completion_entry_function} =
11 $self->term->Attribs->{list_completion_function};
12 push @{$self->term->Attribs->{completion_word}}, $string;
13};
14
15# return the namespace of the module given
16sub get_namespace
17{
18 my ($self, $module) = @_;
19 my $namespace;
20 eval '$namespace = \%'.$module.'::';
21 return $namespace;
22}
23
24# we wrap the run method to init the completion list
25# with filenames found in the current dir and init
26# the completion list.
27# yes, this is our 'init the plugin' stuff actually
28sub BEFORE_PLUGIN
29{
30 my ($self) = @_;
31 # set the completion function
32 $self->term->Attribs->{completion_entry_function} =
33 $self->term->Attribs->{list_completion_function};
34
35 # init the completion with an arrayref (could be the Perl built-ins)
36 $self->term->Attribs->{completion_word} = [];
37
38 # now put each file in curdir in the completion list
39 my $curdir = File::Spec->curdir();
40 if (opendir(CURDIR, $curdir)) {
41 while (my $file = readdir(CURDIR)) {
42 next if $file =~ /^\.+$/; # we skip "." and ".."
43 $self->push_completion($file);
44 }
45 }
46 closedir(CURDIR);
47}
48
49# wrap the read method so we save in the completion list
50# each variable declaration
51around 'read' => sub {
52 my $orig = shift;
53 my ($self, @args) = @_;
54 my $line = $self->$orig(@args);
55 if (defined $line) {
56 if ($line =~ /\s*[\$\%\@](\S+)\s*=/) {
57 my $str = $1;
58 $self->push_completion($str);
59 }
60 }
61 return $line;
62};
63
64# wrap the eval one to catch each 'use' statement in order to
65# load the namespace in the completion list (module functions and friends)
66# we do that around the eval method cause we want the module to be actually loaded.
67around 'eval' => sub {
68 my $orig = shift;
69 my ($self, $line) = @_;
70 my @ret = $self->$orig($line);
71 if ($line =~ /use\s+(\S+)/) {
72 my $module = $1;
73 foreach my $keyword (keys %{$self->get_namespace($module)}) {
74 $self->push_completion($keyword);
75 }
76 }
77 return @ret;
78};
79
801;