From: Sartak Date: Wed, 26 Sep 2007 01:39:33 +0000 (+0000) Subject: Add LexEnv completion plugin. I still owe mst a refactor of the completion subsystem :) X-Git-Tag: v1.003015~144 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=314f229330cdc3be301a39eadb68ff8f2bf13043;p=p5sagit%2FDevel-REPL.git Add LexEnv completion plugin. I still owe mst a refactor of the completion subsystem :) git-svn-id: http://dev.catalyst.perl.org/repos/bast/trunk/Devel-REPL@3783 bd8105ee-0ff8-0310-8827-fb3f25b6796d --- diff --git a/lib/Devel/REPL/Plugin/Completion.pm b/lib/Devel/REPL/Plugin/Completion.pm index ae4a8ec..e9ac902 100644 --- a/lib/Devel/REPL/Plugin/Completion.pm +++ b/lib/Devel/REPL/Plugin/Completion.pm @@ -5,17 +5,17 @@ use PPI; use namespace::clean -except => [ 'meta' ]; has current_matches => ( - is => 'rw', - isa => 'ArrayRef', - lazy => 1, - default => sub { [] }, + is => 'rw', + isa => 'ArrayRef', + lazy => 1, + default => sub { [] }, ); has match_index => ( - is => 'rw', - isa => 'Int', - lazy => 1, - default => sub { 0 }, + is => 'rw', + isa => 'Int', + lazy => 1, + default => sub { 0 }, ); sub BEFORE_PLUGIN { @@ -33,11 +33,15 @@ sub _completion { my ($self, $text, $line, $start, $end) = @_; # we're discarding everything after the cursor for completion purposes + # we can't just use $text because we want all the code before the cursor to + # matter, not just the current word substr($line, $end) = ''; my $document = PPI::Document->new(\$line); return unless defined($document); + $document->prune('PPI::Token::Whitespace'); + my @matches = $self->complete($text, $document); # iterate through the completions diff --git a/lib/Devel/REPL/Plugin/CompletionDriver/LexEnv.pm b/lib/Devel/REPL/Plugin/CompletionDriver/LexEnv.pm new file mode 100644 index 0000000..2011896 --- /dev/null +++ b/lib/Devel/REPL/Plugin/CompletionDriver/LexEnv.pm @@ -0,0 +1,38 @@ +package Devel::REPL::Plugin::CompletionDriver::LexEnv; +use Devel::REPL::Plugin; +use namespace::clean -except => [ 'meta' ]; + +sub AFTER_PLUGIN { + my ($_REPL) = @_; + + if (!$_REPL->can('lexical_environment')) { + warn "Devel::REPL::Plugin::CompletionDriver::LexEnv requires Devel::REPL::Plugin::LexEnv."; + } +} + +around complete => sub { + my $orig = shift; + my ($self, $text, $document) = @_; + + # recursively find the last element + my $last = $document; + while ($last->can('last_element') && defined($last->last_element)) { + $last = $last->last_element; + } + + return $orig->(@_) + unless $last->isa('PPI::Token::Symbol'); + + my $sigil = substr($last, 0, 1, ''); + my $re = qr/^\Q$last/; + + return $orig->(@_), + # ReadLine is weirdly inconsistent + map { $sigil eq '%' ? '%' . $_ : $_ } + grep { /$re/ } + map { substr($_, 1) } # drop lexical's sigil + keys %{$self->lexical_environment->get_context('_')}; +}; + +1; +