Add the @INC completion driver. Needs some tweaking, but it's generally there
Sartak [Sun, 25 May 2008 17:09:23 +0000 (17:09 +0000)]
git-svn-id: http://dev.catalyst.perl.org/repos/bast/trunk/Devel-REPL@4397 bd8105ee-0ff8-0310-8827-fb3f25b6796d

lib/Devel/REPL/Plugin/CompletionDriver/INC.pm [new file with mode: 0644]

diff --git a/lib/Devel/REPL/Plugin/CompletionDriver/INC.pm b/lib/Devel/REPL/Plugin/CompletionDriver/INC.pm
new file mode 100644 (file)
index 0000000..d2996e3
--- /dev/null
@@ -0,0 +1,73 @@
+package Devel::REPL::Plugin::CompletionDriver::INC;
+use Devel::REPL::Plugin;
+use File::Next;
+use File::Spec;
+use namespace::clean -except => [ 'meta' ];
+
+around complete => sub {
+  my $orig = shift;
+  my ($self, $text, $document) = @_;
+
+  my $last = $self->last_ppi_element($document, 'PPI::Statement::Include');
+
+  return $orig->(@_)
+    unless $last->isa('PPI::Statement::Include');
+
+  my @elements = $last->children;
+  shift @elements; # use or require
+
+  # too late for us to care, they're completing on something like
+  #     use List::Util qw(m
+  # OR they just have "use " and are tab completing. we'll spare them the flood
+  return $orig->(@_)
+    if @elements != 1;
+
+  my $package = shift @elements;
+  my $outsep  = '::';
+  my $insep   = '::';
+  my $keep_extension = 0;
+
+  # require "Module"
+  if ($package->isa('PPI::Token::Quote'))
+  {
+      $outsep = $insep = '/';
+      $keep_extension = 1;
+  }
+  elsif ($package =~ /'/)
+  {
+      # the goofball is using the ancient ' package sep, we'll humor him
+      $outsep = q{'};
+      $insep = "'|::";
+  }
+
+  my @directories = split $insep, $package;
+
+  # split drops trailing fields
+  push @directories, '' if $package =~ /(?:$insep)$/;
+  my $final = pop @directories;
+  my $final_re = qr/^\Q$final/;
+
+  my @found;
+
+  INC: for (@INC)
+  {
+    my $path = $_;
+    for my $subdir (@directories)
+    {
+      $path = File::Spec->catdir($path, $subdir);
+      -d $path or next INC;
+    }
+
+    opendir((my $dirhandle), $path);
+    for my $match (grep { $_ =~ $final_re } readdir $dirhandle)
+    {
+      $match =~ s/\..*// unless $keep_extension;
+      push @found, join $outsep, @directories, $match;
+    }
+  }
+
+  return $orig->(@_), @found;
+};
+
+1;
+