File Coverage

blib/lib/Padre/Plugin/Shell/Base.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Padre::Plugin::Shell::Base;
2              
3 1     1   20809 use 5.008;
  1         19  
  1         41  
4 1     1   6 use strict;
  1         2  
  1         35  
5 1     1   5 use warnings;
  1         7  
  1         40  
6 1     1   346 use Padre::Constant ();
  0            
  0            
7             use Padre::Current ();
8             use Padre::Wx ();
9             use File::Temp qw/ tempfile /;
10             use YAML qw/DumpFile LoadFile/;
11              
12             our $VERSION = '0.13';
13              
14             ########################################################################
15             #
16             sub new {
17             my $class = shift;
18             my $self = bless {}, $class;
19             return $self;
20             }
21              
22             sub plugin_menu {
23             warn "sub plugin_menu is missing!\n";
24             return undef;
25             }
26              
27             sub notify_of_error {
28             my ( $self, $message ) = @_;
29             Padre::Current->main->message( $message, Wx::gettext("Error") );
30             }
31              
32             ########################################################################
33             #
34             sub update_environment_vars {
35             my ($self) = @_;
36              
37             # Clear out the PE_* environment variables to ensure there are
38             # no previous values hanging around.
39             foreach my $var qw(PE_CURRENT_WORD
40             PE_CURRENT_LINE
41             PE_COLUMN_INDEX
42             PE_COLUMN_NUMBER
43             PE_LINE_INDEX
44             PE_LINE_NUMBER
45             PE_LINE_COUNT
46             PE_FILEPATH
47             PE_BASENAME
48             PE_DIRECTORY
49             PE_MIMETYPE
50             PE_CONFIG_DIR
51             PE_INDENT_TAB_WIDTH
52             PE_INDENT_WIDTH
53             PE_INDENT_TAB
54             PE_DEF_PROJ_DIR
55             ) {
56             delete $ENV{$var};
57             };
58              
59             # Configuration variables
60             my $padre_config = Padre::Current->main->ide->config;
61             if ($padre_config) {
62             $ENV{PE_CONFIG_DIR} = Padre::Constant::CONFIG_DIR;
63             $ENV{PE_DEF_PROJ_DIR} = $padre_config->default_projects_directory;
64             $ENV{PE_INDENT_TAB_WIDTH} = $padre_config->editor_indent_tab_width;
65             $ENV{PE_INDENT_WIDTH} = $padre_config->editor_indent_width;
66             $ENV{PE_INDENT_TAB} = ( $padre_config->editor_indent_tab ) ? 'YES' : 'NO';
67             }
68              
69             my $editor = Padre::Current->editor or return;
70              
71             # Document content/statistics information
72             my $pos = $editor->GetCurrentPos();
73             my $line = $editor->LineFromPosition($pos);
74             my $line_start_pos = $editor->PositionFromLine($line);
75             my $line_end_pos = $editor->GetLineEndPosition($line);
76             my $word_start_pos = $editor->WordStartPosition( $pos, 1 );
77             my $word_end_pos = $editor->WordEndPosition( $pos, 1 );
78             $ENV{PE_CURRENT_WORD} = $editor->GetTextRange( $word_start_pos, $word_end_pos );
79             $ENV{PE_CURRENT_LINE} = $editor->GetTextRange( $line_start_pos, $line_end_pos );
80             $ENV{PE_COLUMN_INDEX} = $pos - $line_start_pos;
81             $ENV{PE_COLUMN_NUMBER} = $pos - $line_start_pos + 1;
82             $ENV{PE_LINE_INDEX} = $line;
83             $ENV{PE_LINE_NUMBER} = $line + 1;
84             $ENV{PE_LINE_COUNT} = $editor->GetLineCount();
85              
86             # Document metadata
87             # Ensure that the document has been saved before trying to access
88             # this information.
89             my $document = $editor->{Document};
90             if ( $document && !$document->is_new() ) {
91             $ENV{PE_FILEPATH} = $document->filename();
92             $ENV{PE_BASENAME} = $document->basename();
93             $ENV{PE_DIRECTORY} = $document->dirname();
94             $ENV{PE_MIMETYPE} = $document->mimetype();
95             }
96             }
97              
98             ########################################################################
99             # Document/file interaction
100             sub new_document_from_file {
101             my ( $self, $file_name, $mimetype ) = @_;
102              
103             # Load up a new editor tab...
104             my $main = Padre::Current->main;
105             $main->on_new;
106              
107             # ...and insert the text into the tab.
108             # (Mostly shamelessly copied from Padre::Wx::Main b.t.w.)
109             my $new_editor = Padre::Current->editor or return;
110              
111             if ( $new_editor->insert_from_file($file_name) ) {
112             my $document = $new_editor->{Document};
113             $document->{original_content} = $document->text_get;
114             $mimetype ||= $document->guess_mimetype;
115             $document->set_mimetype($mimetype);
116             $document->editor->padre_setup;
117             $document->rebless;
118             $document->colourize;
119             }
120             }
121              
122             sub replace_selection_from_file {
123             my ( $self, $file_name ) = @_;
124             my $editor = Padre::Current->editor or return;
125             my $file_text = $self->slurp_file($file_name);
126             $editor->ReplaceSelection($file_text);
127             }
128              
129             sub append_selection_from_file {
130             my ( $self, $file_name ) = @_;
131             my $editor = Padre::Current->editor or return;
132             my $file_text = $self->slurp_file($file_name);
133             my $sel_end = $editor->GetSelectionEnd() || 0;
134             $editor->GotoPos($sel_end);
135             $editor->insert_text( "\n" . $file_text );
136             }
137              
138             ########################################################################
139             # File utility
140             sub slurp_file {
141             my $self = shift;
142             local ( *ARGV, $/ );
143             @ARGV = shift;
144             <>;
145             }
146              
147             sub get_temp_file {
148             my $self = shift;
149             my ( $fh, $filename ) = tempfile( '.PF_XXXXXXXX', UNLINK => 1 );
150             close $fh;
151             return $filename;
152             }
153              
154             sub delete_temp_file {
155             my ( $self, $filename ) = @_;
156             ( -f $filename ) && unlink $filename;
157             }
158              
159             ########################################################################
160             # Configuration files
161             sub config_file {
162             my $class = ref $_[0] || $_[0];
163             my $name = join '_', (split /\W+/, $class);
164             my $file_name = $name . '.yml';
165             return File::Spec->catfile( Padre::Constant::CONFIG_DIR, $file_name );
166             }
167              
168             sub initialize_config_file {
169             my ($self) = @_;
170             my $config_file = $self->config_file();
171              
172             # Create a skeleton/example config if needed
173             unless ( -f $config_file ) {
174             my $OUT;
175             if ( open( $OUT, '>', $config_file ) ) {
176             my $config = $self->example_config();
177             print $OUT $config;
178             close $OUT;
179             }
180             }
181             }
182              
183             sub example_config {
184             warn "sub example_config is missing!\n";
185             return '';
186             }
187              
188             sub edit_config_file {
189             my ($self) = @_;
190             my $config_file = $self->config_file();
191              
192             ( -f $config_file ) || $self->initialize_config_file();
193              
194             if ( -f $config_file ) {
195             my $main = Padre::Current->main or return;
196             $main->setup_editors($config_file);
197             }
198             }
199              
200             sub get_config {
201             my ($self) = @_;
202             my $config_file = $self->config_file();
203             ( -f $config_file ) || $self->initialize_config_file();
204             my %config = %{ LoadFile($config_file) };
205             return %config;
206             }
207              
208             1;
209              
210             =pod
211              
212             =head1 NAME
213              
214             Padre::Plugin::Shell::Base - A base class for Padre plugins.
215              
216             =head1 DESCRIPTION
217              
218             Base class for plugins that use the system shell to extend Padre.
219              
220             =head2 Example
221              
222             Subclass Padre::Plugin::Shell::Base to create a plugin.
223              
224             package Padre::Plugin::Shell::Foo;
225             use base 'Padre::Plugin::Shell::Base';
226              
227             use 5.008;
228             use strict;
229             use warnings;
230             use Padre::Wx ();
231              
232             sub plugin_menu {
233             my ($self) = @_;
234             my @menu = ();
235             push @menu, "Do Foo" => sub {$self->do_foo()};
236             push @menu, '---' => undef;
237             push @menu, Wx::gettext("&Configure Foo") => sub { $self->edit_config_file() },;
238             return @menu;
239             }
240              
241             sub example_config {
242             my ($self) = @_;
243             my $config = "---\n";
244              
245             # additional config
246             return $config;
247             }
248              
249             sub do_foo {
250             my ( $self ) = @_;
251             my %config = $self->get_config();
252              
253             # additional foo
254             }
255             1;
256              
257             Subclass Padre::Plugin to wrap the plugin.
258              
259             package Padre::Plugin::Foo;
260             use base 'Padre::Plugin';
261              
262             use 5.008;
263             use strict;
264             use warnings;
265             use Padre::Plugin ();
266             use Padre::Plugin::Shell::Foo;
267              
268             our $VERSION = '0.01';
269              
270             my $foo_plugin;
271              
272             sub plugin_name {
273             'Foo';
274             }
275              
276             sub padre_interfaces {
277             'Padre::Plugin' => 0.43;
278             }
279              
280             sub menu_plugins_simple {
281             my ($self) = @_;
282             $foo_plugin = Padre::Plugin::Shell::Foo->new();
283             'Foo' => [$plugin->plugin_menu()];
284             }
285             1;
286              
287             =head1 ENVIRONMENT VARIABLES
288              
289             To provide additional information for the plugins, the following
290             environment variables are set prior to performing the plugin action:
291              
292             =over
293              
294             =over
295              
296             =item B -- The I at the caret position.
297              
298             =item B -- The text of the current line.
299              
300             =item B -- The index of the position of the caret in the
301             current line (counting from 0).
302              
303             =item B -- The column number of the caret in the current
304             line (counting from 1).
305              
306             =item B -- The index of the current line (counting from 0).
307              
308             =item B -- The line number of the current line (counting from 1).
309              
310             =item B -- The count of lines in the document.
311              
312             =item B -- The file name of the current document.
313              
314             =item B -- The directory of the current document.
315              
316             =item B -- The full path and name of the current document.
317              
318             =item B -- The mime-type of the current document.
319              
320             =item B -- Location of the configuration directory (C<~/.padre>)
321              
322             =item B -- The default project directory.
323              
324             =item B -- Use tabs for indentation. 'YES' or 'NO'
325              
326             =item B -- Tab width/size.
327              
328             =item B -- Indentation width/size.
329              
330             =back
331              
332             =back
333              
334             =head1 METHODS
335              
336             =head2 Document/file interaction methods
337              
338             =head4 append_selection_from_file ($file_pathname)
339              
340             Takes the contents of C<$file_pathname> and appends it to after
341             the selection in the current editor tab.
342              
343             =head4 new_document_from_file ($file_pathname, $mimetype)
344              
345             Creates a new document from the contents in C<$file_pathname>.
346             The (optional) C<$mimetype> tells Padre what kind of document is
347             being created. If no mimetype is specified the Padre will be attempt
348             to guess the mimetype.
349              
350             =head4 replace_selection_from_file ($file_pathname)
351              
352             Takes the contents of C<$file_pathname> and uses it to replace
353             the selection in the current editor tab.
354              
355             =head2 File utility methods
356              
357             =head4 get_temp_file
358              
359             Creates a temporary file and returns the pathname of the temporary file.
360              
361             =head4 delete_temp_file ($file_pathname)
362              
363             Deletes a temporary file.
364              
365             =head4 slurp_file ($file_pathname)
366              
367             Returns the contents of the specified file.
368              
369             =head2 Configuration file methods
370              
371             B: Plugin configurations are stored using YAML.
372              
373             =head4 config_file
374              
375             Returns the pathname of a plugin configuration file.
376              
377             =head4 edit_config_file
378              
379             Opens the configuration file for a plugin for editing.
380              
381             =head4 example_config
382              
383             Returns an example configuration for a plugin. Is to be overwritten
384             by plugins that subclass this package.
385              
386             =head4 get_config
387              
388             Returns a hash containing the configuration for a plugin.
389              
390             =head4 initialize_config_file
391              
392             Initializes a configuration file for a plugin using the return
393             value from C.
394              
395             =head2 Environment variable methods
396              
397             =head4 update_environment_vars
398              
399             Updates the environment variables supported by plugins that
400             subclass this package. See the ENVIRONMENT VARIABLES section for details.
401              
402             =head2 Other methods
403              
404             =head4 new
405              
406             The cannonical new method.
407              
408             =head4 plugin_menu
409              
410             Returns the menu for a plugin. Is to be overwritten by plugins that
411             subclass this package.
412              
413             =head4 notify_of_error
414              
415             Displays an error message.
416              
417             =head1 AUTHOR
418              
419             Gregory Siems Egsiems@gmail.comE
420              
421             =head1 COPYRIGHT AND LICENSE
422              
423             Copyright (C) 2009 by Gregory Siems
424              
425             This library is free software; you can redistribute it and/or modify
426             it under the same terms as Perl itself, either Perl version 5.8.8 or,
427             at your option, any later version of Perl 5 you may have available.
428              
429             =cut