Add variable names to the completion list by using $self->lexical_environement
sukria [Mon, 20 Aug 2007 22:14:48 +0000 (22:14 +0000)]
git-svn-id: http://dev.catalyst.perl.org/repos/bast/trunk/Devel-REPL@3688 bd8105ee-0ff8-0310-8827-fb3f25b6796d

lib/Devel/REPL/Plugin/Completion.pm

index bbee49a..b546488 100644 (file)
@@ -3,6 +3,7 @@ package Devel::REPL::Plugin::Completion;
 use Moose::Role;
 use namespace::clean -except => [ 'meta' ];
 
+
 # push the given string in the completion list
 sub push_completion
 {
@@ -31,10 +32,8 @@ sub BEFORE_PLUGIN
     # 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)) {
@@ -46,21 +45,6 @@ sub BEFORE_PLUGIN
     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.
@@ -68,12 +52,24 @@ around 'eval' => sub {
     my $orig = shift;
     my ($self, $line) = @_;
     my @ret = $self->$orig($line);
+    
+    # the namespace of the loaded module
     if ($line =~ /use\s+(\S+)/) {
         my $module = $1;
         foreach my $keyword (keys %{$self->get_namespace($module)}) {
             $self->push_completion($keyword);
         }
     }
+
+    # parses the lexical environment for new variables to add to 
+    # the completion list
+    my $lex = $self->lexical_environment;
+    foreach my $var (keys %{$lex->get_context('_')}) {
+        $var = substr($var, 1); # we drop the variable idiom as it confuses the completion
+        $self->push_completion($var) unless 
+            grep /^${var}$/, @{$self->term->Attribs->{completion_word}};
+    }
+
     return @ret;
 };