воскресенье, 25 сентября 2011 г.

My life is in the editor Padre

My acquaintance with Padre

Of course for the Perl programming before and I've used Emacs and Vim (and I use it now, if you need something quickly edit or view). It all started when I looked up movie genius programmer Gabor Szabo, but the Padre plugin I have not earned.

YAPC::EU RIGA 2011

I went to YAPC::Europe 2011 “Modern Perl” and there on kahatone, Gabor explained what is my mistake, it turns out I could not activate (My.pm) plug-in, because I just stood an old version of the variable and must be changed from 0.40 to 0.66

The following code plug My.pm

sub padre_interfaces {
return (
'Padre::Plugin' => 0.66,
'Padre::Constant' => 0.66,
);
}

Excellent, I thought, very simple plugin that shows information about Padre (self-> show_about)

earned:

sub show_about {
my $self = shift;

# Locate this plugin
my $path = File::Spec->catfile(
Padre::Constant::CONFIG_DIR,
qw{ plugins Padre Plugin My.pm }
);

# Generate the About dialog
my $about = Wx::AboutDialogInfo->new;
$about->SetName('My Plug-in');
$about->SetDescription( <<"END_MESSAGE" );
The philosophy behind Padre is that every Perl programmer
should be able to easily modify and improve their own editor.

To help you get started, we've provided you with your own plug-in.

It is located in your configuration directory at:
$path
Open it with with Padre and you'll see an explanation on how to add items.
END_MESSAGE

# Show the About dialog
Wx::AboutBox($about);

return;
}
Maybe you can come up with something interesting. In the beginning, I had a problem just replace the slashes with \ (windows) on / (unix) elementary problem, but I had to change them often and would once have to write a regular expression for it, hang it on the menu, and it is better to shortcut and forget about it.

and I wrote a simple macro

sub replace_slash {
    my $self = shift;
    my $main = $self->main;

    my $doc = Padre::Current->document;
    my $text = $doc->text_get();
    $text =~ s#\\#/#g;
    $doc->text_set($text);

    return;
}

I was tied to a menu

menu

sub menu_plugins_simple {
    my $self = shift;
    return $self->plugin_name => [
        'About' => sub { $self->show_about },

        '&Replace_slash' => sub { $self->replace_slash },
    ];
}
and was happy, at any time I could now call him the menu. Then I needed to delete the numbers after you copy text from the VI with parameter set nu

replace_start_digit

sub replace_start_digit {
    my $self = shift;
    my $main = $self->main;

    my $doc = Padre::Current->document;
    my $text = $doc->text_get();
    $text =~ s/^\s*[0-9]//mg;
    $doc->text_set($text);
    return;
}

 

PerlCritic - Graphical Interface from ActivePerl

Then I remembered that I really like perlcritic from ActiveState and would like to call it directly from Padre

run_perlcritic_from_activeperl

sub run_perlcritic_from_activeperl {
    my $self = shift;
    my $main = $self->main;
    my $doc = Padre::Current->document;

    my $filename = $doc->filename;

    my $exec_shell =
q{C:\Perl\bin\wperl.exe -x "C:\Perl\bin\perlcritic-gui" c:\Users\nmishin\Documents\git\perlcritic\perlcritic_profile.perlcriticrc }
      . $filename
      . q{ --run};
    $main->message($exec_shell);

    my $a = run_shell($exec_shell);
    return;
}

sub run_shell {
    my ($cmd) = @_;
use IPC::Open3 'open3';
use Carp;
use English qw(-no_match_vars);

    my @args = ();
    my $EMPTY = q{};
    my $ret = undef;
    my ( $HIS_IN, $HIS_OUT, $HIS_ERR ) = ( $EMPTY, $EMPTY, $EMPTY );
    my $childpid = open3( $HIS_IN, $HIS_OUT, $HIS_ERR, $cmd, @args );
    $ret = print {$HIS_IN} "stuff\n";
    close $HIS_IN or croak "unable to close: $HIS_IN $ERRNO";
    ; # Give end of file to kid.

    if ($HIS_OUT) {
        my @outlines = <$HIS_OUT>; # Read till EOF.
        $ret = print " STDOUT:\n", @outlines, "\n";
    }
    if ($HIS_ERR) {
        my @errlines = <$HIS_ERR>; # XXX: block potential if massive
        $ret = print " STDERR:\n", @errlines, "\n";
    }
    close $HIS_OUT or croak "unable to close: $HIS_OUT $ERRNO";

    #close $HIS_ERR or croak "unable to close: $HIS_ERR $ERRNO";#bad..todo
    waitpid $childpid, 0;
    if ($CHILD_ERROR) {
        $ret = print "That child exited with wait status of $CHILD_ERROR\n";
    }
    return 1;
}
 
and the padre irc helped me, saying how to invoke a command keyboard shortcut is a talented hacker Alias​​and I was able,

written so

sub menu_plugins_simple {
    my $self = shift;
    return $self->plugin_name => [
        'About' => sub { $self->show_about },

        '&Replace_slash' => sub { $self->replace_slash },
        'Replace_start_digit' => sub { $self->replace_start_digit },
        "Run_perlcritic_from_activeperl\tCtrl-Alt-F3" =>
          sub { $self->run_perlcritic_from_activeperl },
    ];
}

 
perlcritic start with the visual interface of Activestate directly from the Padre by Ctrl-Alt-F3.

Improving macro replacement (edit)

At the macro described above have the disadvantage - it makes the changes with only 1 line of text, I decided to correct this assumption by adding a function

change_text

sub change_text {
    my $self = shift;
    my $replace_text = shift;
    my $main = $self->main;
    my $doc = Padre::Current->document;
    my $text = $doc->text_get();

    my @all_text_lines = split "\n", $text;
    my $out_line = "";

    #change every line in text
    for my $current_line (@all_text_lines) {
        $out_line .= &$replace_text($current_line);
    }

    $doc->text_set($out_line);
    return;
}

 
and now you can write the following function

type

sub jira_link2 {
    my $self = shift;

    my $ref_replace_text = sub {
        my $in_text = shift;
        $in_text =~
s{([A-Z]+-\d+)\s+}{[$1\|http://jira.gto.intranet.db.com:2020/jira/browse/$1]};
        return $in_text;
    };

    change_text( $self, $ref_replace_text );
    return;
}

sub selace_space {
    my $self = shift;

    my $ref_replace_text = sub {
        my $in_text = shift;

        ###Change this text
        $in_text =~ s{(\w+)\s+(\w+)\s+(\w+)}{$1,$2,$3};

        return $in_text;
    };

    change_text( $self, $ref_replace_text );
    return;
}

sub word_to_sql {
    my $self = shift;

    #Mon Sep 19 20:42:12 2011
    #C:\Users\nmishin\AppData\Local\Perl\Padre\plugins\Padre\Plugin\My.pm
    #11619

    my $ref_replace_text = sub {
        my $in_text = shift;

        ###Change this text
        $in_text =~ s{(\w+)}{'$1',};

        return $in_text;
    };

    change_text( $self, $ref_replace_text );
    return;
}

 
without thinking how they will work in the Padre, and thinking only of the right regular expression and I even wrote a template for it

template_of_replace

sub template_of_replace {
    my $self = shift;
    my $main = $self->main;

    my $doc = Padre::Current->document;
    my $text = $doc->text_get();
    my $template = <<'END_MESSAGE';
sub word_to_sql {
my $self = shift;

my $ref_replace_text = sub {
my $in_text = shift;
###Change this text
$in_text =~ s{(\w+)}{'$1',};
return $in_text;
};

change_text( $self, $ref_replace_text );
return;
}
END_MESSAGE

    my $editor = Padre::Current->editor;
    $editor->ReplaceSelection('');
    my $pos = $editor->GetCurrentPos;
    $editor->InsertText( $pos, $template );
    return;
}

 
These macros are greatly simplified my life, especially since the idea for them can be easily found in the sources of the priest, for example in the same plugin perltidy.

Find ideas in the source code.

Padre has a wonderful property, as in Delphi, when you click on the name of the module with the mouse while holding CTRL, and it is in the array @ INC is the module, it opens in the editor and we can see how it is implemented, and in the status bar you can see the path to module on it we can see that all modules are in the Padre directory c:\Strawberry\perl\site\lib\Padre. Better yet, say

Search->Find in files CTRL-SHIFT-F...

and then write in the search area, for example, 'Perl Tidy' (the name of a menu item, which theoretically should be in the target module):
after that you can see the path to the module
with the required functionality (such as I was looking for work in selected text) and open it in a Padre.  

Working with a database of Padre

And the last. At work, I work with DBMS Oracle. Module DBD:: Oracle I have not managed to install on Windows 7, but under cygwin it successfully compiled. And his tests I run in cygwin. I also use sqlsh. It turns out that if you call cygwin's perl, then DBD:: Oracle can see and connect to the database. Using

cygwin_here.bat

@echo off
REM --- cygwin_here.bat ------------------------------------------------------
REM function: Start Cygwin in current directory
REM args: - 1..9

REM Setting `CHERE_INVOKING' prevents /etc/profile from issuing `cd $HOME'
set CHERE_INVOKING=1
C:\cygwin\bin\bash --login -i %1 %2 %3 %4 %5 %6 %7 %8 %9

 
You can call from cygwin using sqlsh

interactive mode

c:\cygwin\cygwin_here.bat sqlsh -d DBI:Oracle:BUSINESS.DE.DB.COM -u mishnik -p password -i < c:\Users\nmishin\Documents\svn\misc\chunk_status\sqlsh_command.sqlsh
 
As well as refusing to load bash_completion.sh (mv /etc/profile.d/bash_completion.sh{,.disabled}) , which has accelerated running cygwin. And then I wrote a wrapper in Padre:

execute_selection_in_oracle

sub execute_selection_in_oracle {
    my $main = shift;

    # Tidy the current selected text
    my $current = $main->current;
    my $text = $current->text;

    # Generate the About dialog
    #my $about = Wx::AboutDialogInfo->new;
    #$about->SetName('Show_selection');

    use File::Temp qw/ tempfile tempdir /;

    #$fh = tempfile();
    #my ( $fh, $out_file ) = tempfile();
    my ( undef, $out_file ) = tempfile(
        'tmp_sql_XXXXXX',
        OPEN => 0,
        UNLINK => 0,
        DIR => 'c:/Users/nmishin/Documents/git/cygwin',
        SUFFIX => '.dat',
    );

    my ( undef, $log_file ) = tempfile(
        'tmp_log_XXXXXX',
        OPEN => 0,
        UNLINK => 0,
        DIR => 'c:/Users/nmishin/Documents/git/cygwin',
        SUFFIX => '.dat',
    );

    my ( undef, $query_file ) = tempfile(
        'tmp_qry_XXXXXX',
        OPEN => 0,
        UNLINK => 0,
        DIR => 'c:/Users/nmishin/Documents/git/cygwin',
        SUFFIX => '.dat',
    );

    #my $out_file = get_temp_filename();
    if ( $text !~ m/;/xms ) { $text .= ';' }

    #print "file:$filename\n";
    my $sqlsqh_command = <<"END_SQLSQH_COMMAND";
set multiline on;
ALTER SESSION SET NLS_DATE_FORMAT = 'DD.MM.YYYY HH24:MI';
ALTER SESSION SET CURRENT_SCHEMA = RWA_OWNER;
set log-mode box;
log commands $log_file;
log queries $query_file;
$text
no log;
exit;
END_SQLSQH_COMMAND

    my $main_object = $main->main;
    $main_object->message($sqlsqh_command);

    open my $out, '>', $out_file
      or croak "Couldn't open '$out_file': $OS_ERROR";
    print {$out} $sqlsqh_command
      or croak "Couldn't write '$out_file': $OS_ERROR";
    close $out or croak "Couldn't close '$out_file': $OS_ERROR";

#c:\cygwin\cygwin_here.bat sqlsh -d DBI:Oracle:BUSINESS.DE.DB.COM -u mishnik -p password -i < c:\Users\nmishin\Documents\svn\misc\chunk_status\sqlsh_command.sqlsh

    my $exec_shell =
q{c:\cygwin\cygwin_here.bat sqlsh -d DBI:Oracle:BUSINESS.DE.DB.COM -u mishnik -p password -i < }
      . $out_file;

    $main_object->message($exec_shell);
    my $cmd_file = 'c:/Users/nmishin/Documents/git/cygwin/sqlsh_command.bat';
    open my $cmd_out, '>', $cmd_file
      or croak "Couldn't open '$cmd_file': $OS_ERROR";
    print {$cmd_out} $exec_shell
      or croak "Couldn't write '$cmd_file': $OS_ERROR";
    close $cmd_out or croak "Couldn't close '$cmd_file': $OS_ERROR";

    # $main->message($exec_shell);

    my $a = run_shell($exec_shell);

    my $sql_result = $text . "\n" . read_file($query_file);

    my $editor = Padre::Current->editor;
    $editor->ReplaceSelection('');
    my $pos = $editor->GetCurrentPos;
    $editor->InsertText( $pos, $sql_result );
    return;

}

 
And now on Ctrl-Alt-F7 I have selected in the Padre select run in gywin 's TV sqlsh and the result is returned to the editor. Super. I'm happy.

Final menu_plugins_simple

sub menu_plugins_simple {
    my $self = shift;
    return $self->plugin_name => [
        'About' => sub { $self->show_about },

        '&Replace_slash' => sub { $self->replace_slash },
        'Replace_start_digit' => sub { $self->replace_start_digit },
        "Run_perlcritic_from_activeperl\tCtrl-Alt-F3" =>
          sub { $self->run_perlcritic_from_activeperl },
        'Template_of_module' => sub { $self->template_of_module },

        "Jira_link\tCtrl-Alt-F5" => sub { $self->jira_link2 },
        "Replace_Space\tCtrl-Alt-F6" => sub { $self->seplace_space },
        "Word_to_sql" => sub { $self->word_to_sql },
        "Template_of_replace" => sub { $self->template_of_replace },
        "Execute_selection_in_Oracle\tCtrl-Alt-F7" =>
          sub { $self->execute_selection_in_oracle },

        'Date_time' => sub { $self->date_time },

        # 'A Sub-Menu...' => [
        # 'Sub-Menu Entry' => sub { $self->yet_another_method },
        # ],
    ];
}

 
On github is the final version of my plugin. Thank you all for your attention.

0 коммент.:

Отправить комментарий