File Coverage

blib/lib/Pinto/Editor/Edit.pm
Criterion Covered Total %
statement 12 115 10.4
branch 0 66 0.0
condition n/a
subroutine 4 16 25.0
pod 0 8 0.0
total 16 205 7.8


line stmt bran cond sub pod time code
1             # ABSTRACT: Internal class for Pinto::Editor
2              
3             package Pinto::Editor::Edit;
4              
5 57     57   370 use Moose;
  57         207  
  57         381  
6 57     57   382452 use Try::Tiny;
  57         158  
  57         3619  
7 57     57   2117 use IO::File;
  57         3541  
  57         6998  
8              
9 57     57   23530 use Pinto::Editor::Clip;
  57         197  
  57         71726  
10              
11             #-----------------------------------------------------------------------------
12              
13             our $VERSION = '0.14'; # VERSION
14              
15             #-----------------------------------------------------------------------------
16              
17             our $EDITOR = 'Pinto::Editor';
18             our $RETRY = "__Pinto_Editor_retry__\n";
19             our $Test_edit;
20              
21             #-----------------------------------------------------------------------------
22              
23             has process => qw/ is ro isa Maybe[CodeRef] /;
24             has separator => qw/ is rw /;
25             has file => qw/ is ro required 1 /;
26              
27             has document => qw/ is rw isa Str required 1 /;
28             has $_ => reader => $_, writer => "_$_", isa => 'Str' for qw/ initial_document /;
29              
30             has preamble => qw/ is rw isa Maybe[Str] /;
31             has $_ => reader => $_, writer => "_$_", isa => 'Maybe[Str]' for qw/ initial_preamble /;
32              
33             has content => qw/ is rw isa Str /;
34             has $_ => reader => $_, writer => "_$_", isa => 'Str' for qw/ initial_content /;
35              
36             #-----------------------------------------------------------------------------
37              
38             sub BUILD {
39 0     0 0   my $self = shift;
40              
41 0           my $document = $self->document;
42 0           $self->_initial_document( $document );
43              
44 0           my ( $preamble, $content ) = $self->split( $document );
45              
46 0           $self->preamble( $preamble );
47 0           $self->_initial_preamble( $preamble );
48              
49 0           $self->content( $content );
50 0           $self->_initial_content( $content );
51             }
52              
53             #-----------------------------------------------------------------------------
54              
55             sub edit {
56 0     0 0   my $self = shift;
57              
58 0           my $file = $self->file;
59 0           my $tmp;
60 0 0         if ( blessed $file ) {
61 0 0         if ( $file->isa( 'IO::Handle' ) ) {
    0          
62 0           $tmp = $file;
63             }
64             elsif ( $file->isa( 'Path::Class::File' ) ) {
65 0 0         $tmp = $file->open( 'w' ) or die "Unable to open $file: $!";
66             }
67             else {
68 0           die "Invalid file: $file";
69             }
70             }
71             else {
72 0 0         $file = '' unless defined $file;
73 0 0         if ( ref $file ) {
    0          
74 0           die "Invalid file: $file";
75             }
76             elsif ( length $file ) {
77 0 0         $tmp = IO::File->new( $file, 'w' ) or die "Unable to open $file: $!";
78             }
79             else {
80 0           die "Missing file";
81             }
82             }
83 0           $tmp->autoflush( 1 );
84              
85 0           while ( 1 ) {
86 0 0         $tmp->seek( 0, 0 ) or die "Unable to seek on tmp ($tmp): $!";
87 0 0         $tmp->truncate( 0 ) or die "Unable to truncate on tmp ($tmp): $!";
88 0           $tmp->print( $self->join( $self->preamble, $self->content ) );
89              
90 0 0         if ( $Test_edit ) {
91 0           $Test_edit->( $tmp );
92             }
93             else {
94             try {
95 0     0     $EDITOR->edit_file( $tmp->filename );
96             }
97             catch {
98 0     0     my $error = $_[0];
99 0           warn "$error";
100 0           warn "*** There was an error editing ", $tmp->filename, "\n";
101 0           while ( 1 ) {
102 0           print STDERR "Do you want to (c)ontinue, (a)bort, or (s)ave? ";
103 0           my $input = <STDIN>;
104 0           chomp $input;
105 0 0         die $error unless defined $input;
106 0 0         if ( 0 ) { }
    0          
    0          
107 0           elsif ( $input eq 'c' ) {
108 0           last;
109             }
110             elsif ( $input eq 'a' ) {
111 0           die $error;
112             }
113             elsif ( $input eq 's' ) {
114 0           my $save;
115 0 0         unless ( $save = File::Temp->new( dir => '.', template => 'PintoEditor.XXXXXX', unlink => 0 ) ) {
116 0 0         warn "Unable to create temporary file: $!" and next;
117             }
118 0           my $tmp_filename = $tmp->filename;
119 0           my $tmpr;
120 0 0         unless ( $tmpr = IO::File->new( $tmp_filename, 'r' ) ) {
121 0 0         warn "Unable to open ($tmp_filename): $!" and next;
122             }
123 0           $save->print( join '', <$tmpr> );
124 0           $save->close;
125 0           warn "Saved to: ", $save->filename, " ", ( -s $save->filename ), "\n";
126             }
127             else {
128 0           warn "I don't understand ($input)\n";
129             }
130             }
131              
132 0           };
133             }
134              
135 0           my $document;
136             {
137 0           my $filename = $tmp->filename;
  0            
138 0 0         my $tmpr = IO::File->new( $filename, 'r' ) or die "Unable to open ($filename): $!";
139 0           $document = join '', <$tmpr>;
140 0           $tmpr->close;
141 0           undef $tmpr;
142             }
143              
144 0           $self->document( $document );
145 0           my ( $preamble, $content ) = $self->split( $document );
146 0           $self->preamble( $preamble );
147 0           $self->content( $content );
148              
149 0 0         if ( my $process = $self->process ) {
150 0           my ( @result, $retry );
151             try {
152 0     0     @result = $process->( $self );
153             }
154             catch {
155 0 0   0     die $_ unless $_ eq $RETRY;
156 0           $retry = 1;
157 0           };
158              
159 0 0         next if $retry;
160              
161 0 0         return $result[0] if defined $result[0];
162             }
163              
164 0           return $content;
165             }
166              
167             }
168              
169             #-----------------------------------------------------------------------------
170              
171             sub first_line_blank {
172 0     0 0   my $self = shift;
173 0           return $self->document =~ m/\A\s*$/m;
174             }
175              
176             #-----------------------------------------------------------------------------
177              
178 0     0 0   sub line0_blank { return $_[0]->first_line_blank }
179              
180             #-----------------------------------------------------------------------------
181              
182             sub preamble_from_initial {
183 0     0 0   my $self = shift;
184 0           my @preamble;
185 0           for my $part ( "$_[0]", $self->initial_preamble ) {
186 0 0         next unless defined $part;
187 0           chomp $part;
188 0           push @preamble, $part;
189             }
190 0 0         $self->preamble( join "\n", @preamble, '' ) if @preamble;
191             }
192              
193             #-----------------------------------------------------------------------------
194              
195             sub retry {
196 0     0 0   my $self = shift;
197 0           die $RETRY;
198             }
199              
200             #-----------------------------------------------------------------------------
201              
202             sub split {
203 0     0 0   my $self = shift;
204 0           my $document = shift;
205              
206 0 0         return ( undef, $document ) unless my $separator = $self->separator;
207              
208 0 0         die "Invalid separator ($separator)" if ref $separator;
209              
210 0 0         if ( my $mark = Text::Clip->new( data => $document )->find( qr/^\s*$separator\s*$/m ) ) {
211 0           return ( $mark->preceding, $mark->remaining );
212             }
213              
214 0           return ( undef, $document );
215             }
216              
217             #-----------------------------------------------------------------------------
218              
219             sub join {
220 0     0 0   my $self = shift;
221 0           my $preamble = shift;
222 0           my $content = shift;
223              
224 0 0         return $content unless defined $preamble;
225 0           chomp $preamble;
226              
227 0           my $separator = $self->separator;
228 0 0         unless ( defined $separator ) {
229 0 0         return $content unless length $preamble;
230 0           return join "\n", $preamble, $content;
231             }
232 0 0         return join "\n", $separator, $content unless length $preamble;
233 0           return join "\n", $preamble, $separator, $content;
234             }
235              
236             #-----------------------------------------------------------------------------
237             1;
238              
239             =pod
240              
241             =encoding UTF-8
242              
243             =for :stopwords Jeffrey Ryan Thalhammer
244              
245             =head1 NAME
246              
247             Pinto::Editor::Edit - Internal class for Pinto::Editor
248              
249             =head1 VERSION
250              
251             version 0.14
252              
253             =head1 DESCRIPTION
254              
255             This is a forked version of L<Term::EditorEdit::Edit> which does not use the deprecated
256             module L<Any::Moose>. My thanks to Robert Krimen for authoring the original.
257             No user-servicable parts in here.
258              
259             =head1 AUTHOR
260              
261             Jeffrey Ryan Thalhammer <jeff@stratopan.com>
262              
263             =head1 COPYRIGHT AND LICENSE
264              
265             This software is copyright (c) 2015 by Jeffrey Ryan Thalhammer.
266              
267             This is free software; you can redistribute it and/or modify it under
268             the same terms as the Perl 5 programming language system itself.
269              
270             =cut
271              
272             __END__
273              
274             #-----------------------------------------------------------------------------
275