increment $VERSION after 1.003029 release
[p5sagit/Devel-REPL.git] / lib / Devel / REPL / Plugin / Interrupt.pm
CommitLineData
1716b200 1use strict;
2use warnings;
54d0f9a0 3package Devel::REPL::Plugin::Interrupt;
9d2a4940 4# ABSTRACT: Traps SIGINT to kill long-running lines
54d0f9a0 5
77327851 6our $VERSION = '1.003030';
54beb05d 7
6a5409bc 8use Devel::REPL::Plugin;
54fea9b0 9use Sys::SigAction qw(set_sig_handler);
aa8b7647 10use namespace::autoclean;
54d0f9a0 11
54fea9b0 12around 'run' => sub {
13 my ($orig, $self) = (shift, shift);
54d0f9a0 14
54fea9b0 15 local $SIG{INT} = 'IGNORE';
16
17 return $self->$orig(@_);
18};
19
20around 'run_once' => sub {
21 my ($orig, $self) = (shift, shift);
22
23 # We have to use Sys::SigAction: Perl 5.8+ has safe signal handling by
24 # default, and Term::ReadLine::Gnu restarts the interrupted system calls.
25 # The result is that the signal handler is not fired until you hit Enter.
26 my $sig_action = set_sig_handler INT => sub {
54d0f9a0 27 die "Interrupted.\n";
28 };
29
54fea9b0 30 return $self->$orig(@_);
31};
32
33around 'read' => sub {
34 my ($orig, $self) = (shift, shift);
35
36 # here SIGINT is caught and only kills the line being edited
37 while (1) {
38 my $line = eval { $self->$orig(@_) };
39 return $line unless $@;
40
41 die unless $@ =~ /^Interrupted\./;
42
43 # (Term::ReadLine::Gnu kills the line by default, but needs a LF -
44 # maybe I missed something?)
45 print "\n";
46 }
54d0f9a0 47};
48
491;
50
cfd1094b 51__END__
52
9d2a4940 53=pod
cfd1094b 54
54fea9b0 55=head1 DESCRIPTION
56
57By default L<Devel::REPL> exits on SIGINT (usually Ctrl-C). If you load this
58module, SIGINT will be trapped and used to kill long-running commands
59(statements) and also to kill the line being edited (like eg. BASH do). (You
60can still use Ctrl-D to exit.)
61
30b459d4 62=head1 AUTHOR
63
64Shawn M Moore, C<< <sartak at gmail dot com> >>
65
54fea9b0 66=cut