From: sukria Date: Mon, 20 Aug 2007 17:18:39 +0000 (+0000) Subject: Adding the Compeltion plugin X-Git-Tag: v1.003015~162 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=e4ac8502d347481fb17c889adb8a4a831988359a;p=p5sagit%2FDevel-REPL.git Adding the Compeltion plugin git-svn-id: http://dev.catalyst.perl.org/repos/bast/trunk/Devel-REPL@3687 bd8105ee-0ff8-0310-8827-fb3f25b6796d --- diff --git a/lib/Devel/REPL/Plugin/Completion.pm b/lib/Devel/REPL/Plugin/Completion.pm new file mode 100644 index 0000000..bbee49a --- /dev/null +++ b/lib/Devel/REPL/Plugin/Completion.pm @@ -0,0 +1,80 @@ +package Devel::REPL::Plugin::Completion; + +use Moose::Role; +use namespace::clean -except => [ 'meta' ]; + +# push the given string in the completion list +sub push_completion +{ + my ($self, $string) = @_; + $self->term->Attribs->{completion_entry_function} = + $self->term->Attribs->{list_completion_function}; + push @{$self->term->Attribs->{completion_word}}, $string; +}; + +# return the namespace of the module given +sub get_namespace +{ + my ($self, $module) = @_; + my $namespace; + eval '$namespace = \%'.$module.'::'; + return $namespace; +} + +# we wrap the run method to init the completion list +# with filenames found in the current dir and init +# the completion list. +# yes, this is our 'init the plugin' stuff actually +sub BEFORE_PLUGIN +{ + my ($self) = @_; + # set the completion function + $self->term->Attribs->{completion_entry_function} = + $self->term->Attribs->{list_completion_function}; + + # init the completion with an arrayref (could be the Perl built-ins) + $self->term->Attribs->{completion_word} = []; + + # now put each file in curdir in the completion list + my $curdir = File::Spec->curdir(); + if (opendir(CURDIR, $curdir)) { + while (my $file = readdir(CURDIR)) { + next if $file =~ /^\.+$/; # we skip "." and ".." + $self->push_completion($file); + } + } + closedir(CURDIR); +} + +# wrap the read method so we save in the completion list +# each variable declaration +around 'read' => sub { + my $orig = shift; + my ($self, @args) = @_; + my $line = $self->$orig(@args); + if (defined $line) { + if ($line =~ /\s*[\$\%\@](\S+)\s*=/) { + my $str = $1; + $self->push_completion($str); + } + } + return $line; +}; + +# wrap the eval one to catch each 'use' statement in order to +# load the namespace in the completion list (module functions and friends) +# we do that around the eval method cause we want the module to be actually loaded. +around 'eval' => sub { + my $orig = shift; + my ($self, $line) = @_; + my @ret = $self->$orig($line); + if ($line =~ /use\s+(\S+)/) { + my $module = $1; + foreach my $keyword (keys %{$self->get_namespace($module)}) { + $self->push_completion($keyword); + } + } + return @ret; +}; + +1;