r69325@onn: sartak | 2008-08-12 06:34:42 -0400
[p5sagit/Devel-REPL.git] / lib / Devel / REPL / Plugin / Turtles.pm
index 5faafc6..b53a3c1 100644 (file)
@@ -1,17 +1,79 @@
 package Devel::REPL::Plugin::Turtles;
-use Moose::Role;
+use Devel::REPL::Plugin;
+
+use Scalar::Util qw(reftype);
+
+use MooseX::AttributeHelpers;
+
 use namespace::clean -except => [ 'meta' ];
 
-around 'eval' => sub {
-    my $next = shift;
-    my ($self, $line) = @_;
-    if ($line =~ /^#(.*)/) {
-        return $next->($self, ('$REPL->' . $1 . '; return();'));
-    }
-    else {
-        return $next->($self, $line);
+has default_command_prefix => (
+  isa => "RegexpRef",
+  is  => "rw",
+  default => sub { qr/\#/ },
+);
+
+has turtles_matchers => (
+  metaclass => "Collection::Array",
+  isa => "ArrayRef[RegexpRef|CodeRef]",
+  is  => "rw",
+  lazy => 1,
+  default => sub { my $prefix = shift->default_command_prefix; [qr/^ $prefix (\w+) \s* (.*) /x] },
+  provides => {
+    unshift => "add_turtles_matcher",
+  },
+);
+
+around 'formatted_eval' => sub {
+  my $next = shift;
+  my ($self, $line, @args) = @_;
+
+  if ( my ( $command, @rest ) = $self->match_turtles($line) ) {
+    my $method = "command_$command";
+    my $expr_method = "expr_$method";
+
+    if ( my $expr_code = $self->can($expr_method) ) {
+      if ( my $read_more = $self->can("continue_reading_if_necessary") ) {
+        push @rest, $self->$read_more(pop @rest);
+      }
+      $self->$expr_code($next, @rest);
+    } elsif ( my $cmd_code = $self->can($method) ) {
+      return $self->$cmd_code($next, @rest);
+    } else {
+      unless ( $line =~ /^\s*#/ ) { # special case for comments
+        return $self->format($self->error_return("REPL Error", "Command '$command' does not exist"));
+      }
     }
-    
+  } else {
+    return $self->$next($line, @args);
+  }
 };
 
+sub match_turtles {
+  my ( $self, $line ) = @_;
+
+  foreach my $thingy ( @{ $self->turtles_matchers } ) {
+    if ( reftype $thingy eq 'CODE' ) {
+      if ( my @res = $self->$thingy($line) ) {
+        return @res;
+      }
+    } else {
+      if ( my @res = ( $line =~ $thingy ) ) {
+        return @res;
+      }
+    }
+  }
+
+  return;
+}
+
 1;
+
+__END__
+
+=head1 NAME
+
+Devel::REPL::Plugin::Turtles - Generic command creation using a read hook
+
+=cut
+