X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=p5sagit%2FDevel-REPL.git;a=blobdiff_plain;f=lib%2FDevel%2FREPL%2FPlugin%2FInterrupt.pm;h=2b4a478cdbae82fffee6d5022498d2ab594568eb;hp=0df8cb0a01b69da0cbc89bbedc09bff013ae249a;hb=9d2a4940f5958d82828272364ef754e9290b6113;hpb=6a5409bc859187db7d7553e4c19a559aeeba6430 diff --git a/lib/Devel/REPL/Plugin/Interrupt.pm b/lib/Devel/REPL/Plugin/Interrupt.pm index 0df8cb0..2b4a478 100644 --- a/lib/Devel/REPL/Plugin/Interrupt.pm +++ b/lib/Devel/REPL/Plugin/Interrupt.pm @@ -1,30 +1,66 @@ +use strict; +use warnings; package Devel::REPL::Plugin::Interrupt; +# ABSTRACT: Traps SIGINT to kill long-running lines + +our $VERSION = '1.003027'; use Devel::REPL::Plugin; -use namespace::clean -except => [ 'meta' ]; +use Sys::SigAction qw(set_sig_handler); +use namespace::autoclean; + +around 'run' => sub { + my ($orig, $self) = (shift, shift); + + local $SIG{INT} = 'IGNORE'; -around 'eval' => sub { - my $orig = shift; - my ($self, $line) = @_; + return $self->$orig(@_); +}; + +around 'run_once' => sub { + my ($orig, $self) = (shift, shift); - local $SIG{INT} = sub { + # We have to use Sys::SigAction: Perl 5.8+ has safe signal handling by + # default, and Term::ReadLine::Gnu restarts the interrupted system calls. + # The result is that the signal handler is not fired until you hit Enter. + my $sig_action = set_sig_handler INT => sub { die "Interrupted.\n"; }; - return $self->$orig($line); + return $self->$orig(@_); +}; + +around 'read' => sub { + my ($orig, $self) = (shift, shift); + + # here SIGINT is caught and only kills the line being edited + while (1) { + my $line = eval { $self->$orig(@_) }; + return $line unless $@; + + die unless $@ =~ /^Interrupted\./; + + # (Term::ReadLine::Gnu kills the line by default, but needs a LF - + # maybe I missed something?) + print "\n"; + } }; 1; __END__ -=head1 NAME +=pod + +=head1 DESCRIPTION -Devel::REPL::Plugin::Interrupt - traps SIGINT to kill long-running lines +By default L exits on SIGINT (usually Ctrl-C). If you load this +module, SIGINT will be trapped and used to kill long-running commands +(statements) and also to kill the line being edited (like eg. BASH do). (You +can still use Ctrl-D to exit.) =head1 AUTHOR Shawn M Moore, C<< >> =cut -