133
143
#####################################################################
134
144
# Padre::Document Document Analysis
149
# Don't attempt a content-based guess if the file already has a name.
150
if ( $self->filename ) {
151
return $self->SUPER::guess_filename;
155
my $text = $self->text_get;
156
if ( $text =~ /^\#\![^\n]*\bperl\b/s ) {
158
# It's impossible to predict the name of a script in
159
# advance, but lets default to a standard "script.pl"
164
if ( $text =~ /\bpackage\s*([\w\:]+)/s ) {
166
# Take the last section of the package name, and use that
173
214
? $self->store_in_tempfile
174
215
: $self->filename;
176
# Run with the same Perl that launched Padre
177
# TODO: get preferred Perl from configuration
178
my $perl = Padre->perl_interpreter;
217
# Run with console Perl to prevent unexpected results under wperl
218
# The configuration values is cheaper to get compared to cperl(),
220
my $perl = $config->run_perl_cmd;
222
# Warn if the Perl interpreter is not executable:
223
if ( defined($perl) and ( $perl ne '' ) and ( !-x $perl ) ) {
224
my $ret = Wx::MessageBox(
226
sprintf( '%s seems to be no executable Perl interpreter, use the system default perl instead?', $perl )
229
Wx::wxYES_NO | Wx::wxCENTRE,
230
Padre->ide->wx->main,
232
$perl = Padre::Perl::cperl()
233
if $ret == Wx::wxYES;
236
$perl = Padre::Perl::cperl();
180
239
# Set default arguments
189
248
$run_args{$arg} = Padre::DB::History->previous($type) if Padre::DB::History->previous($type);
251
# (Ticket #530) Pack args here, because adding the space later confuses the called Perls @ARGV
252
my $Script_Args = '';
253
$Script_Args = ' ' . $run_args{script} if defined( $run_args{script} ) and ( $run_args{script} ne '' );
192
255
my $dir = File::Basename::dirname($filename);
195
? qq{"$perl" -Mdiagnostics(-traceonly) $run_args{interpreter} "$filename" $run_args{script}}
196
: qq{"$perl" $run_args{interpreter} "$filename" $run_args{script}};
258
? qq{"$perl" -Mdiagnostics(-traceonly) $run_args{interpreter} "$filename"$Script_Args}
259
: qq{"$perl" $run_args{interpreter} "$filename"$Script_Args};
199
262
sub pre_process {
558
sub extract_subroutine {
559
my ( $self, $newname ) = @_;
561
my $editor = $self->editor;
562
my $code = $editor->GetSelectedText();
564
my $sub_comment = <<EOC;
566
# New subroutine extracted.
570
# we want to get a list of the subroutines to pick where to place
572
my @functions = $self->get_functions;
574
#print "printing the functions: " . join( "\n", @functions );
576
# Show a list of functions
577
require Padre::Wx::Dialog::RefactorSelectFunction;
578
my $dialog = Padre::Wx::Dialog::RefactorSelectFunction->new( $editor->main, \@functions );
580
if ( $dialog->{cancelled} ) {
584
# testing for now hard set:
585
#my $subname = 'testing2';
588
my $subname = $dialog->get_function_name;
590
# get the new code, replace the selection
591
require Devel::Refactor;
592
my $refactory = Devel::Refactor->new;
593
my ( $new_sub_call, $new_code ) = $refactory->extract_subroutine( $newname, $code, 1 );
595
# make the change to the selected text
596
$editor->BeginUndoAction(); # do the edit atomically
597
$editor->ReplaceSelection($new_sub_call);
599
# with the change made
600
# locate the function:
601
my ( $start, $end ) = Padre::Util::get_matches(
603
$self->get_function_regex($subname),
604
$editor->GetSelection, # Provides two params
606
unless ( defined $start ) {
608
# This needs to now rollback the
609
# the changes made with the editor
611
$editor->EndUndoAction();
615
#print "Couldn't find the sub: $subname\n";
619
# now instert the text into the right location
620
my $data = Wx::TextDataObject->new;
621
$data->SetText( $sub_comment . $new_code );
622
my $length = $data->GetTextLength;
624
$editor->InsertText( $start, $data->GetText );
625
$editor->EndUndoAction();
631
# This sub handles a cached C-Tags - Parser object which is much faster
632
# than recreating it on every autocomplete
634
sub _perltags_parser {
637
require Parse::ExuberantCTags;
639
my $perltags_file = $self->{_perltags_file};
641
# Temporary until this is configurable:
642
if ( !defined($perltags_file) ) {
643
$self->{_perltags_file} = File::Spec->catfile( $ENV{PADRE_HOME}, 'perltags' );
644
$perltags_file = $self->{_perltags_file};
647
# If we don't have a file (none specified in config, for example), return undef
648
# as the object and noone will try to use it
649
return undef if !defined($perltags_file);
653
# Use the cached parser if
655
# - the last check is younger than 5 seconds (don't check the file again)
656
# or the file's mtime matches our cached mtime
657
if ( defined( $self->{_perltags_parser} )
658
and defined( $self->{_perltags_parser_time} )
659
and ( ( $self->{_perltags_parser_last} > ( time - 5 ) )
660
or ( $self->{_perltags_parser_time} == ( stat($perltags_file) )[9] ) )
663
$parser = $self->{_perltags_parser};
664
$self->{_perltags_parser_last} = time;
666
$parser = Parse::ExuberantCTags->new($perltags_file);
667
$self->{_perltags_parser} = $parser;
668
$self->{_perltags_parser_time} = ( stat($perltags_file) )[9];
669
$self->{_perltags_parser_last} = time;
467
675
sub autocomplete {
468
676
my $self = shift;
733
elsif ( $prefix =~ /(\$\w+(?:\-\>)?)\{([\'\"]?)([\$\&]?\w*)$/ ) {
738
my $last = $editor->GetLength();
739
my $text = $editor->GetTextRange( 0, $last );
742
while ( $text =~ /\Q$hashname\E\{(([\'\"]?)\Q$keyprefix\E.+?\2)\}/g ) {
747
length( $textmarker . $keyprefix ),
751
$a1 =~ s/^([\'\"])(.+)\1/$2/;
752
$b1 =~ s/^([\'\"])(.+)\1/$2/;
522
759
# check for methods
523
760
elsif ( $prefix =~ /(?![\$\@\%\*])(\w+(?:::\w+)*)\s*->\s*(\w*)$/ ) {
526
763
$prefix = '' if not defined $prefix;
527
my $parser = Parse::ExuberantCTags->new( File::Spec->catfile( $ENV{PADRE_HOME}, 'perltags' ) );
764
my $parser = $self->_perltags_parser;
528
765
if ( defined $parser ) {
529
766
my $tag = ( $prefix eq '' ) ? $parser->firstTag() : $parser->findTag( $prefix, partial => 1 );
597
835
return ( length($prefix), @words );
838
sub newline_keep_column {
841
my $editor = $self->editor or return;
842
my $pos = $editor->GetCurrentPos;
843
my $line = $editor->LineFromPosition($pos);
844
my $first = $editor->PositionFromLine($line);
845
my $col = $pos - $editor->PositionFromLine( $editor->LineFromPosition($pos) );
846
my $text = $editor->GetTextRange( $first, ( $pos - $first ) );
848
$editor->AddText( $self->newline );
850
$pos = $editor->GetCurrentPos;
851
$first = $editor->PositionFromLine( $editor->LineFromPosition($pos) );
853
# my $col2 = $pos - $first;
854
# $editor->AddText( ' ' x ( $col - $col2 ) );
856
# TODO: Remove the part made by auto-ident before addtext:
857
$text =~ s/[^\s\t\r\n]/ /g;
858
$editor->AddText($text);
860
$editor->SetCurrentPos( $first + $col );
600
865
sub event_on_char {
601
866
my ( $self, $editor, $event ) = @_;
868
my $config = Padre->ide->config;
869
my $main = Padre->ide->wx->main;
604
873
my $selection_exists = 0;
917
# This only matches if all conditions are met:
918
# - config option enabled
919
# - none of the following keys pressed: a-z, A-Z, 0-9, _
920
# - cursor position is at end of line
921
if ($config->autocomplete_method
923
or ( ( $key > 57 ) and ( $key < 65 ) )
924
or ( ( $key > 90 ) and ( $key < 95 ) )
927
and ( $pos == $last )
931
# from beginning to current position
932
my $prefix = $editor->GetTextRange( 0, $pos );
934
# methods can't live outside packages, so ignore them
935
if ( $prefix =~ /package / ) {
936
my $linetext = $editor->GetTextRange( $first, $last );
938
# we only match "sub foo" at the beginning of a line
939
# but no inline subs (eval, anonymus, etc.)
940
# The end-of-subname match is included in the first if
941
# which match the last key pressed (which is not part of
942
# $linetext at this moment:
943
if ( $linetext =~ /^sub[\s\t]+\w+$/ ) {
945
# Add the default skeleton of a method,
946
# the \t should be replaced by
947
# (space * current_indent_width)
948
$editor->AddText( ' {'
949
. $self->newline . "\t"
950
. 'my $self = shift;'
951
. $self->newline . "\t"
952
. $self->newline . '}'
956
# Ready for typing in the new method:
957
$editor->GotoPos( $last + 23 );
965
$main->on_autocompletion if $config->autocomplete_always;
658
980
if ( $event->isa("Wx::MouseEvent") ) {
659
981
my $point = $event->GetPosition();
660
$pos = $editor->PositionFromPoint($point);
982
if ( $point != Wx::wxDefaultPosition ) {
984
# Then it is really a mouse event...
985
# On Windows, context menu is faked
987
$pos = $editor->PositionFromPoint($point);
663
993
# Fall back to the cursor position
664
$editor->GetCurrentPos();
994
$pos = $editor->GetCurrentPos();
667
997
my $introduced_separator = 0;