summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2013-06-27 20:39:30 -0400
committerJesse Luehrs <doy@tozt.net>2013-06-27 20:39:30 -0400
commitf24b7a7761c5740561c23f1ef23658d643aae478 (patch)
tree76a73489e8c12e7f8df46517cf2917c65be9918b
parent448ed3da95cf3d28fb35a3231249180cf22f6129 (diff)
downloadreply-f24b7a7761c5740561c23f1ef23658d643aae478.tar.gz
reply-f24b7a7761c5740561c23f1ef23658d643aae478.zip
add method completion
-rw-r--r--lib/Reply/Plugin/Autocomplete/Methods.pm82
1 files changed, 82 insertions, 0 deletions
diff --git a/lib/Reply/Plugin/Autocomplete/Methods.pm b/lib/Reply/Plugin/Autocomplete/Methods.pm
new file mode 100644
index 0000000..19302ce
--- /dev/null
+++ b/lib/Reply/Plugin/Autocomplete/Methods.pm
@@ -0,0 +1,82 @@
+package Reply::Plugin::Autocomplete::Methods;
+use strict;
+use warnings;
+# ABSTRACT: tab completion for methods
+
+use base 'Reply::Plugin';
+
+use Package::Stash;
+use Scalar::Util 'blessed';
+
+=head1 SYNOPSIS
+
+ ; .replyrc
+ [ReadLine]
+ [Autocomplete::Methods]
+
+=head1 DESCRIPTION
+
+This plugin registers a tab key handler to autocomplete method names in Perl
+code.
+
+=cut
+
+sub new {
+ my $class = shift;
+
+ my $self = $class->SUPER::new(@_);
+ $self->{env} = {};
+ $self->{package} = 'main';
+
+ return $self;
+}
+
+sub lexical_environment {
+ my $self = shift;
+ my ($name, $env) = @_;
+
+ $self->{env}{$name} = $env;
+}
+
+sub package {
+ my $self = shift;
+ my ($package) = @_;
+
+ $self->{package} = $package;
+}
+
+sub tab_handler {
+ my $self = shift;
+ my ($line) = @_;
+
+ my ($invocant, $method) = $line =~ /((?:\$\s*)?[A-Z_a-z][0-9A-Z_a-z:]*)->([A-Z_a-z][0-9A-Z_a-z]*)?$/;
+ return unless $method;
+
+ my $package;
+ if ($invocant =~ /^\$/) {
+ my $env = {
+ (map { %$_ } values %{ $self->{env} }),
+ (%{ $self->{env}{defaults} || {} }),
+ };
+ my $var = $env->{$invocant};
+ return unless $var && ref($var) eq 'REF' && blessed($$var);
+ $package = blessed($$var);
+ }
+ else {
+ $package = $invocant;
+ }
+
+ my $stash = eval { Package::Stash->new($package) };
+ return unless $stash;
+
+ my @results;
+ for my $stash_method ($stash->list_all_symbols('CODE')) {
+ next unless index($stash_method, $method) == 0;
+
+ push @results, $stash_method;
+ }
+
+ return @results;
+}
+
+1;