File Coverage

blib/lib/File/Searcher/Interactive.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package File::Searcher::Interactive;
2 1     1   2498 use File::Searcher;
  0            
  0            
3             use Term::Prompt;
4             use Term::ANSIColor qw/:constants/;
5             $Term::ANSIColor::AUTORESET = 1;
6             use strict;
7             use vars qw($VERSION @ISA);
8             @ISA = qw(File::Searcher);
9             $VERSION = '0.9';
10            
11            
12             sub interactive{
13             my $self = shift;
14             $self->{_interactive} = 1;
15             $self->start;
16             }
17            
18             sub _process_file{
19             my $self = shift;
20             my ($file) = @_;
21             my @expressions = @{$self->{_expressions}};
22            
23             my $contents='';
24             $self->_backup($file) if $self->do_backup;
25             $self->_archive($file) if $self->do_archive;
26             $self->{_search}->add_files_matched($file);
27            
28             my $lock = new File::Flock $file;
29             open(FILE, $file) || die "Cannot read file $file\n";
30             my @contents = ;
31             $contents = join("", @contents);
32             foreach my $expression (@expressions)
33             {
34             next if $self->{_search}->expression($expression)->skip_expression;
35             my ($match_cnt,$replace_cnt,$skip_next,$do_file,$do_all,$new_match_cnt,$re_do) = (0)x7;
36             $self->{_search}->expression($expression)->add_files_matched($file);
37             $do_all = $self->expression($expression)->do_all;
38             my $preview = '';
39             my $more = 1;
40             my ($search, $replace, $options_search, $options_replace) = $self->_get_search($expression);
41             $search = "(?$options_search)$search";
42             while($contents =~ m/$search/g)
43             {
44             my $match = Match->new(match=>$&,pre=>$`,post=>$',last=>$+,start_offset=>@-,end_offset=>@+,contents=>$contents);
45            
46             my $return_status = 0;
47             $return_status = $self->{_on_expression_match}->($match, $self->{_search}->expression($expression)) if $do_file != 1 && $do_all != 1 && $new_match_cnt < 1;
48             $contents = $return_status and next if $return_status !~ /\d+/ && $return_status ne '';
49             $self->expression($expression)->do_all(1) and $do_all = 1 if $return_status == 100;
50             $do_file = 1 if $return_status == 10;
51             $self->expression($expression)->skip_expression(1) and last if $return_status == -100;
52             last if $return_status == -10;
53             $skip_next = 1 if $return_status == -1;
54            
55             $skip_next = 1 if $match->match eq $replace;
56             $skip_next = 1 if $new_match_cnt > 0;
57            
58             my $short_pre = substr($match->pre, (-25*$more), (25*$more));
59             my $short_post = substr($match->post, 0, 25*$more);
60             my $message = $short_pre; $message .= $re_do ? BOLD $preview : BOLD $match->match; $message .= $short_post;
61             unless($do_file || $do_all || $skip_next)
62             {
63             my $out = BOLD $file ."\n"; $out.=$message; $out.="\n--------------\n"; $out .= BOLD $replace . "\n";
64             print $out;
65             }
66             my $prompt = BOLD "[Y]"; $prompt .= "Replace "; $prompt .= BOLD "[A]"; $prompt .= "All In File "; $prompt .= BOLD "[Z]"; $prompt .= "All Files\n "; $prompt .= BOLD "[P]"; $prompt .= "Preview "; $prompt .= BOLD "[M]"; $prompt .= "More\n";
67             my $result = '';
68             $result = "Y" if $do_file || $do_all;
69             $result = "Next" if $skip_next;
70             $result = &Term::Prompt::prompt("x", "$prompt", "", "Next") unless $result;
71             $more = 1 if $result !~ /M/i && $skip_next != 1;
72             $re_do = 0 unless $skip_next;
73            
74             if($result =~ /A/i){
75             my $v_message = "Are you sure you want to replace "; $v_message .= BOLD "ALL "; $v_message .= "occurances of $search in "; $v_message .= BOLD "THIS "; $v_message .= "file";
76             my $verify = &prompt("y", "$v_message", "", "n");
77             $do_file = 1 if $verify == 1;
78             $contents = $match->pre . $match->match . $match->post if $verify != 1;
79             }
80             elsif($result =~ /Z/i){
81             my $v_message = "Are you sure you want to replace "; $v_message .= BOLD "ALL "; $v_message .= "occurances of $search in "; $v_message .= BOLD "ALL "; $v_message .= "remaining files";
82             my $verify = &prompt("y", "$v_message", "", "No");
83             $do_all = 1 if $verify == 1;
84             $self->expression($expression)->do_all(1) if $verify == 1;
85             $contents = $match->pre . $match->match . $match->post if $verify != 1;
86             }
87             elsif($result =~ /P/i){
88             $re_do = 1;
89             my $body = $match->match;
90             eval ("\$body =~ s/$search/$replace/$options_replace");
91             $contents = $match->pre . $match->match . $match->post;
92             $new_match_cnt = $match_cnt+1;
93             $preview = $body;
94             }
95             elsif($result =~ /m/i){
96             $re_do = 1;
97             $more = $more*2;
98             $contents = $match->pre . $match->match . $match->post;
99             $new_match_cnt = $match_cnt+1;
100             $preview = $match->match;
101             }
102            
103             $match_cnt++ unless $skip_next == 1 || $re_do == 1;
104             if($result =~ /y/i || ($result =~ /Z/i && $do_all) || ($result =~ /A/i && $do_file))
105             {
106             my $body = $match->match;
107             eval ("\$body =~ s/$search/$replace/$options_replace");
108             $replace_cnt++;
109             $contents = $match->pre . $body . $match->post;
110             $new_match_cnt = $match_cnt+1;
111             }
112             $new_match_cnt--;
113             $skip_next = 0;
114             }
115             $self->{_search}->expression($expression)->add_files_replaced($file) if $replace_cnt > 0;
116             $self->{_search}->expression($expression)->replacements($file, $replace_cnt);
117             $self->{_search}->expression($expression)->matches($file, $match_cnt);
118             }
119             close(FILE);
120             if($self->{_search}->do_replace)
121             {
122             open(FILE, ">$file") || die "Cannot read file $file\n";
123             print FILE $contents;
124             close(FILE);
125             }
126             }
127            
128            
129             1;
130             __END__