1 package Devel::REPL::Plugin::Completion;
4 use namespace::clean -except => [ 'meta' ];
6 # push the given string in the completion list
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;
15 # return the namespace of the module given
18 my ($self, $module) = @_;
20 eval '$namespace = \%'.$module.'::';
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
31 # set the completion function
32 $self->term->Attribs->{completion_entry_function} =
33 $self->term->Attribs->{list_completion_function};
35 # init the completion with an arrayref (could be the Perl built-ins)
36 $self->term->Attribs->{completion_word} = [];
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);
49 # wrap the read method so we save in the completion list
50 # each variable declaration
51 around 'read' => sub {
53 my ($self, @args) = @_;
54 my $line = $self->$orig(@args);
56 if ($line =~ /\s*[\$\%\@](\S+)\s*=/) {
58 $self->push_completion($str);
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.
67 around 'eval' => sub {
69 my ($self, $line) = @_;
70 my @ret = $self->$orig($line);
71 if ($line =~ /use\s+(\S+)/) {
73 foreach my $keyword (keys %{$self->get_namespace($module)}) {
74 $self->push_completion($keyword);