| 41 | | my $self = shift; |
| 42 | | return $self->plugin_name => [ |
| 43 | | Wx::gettext( "Tidy the active document\tAlt+Shift+F" ) => |
| 44 | | \&tidy_document, |
| 45 | | Wx::gettext( "Tidy the selected text\tAlt+Shift+G" ) => |
| 46 | | \&tidy_selection, |
| 47 | | Wx::gettext( 'Export active document to HTML file' ) => |
| 48 | | \&export_document, |
| 49 | | Wx::gettext( 'Export selected text to HTML file' ) => |
| 50 | | \&export_selection, |
| 51 | | ]; |
| | 46 | my $self = shift; |
| | 47 | return $self->plugin_name => [ |
| | 48 | Wx::gettext("Tidy the active document\tAlt+Shift+F") => \&tidy_document, |
| | 49 | Wx::gettext("Tidy the selected text\tAlt+Shift+G") => |
| | 50 | \&tidy_selection, |
| | 51 | '---' => undef, |
| | 52 | Wx::gettext('Export active document to HTML file') => |
| | 53 | \&export_document, |
| | 54 | Wx::gettext('Export selected text to HTML file') => |
| | 55 | \&export_selection, |
| | 56 | ]; |
| 55 | | my ( $main, $src ) = @_; |
| 56 | | |
| 57 | | require Perl::Tidy; |
| 58 | | |
| 59 | | return unless defined $src; |
| 60 | | |
| 61 | | my $doc = $main->current->document; |
| 62 | | |
| 63 | | if ( !$doc->isa( 'Padre::Document::Perl' ) ) { |
| 64 | | return Wx::MessageBox( |
| 65 | | Wx::gettext( 'Document is not a Perl document' ), |
| 66 | | Wx::gettext( 'Error' ), |
| 67 | | Wx::wxOK | Wx::wxCENTRE, $main |
| 68 | | ); |
| 69 | | } |
| 70 | | |
| 71 | | my ( $output, $error ); |
| 72 | | my %tidyargs = ( |
| 73 | | argv => \'-nse -nst', |
| 74 | | source => \$src, |
| 75 | | destination => \$output, |
| 76 | | errorfile => \$error, |
| 77 | | ); |
| 78 | | |
| 79 | | if ( my $tidyrc = $doc->project->config->config_perltidy ) { |
| 80 | | $tidyargs{ perltidyrc } = $tidyrc; |
| 81 | | Padre::Current->main->output->AppendText( |
| 82 | | "Perl\::Tidy running with project-specific configuration $tidyrc\n" |
| 83 | | ); |
| 84 | | } |
| 85 | | else { |
| 86 | | Padre::Current->main->output->AppendText( |
| 87 | | "Perl\::Tidy running with default or user configuration\n" ); |
| 88 | | } |
| 89 | | |
| 90 | | # TODO: suppress the senseless warning from PerlTidy |
| 91 | | eval { Perl::Tidy::perltidy( %tidyargs ); }; |
| 92 | | |
| 93 | | if ( $@ ) { |
| 94 | | my $error_string = $@; |
| 95 | | Wx::MessageBox( |
| 96 | | $error_string, |
| 97 | | Wx::gettext( "PerlTidy Error" ), |
| 98 | | Wx::wxOK | Wx::wxCENTRE, $main |
| 99 | | ); |
| 100 | | return; |
| 101 | | } |
| 102 | | |
| 103 | | if ( defined $error ) { |
| 104 | | my $width = length( $doc->filename ) + 2; |
| 105 | | Padre::Current->main->output->AppendText( "\n\n" |
| 106 | | . "-" x $width . "\n" |
| 107 | | . $doc->filename . "\n" |
| 108 | | . "-" x $width |
| 109 | | . "\n" ); |
| 110 | | Padre::Current->main->output->AppendText( "$error\n" ); |
| 111 | | Padre::Current->main->show_output( 1 ); |
| 112 | | } |
| 113 | | return $output; |
| | 60 | my $main = shift; |
| | 61 | my $current = shift; |
| | 62 | my $source = shift; |
| | 63 | my $document = $current->document; |
| | 64 | |
| | 65 | # Check for problems |
| | 66 | unless ( defined $source ) { |
| | 67 | return; |
| | 68 | } |
| | 69 | unless ( $document->isa('Padre::Document::Perl') ) { |
| | 70 | return Wx::MessageBox( |
| | 71 | Wx::gettext('Document is not a Perl document'), |
| | 72 | Wx::gettext('Error'), |
| | 73 | Wx::wxOK | Wx::wxCENTRE, |
| | 74 | $main |
| | 75 | ); |
| | 76 | } |
| | 77 | |
| | 78 | my $destination = undef; |
| | 79 | my $errorfile = undef; |
| | 80 | my %tidyargs = ( |
| | 81 | argv => \'-nse -nst', |
| | 82 | source => \$source, |
| | 83 | destination => \$destination, |
| | 84 | errorfile => \$errorfile, |
| | 85 | ); |
| | 86 | |
| | 87 | my $output = $main->output; |
| | 88 | my $perltidyrc = $document->project->config->config_perltidy; |
| | 89 | if ($perltidyrc) { |
| | 90 | $tidyargs{perltidyrc} = $perltidyrc; |
| | 91 | $output->AppendText("Perl::Tidy running with project configuration $perltidyrc\n"); |
| | 92 | } else { |
| | 93 | $output->AppendText("Perl::Tidy running with default or user configuration\n"); |
| | 94 | } |
| | 95 | |
| | 96 | # TODO: suppress the senseless warning from PerlTidy |
| | 97 | require Perl::Tidy; |
| | 98 | eval { Perl::Tidy::perltidy(%tidyargs); }; |
| | 99 | |
| | 100 | if ($@) { |
| | 101 | Wx::MessageBox( |
| | 102 | $@, |
| | 103 | Wx::gettext("PerlTidy Error"), |
| | 104 | Wx::wxOK | Wx::wxCENTRE, |
| | 105 | $main |
| | 106 | ); |
| | 107 | return; |
| | 108 | } |
| | 109 | |
| | 110 | if ( defined $errorfile ) { |
| | 111 | my $filename = $document->filename; |
| | 112 | my $width = length($filename) + 2; |
| | 113 | $output->AppendText( "\n\n" . "-" x $width . "\n" . $filename . "\n" . "-" x $width . "\n" ); |
| | 114 | $output->AppendText("$errorfile\n"); |
| | 115 | $main->show_output(1); |
| | 116 | } |
| | 117 | |
| | 118 | return $destination; |
| 117 | | my ( $main, $event ) = @_; |
| 118 | | my $src = $main->current->text; |
| 119 | | |
| 120 | | my $newtext = _tidy( $main, $src ); |
| 121 | | |
| 122 | | return unless defined $newtext && length $newtext; |
| 123 | | |
| 124 | | $newtext =~ s{\n$}{}; |
| 125 | | |
| 126 | | my $editor = $main->current->editor; |
| 127 | | $editor->ReplaceSelection( $newtext ); |
| | 122 | my $main = shift; |
| | 123 | |
| | 124 | # Tidy the current selected text |
| | 125 | my $current = $main->current; |
| | 126 | my $text = $current->text; |
| | 127 | my $tidy = _tidy( $main, $current, $text ); |
| | 128 | unless ( defined Params::Util::_STRING($tidy) ) { |
| | 129 | return; |
| | 130 | } |
| | 131 | |
| | 132 | # If the selected text does not have a newline at the end, |
| | 133 | # trim off any that Perl::Tidy has added. |
| | 134 | unless ( $text =~ /\n\z/ ) { |
| | 135 | $tidy =~ s{\n\z}{}; |
| | 136 | } |
| | 137 | |
| | 138 | # Overwrite the selected text |
| | 139 | $current->editor->ReplaceSelection($tidy); |
| 131 | | my ( $main, $event ) = @_; |
| 132 | | |
| 133 | | my $doc = $main->current->document; |
| 134 | | my $src = $doc->text_get; |
| 135 | | |
| 136 | | my $newtext = _tidy( $main, $src ); |
| 137 | | |
| 138 | | return unless defined $newtext && length $newtext; |
| 139 | | |
| 140 | | my ( $regex, $start ) = _store_cursor_position( $main ); |
| 141 | | $doc->text_set( $newtext ); |
| 142 | | _restore_cursor_position( $main, $regex, $start ); |
| | 143 | my $main = shift; |
| | 144 | |
| | 145 | # Tidy the entire current document |
| | 146 | my $current = $main->current; |
| | 147 | my $document = $current->document; |
| | 148 | my $text = $document->text_get; |
| | 149 | my $tidy = _tidy( $main, $current, $text ); |
| | 150 | unless ( defined Params::Util::_STRING($tidy) ) { |
| | 151 | return; |
| | 152 | } |
| | 153 | |
| | 154 | # Overwrite the entire document |
| | 155 | my ( $regex, $start ) = _store_cursor_position($current); |
| | 156 | $document->text_set($tidy); |
| | 157 | _restore_cursor_position( $current, $regex, $start ); |
| 146 | | my $main = shift; |
| 147 | | |
| 148 | | my $doc = $main->current->document or return; |
| 149 | | my $current = $doc->filename; |
| 150 | | my $default_dir = ''; |
| 151 | | |
| 152 | | if ( defined $current ) { |
| 153 | | require File::Basename; |
| 154 | | $default_dir = File::Basename::dirname( $current ); |
| 155 | | } |
| 156 | | |
| 157 | | require File::Spec; |
| 158 | | |
| 159 | | while ( 1 ) { |
| 160 | | my $dialog = Wx::FileDialog->new( |
| 161 | | $main, Wx::gettext( "Save file as..." ), |
| 162 | | $default_dir, $doc->filename . '.html', |
| 163 | | "*.*", Wx::wxFD_SAVE, |
| 164 | | ); |
| 165 | | if ( $dialog->ShowModal == Wx::wxID_CANCEL ) { |
| 166 | | return; |
| 167 | | } |
| 168 | | my $filename = $dialog->GetFilename; |
| 169 | | $default_dir = $dialog->GetDirectory; |
| 170 | | my $path = File::Spec->catfile( $default_dir, $filename ); |
| 171 | | if ( -e $path ) { |
| 172 | | my $res = Wx::MessageBox( |
| 173 | | Wx::gettext( "File already exists. Overwrite it?" ), |
| 174 | | Wx::gettext( "Exist" ), |
| 175 | | Wx::wxYES_NO, $main, |
| 176 | | ); |
| 177 | | if ( $res == Wx::wxYES ) { |
| 178 | | return $path; |
| 179 | | } |
| 180 | | } |
| 181 | | else { |
| 182 | | return $path; |
| 183 | | } |
| 184 | | } |
| | 161 | my $main = shift; |
| | 162 | |
| | 163 | my $doc = $main->current->document or return; |
| | 164 | my $current = $doc->filename; |
| | 165 | my $default_dir = ''; |
| | 166 | |
| | 167 | if ( defined $current ) { |
| | 168 | require File::Basename; |
| | 169 | $default_dir = File::Basename::dirname($current); |
| | 170 | } |
| | 171 | |
| | 172 | require File::Spec; |
| | 173 | |
| | 174 | while (1) { |
| | 175 | my $dialog = Wx::FileDialog->new( |
| | 176 | $main, Wx::gettext("Save file as..."), |
| | 177 | $default_dir, $doc->filename . '.html', |
| | 178 | "*.*", Wx::wxFD_SAVE, |
| | 179 | ); |
| | 180 | if ( $dialog->ShowModal == Wx::wxID_CANCEL ) { |
| | 181 | return; |
| | 182 | } |
| | 183 | my $filename = $dialog->GetFilename; |
| | 184 | $default_dir = $dialog->GetDirectory; |
| | 185 | my $path = File::Spec->catfile( $default_dir, $filename ); |
| | 186 | if ( -e $path ) { |
| | 187 | my $res = Wx::MessageBox( |
| | 188 | Wx::gettext("File already exists. Overwrite it?"), |
| | 189 | Wx::gettext("Exist"), |
| | 190 | Wx::wxYES_NO, $main, |
| | 191 | ); |
| | 192 | if ( $res == Wx::wxYES ) { |
| | 193 | return $path; |
| | 194 | } |
| | 195 | } else { |
| | 196 | return $path; |
| | 197 | } |
| | 198 | } |
| 188 | | my ( $main, $src ) = @_; |
| 189 | | |
| 190 | | require Perl::Tidy; |
| 191 | | |
| 192 | | return unless defined $src; |
| 193 | | |
| 194 | | my $doc = $main->current->document; |
| 195 | | |
| 196 | | if ( !$doc->isa( 'Padre::Document::Perl' ) ) { |
| 197 | | return Wx::MessageBox( |
| 198 | | Wx::gettext( 'Document is not a Perl document' ), |
| 199 | | Wx::gettext( 'Error' ), |
| 200 | | Wx::wxOK | Wx::wxCENTRE, $main |
| 201 | | ); |
| 202 | | } |
| 203 | | |
| 204 | | my $filename = _get_filename( $main ); |
| 205 | | |
| 206 | | return unless defined $filename; |
| 207 | | |
| 208 | | my ( $output, $error ); |
| 209 | | my %tidyargs = ( |
| 210 | | argv => \'-html -nnn -nse -nst', |
| 211 | | source => \$src, |
| 212 | | destination => $filename, |
| 213 | | errorfile => \$error, |
| 214 | | ); |
| 215 | | |
| 216 | | if ( my $tidyrc = $doc->project->config->config_perltidy ) { |
| 217 | | $tidyargs{ perltidyrc } = $tidyrc; |
| 218 | | Padre::Current->main->output->AppendText( |
| 219 | | "Perl\::Tidy running with project-specific configuration $tidyrc\n" |
| 220 | | ); |
| 221 | | } |
| 222 | | |
| 223 | | else { |
| 224 | | Padre::Current->main->output->AppendText( |
| 225 | | "Perl::Tidy running with default or user configuration\n" ); |
| 226 | | } |
| 227 | | |
| 228 | | # TODO: suppress the senseless warning from PerlTidy |
| 229 | | eval { Perl::Tidy::perltidy( %tidyargs ); }; |
| 230 | | |
| 231 | | if ( $@ ) { |
| 232 | | my $error_string = $@; |
| 233 | | Wx::MessageBox( |
| 234 | | $error_string, |
| 235 | | Wx::gettext( 'PerlTidy Error' ), |
| 236 | | Wx::wxOK | Wx::wxCENTRE, $main |
| 237 | | ); |
| 238 | | return; |
| 239 | | } |
| 240 | | |
| 241 | | if ( defined $error ) { |
| 242 | | my $width = length( $doc->filename ) + 2; |
| 243 | | my $main = Padre::Current->main; |
| 244 | | $main->output->AppendText( "\n\n" |
| 245 | | . "-" x $width . "\n" |
| 246 | | . $doc->filename . "\n" |
| 247 | | . "-" x $width |
| 248 | | . "\n" ); |
| 249 | | $main->output->AppendText( "$error\n" ); |
| 250 | | $main->show_output( 1 ); |
| 251 | | } |
| 252 | | |
| 253 | | return; |
| | 202 | my ( $main, $src ) = @_; |
| | 203 | |
| | 204 | require Perl::Tidy; |
| | 205 | |
| | 206 | return unless defined $src; |
| | 207 | |
| | 208 | my $doc = $main->current->document; |
| | 209 | |
| | 210 | if ( !$doc->isa('Padre::Document::Perl') ) { |
| | 211 | return Wx::MessageBox( |
| | 212 | Wx::gettext('Document is not a Perl document'), |
| | 213 | Wx::gettext('Error'), |
| | 214 | Wx::wxOK | Wx::wxCENTRE, $main |
| | 215 | ); |
| | 216 | } |
| | 217 | |
| | 218 | my $filename = _get_filename($main); |
| | 219 | |
| | 220 | return unless defined $filename; |
| | 221 | |
| | 222 | my ( $output, $error ); |
| | 223 | my %tidyargs = ( |
| | 224 | argv => \'-html -nnn -nse -nst', |
| | 225 | source => \$src, |
| | 226 | destination => $filename, |
| | 227 | errorfile => \$error, |
| | 228 | ); |
| | 229 | |
| | 230 | if ( my $tidyrc = $doc->project->config->config_perltidy ) { |
| | 231 | $tidyargs{perltidyrc} = $tidyrc; |
| | 232 | Padre::Current->main->output->AppendText("Perl\::Tidy running with project-specific configuration $tidyrc\n"); |
| | 233 | } |
| | 234 | |
| | 235 | else { |
| | 236 | Padre::Current->main->output->AppendText("Perl::Tidy running with default or user configuration\n"); |
| | 237 | } |
| | 238 | |
| | 239 | # TODO: suppress the senseless warning from PerlTidy |
| | 240 | eval { Perl::Tidy::perltidy(%tidyargs); }; |
| | 241 | |
| | 242 | if ($@) { |
| | 243 | my $error_string = $@; |
| | 244 | Wx::MessageBox( |
| | 245 | $error_string, |
| | 246 | Wx::gettext('PerlTidy Error'), |
| | 247 | Wx::wxOK | Wx::wxCENTRE, $main |
| | 248 | ); |
| | 249 | return; |
| | 250 | } |
| | 251 | |
| | 252 | if ( defined $error ) { |
| | 253 | my $width = length( $doc->filename ) + 2; |
| | 254 | my $main = Padre::Current->main; |
| | 255 | $main->output->AppendText( "\n\n" . "-" x $width . "\n" . $doc->filename . "\n" . "-" x $width . "\n" ); |
| | 256 | $main->output->AppendText("$error\n"); |
| | 257 | $main->show_output(1); |
| | 258 | } |
| | 259 | |
| | 260 | return; |
| 275 | | |
| 276 | | # parameter: $main, compiled regex |
| 277 | | my ( $main, $regex, $start ) = @_; |
| 278 | | my $doc = $main->current->document; |
| 279 | | my $editor = $doc->editor; |
| 280 | | my $text = $editor->GetTextRange( |
| 281 | | ( $start - SELECTIONSIZE ) > 0 ? $start - SELECTIONSIZE |
| 282 | | : 0, |
| 283 | | ( $start + SELECTIONSIZE < $editor->GetLength() ) |
| 284 | | ? $start + SELECTIONSIZE |
| 285 | | : $editor->GetLength() |
| 286 | | ); |
| 287 | | eval { |
| 288 | | if ( $text =~ /($regex)/ ) |
| 289 | | { |
| 290 | | my $pos = $start + length $1; |
| 291 | | $editor->SetCurrentPos( $pos ); |
| 292 | | $editor->SetSelection( $pos, $pos ); |
| 293 | | } |
| 294 | | }; |
| 295 | | $editor->goto_line_centerize( $editor->GetCurrentLine ); |
| 296 | | return; |
| 297 | | } |
| 298 | | |
| | 279 | my $current = shift; |
| | 280 | my $regex = shift; |
| | 281 | my $start = shift; |
| | 282 | my $editor = $current->editor; |
| | 283 | my $text = $editor->GetTextRange( |
| | 284 | ( $start - SELECTIONSIZE ) > 0 ? $start - SELECTIONSIZE |
| | 285 | : 0, |
| | 286 | ( $start + SELECTIONSIZE < $editor->GetLength ) ? $start + SELECTIONSIZE |
| | 287 | : $editor->GetLength |
| | 288 | ); |
| | 289 | eval { |
| | 290 | if ( $text =~ /($regex)/ ) |
| | 291 | { |
| | 292 | my $pos = $start + length $1; |
| | 293 | $editor->SetCurrentPos($pos); |
| | 294 | $editor->SetSelection( $pos, $pos ); |
| | 295 | } |
| | 296 | }; |
| | 297 | $editor->goto_line_centerize( $editor->GetCurrentLine ); |
| | 298 | return; |
| | 299 | } |
| | 300 | |
| | 301 | # parameter: $current |
| | 302 | # returns: compiled regex, start position |
| | 303 | # compiled regex is /^./ if no valid regex can be reconstructed. |
| 300 | | |
| 301 | | # parameter: $main |
| 302 | | # returns: compiled regex, start position |
| 303 | | # compiled regex is /^./ if no valid regex can be reconstructed. |
| 304 | | my $main = shift; |
| 305 | | my $doc = $main->current->document; |
| 306 | | my $editor = $doc->editor; |
| 307 | | my $pos = $editor->GetCurrentPos; |
| 308 | | my $start; |
| 309 | | |
| 310 | | if ( ( $pos - SELECTIONSIZE ) > 0 ) { |
| 311 | | $start = $pos - SELECTIONSIZE; |
| 312 | | } |
| 313 | | else { |
| 314 | | $start = 0; |
| 315 | | } |
| 316 | | my $prefix = $editor->GetTextRange( $start, $pos ); |
| 317 | | my $regex; |
| 318 | | eval { |
| 319 | | $prefix =~ s/(\W)/\\$1/gm; # Escape non-word chars |
| 320 | | $prefix |
| 321 | | =~ s/(\\\s+)/(\\s+|\\r*\\n)*/gm; # Replace whitespace by regex \s+ |
| 322 | | $regex = qr{$prefix}; |
| 323 | | }; |
| 324 | | if ( $@ ) { |
| 325 | | $regex = qw{^.}; |
| 326 | | print STDERR @_; |
| 327 | | } |
| 328 | | return ( $regex, $start ); |
| | 305 | my $current = shift; |
| | 306 | my $editor = $current->editor; |
| | 307 | my $pos = $editor->GetCurrentPos; |
| | 308 | |
| | 309 | my $start; |
| | 310 | if ( ( $pos - SELECTIONSIZE ) > 0 ) { |
| | 311 | $start = $pos - SELECTIONSIZE; |
| | 312 | } else { |
| | 313 | $start = 0; |
| | 314 | } |
| | 315 | |
| | 316 | my $prefix = $editor->GetTextRange( $start, $pos ); |
| | 317 | my $regex; |
| | 318 | eval { |
| | 319 | |
| | 320 | # Escape non-word chars |
| | 321 | $prefix =~ s/(\W)/\\$1/gm; |
| | 322 | |
| | 323 | # Replace whitespace by regex \s+ |
| | 324 | $prefix =~ s/(\\\s+)/(\\s+|\\r*\\n)*/gm; |
| | 325 | |
| | 326 | $regex = qr{$prefix}; |
| | 327 | }; |
| | 328 | if ($@) { |
| | 329 | $regex = qw{^.}; |
| | 330 | print STDERR @_; |
| | 331 | } |
| | 332 | return ( $regex, $start ); |