File Coverage

blib/lib/Emacs/Run.pm
Criterion Covered Total %
statement 96 568 16.9
branch 12 162 7.4
condition 4 110 3.6
subroutine 21 57 36.8
pod 38 38 100.0
total 171 935 18.2


line stmt bran cond sub pod time code
1             package Emacs::Run;
2 3     3   207288 use base qw( Class::Base );
  3         9  
  3         5137  
3              
4             =head1 NAME
5              
6             Emacs::Run - use emacs from perl via the shell
7              
8             =head1 SYNOPSIS
9              
10             use Emacs::Run;
11             my $er = Emacs::Run->new();
12             my $major_version = $er->emacs_major_version;
13             if ($major_version > 22) {
14             print "You have a recent version of emacs\n";
15             }
16              
17             # use extra emacs lisp libraries, then get emacs settings
18             my $er = Emacs::Run->new({
19             emacs_libs => [ '~/lib/my-elisp.el',
20             '/usr/lib/site-emacs/stuff.el' ],
21             });
22             my $emacs_load_path_aref = $er->get_load_path;
23             my $email = $er->get_variable( 'user-mail-address' );
24             my $name = $er->eval_function( 'user-full-name' );
25              
26             # suppress the use of the usual emacs init (e.g. ~/.emacs)
27             my $er = Emacs::Run->new({
28             load_emacs_init => 0,
29             });
30             my $result = $er->eval_elisp( '(print (+ 2 2))' ); # that's "4"
31              
32              
33             # the eval_elisp_full_emacs method works with a full externally
34             # spawned emacs (for unusual code that won't run under '--batch')
35             my $elisp_initialize =
36             qq{
37             (defvar my-temp-var "$text")
38             (insert "The initialize elisp has no effect on output: you won't see this.")
39             };
40             my $elisp =
41             qq{
42             (insert my-temp-var)
43             (downcase-region (point-min) (point-max))
44             (my-test-lib-do-something)
45             };
46              
47             my @emacs_libs = ( $dot_emacs, 'my-test-lib' );
48              
49             my $er = Emacs::Run->new({
50             load_no_inits => 1,
51             emacs_libs => \@emacs_libs,
52             });
53              
54             my $output_lines_aref =
55             $er->eval_elisp_full_emacs( {
56             elisp_initialize => $elisp_initialize,
57             output_file => $name_list_file, # omit to use temp file
58             elisp => $elisp,
59              
60             =head1 DESCRIPTION
61              
62             Emacs::Run is a module that provides portable utilities to run
63             emacs from perl as an external process.
64              
65             This module provides methods to allow perl code to:
66              
67             =over
68              
69             =item *
70              
71             Probe the system's emacs installation to get the installed
72             version, the user's current load-path, and so on.
73              
74             =item *
75              
76             Run chunks of emacs lisp code without worrying too much about the
77             details of quoting issues and loading libraries and so on.
78              
79             =back
80              
81             Most of the routines here make use of the emacs "--batch" feature
82             that runs emacs in a non-interactive mode. A few, such as
83             L work by opening a full emacs window,
84             and then killing it when it's no longer needed.
85              
86             =head2 MOTIVATION
87              
88             Periodically, I find myself interested in the strange world of
89             running emacs code from perl. There's a mildly obscure feature of
90             emacs command line invocations called "--batch" that essentially
91             transforms emacs into a lisp interpreter. Additonal command-line
92             options allow one to load files of elisp code and run pieces of code
93             from the command-line.
94              
95             I've found several uses for this tricks. You can use it to:
96              
97             =over
98              
99             =item *
100              
101             Write perl tools to do automated installation of elisp packages.
102              
103             =item *
104              
105             To test elisp code using a perl test harness.
106              
107             =item *
108              
109             To use code written in elisp that you don't want to rewrite in perl.
110              
111             =back
112              
113             This emacs command line invocation is a little language all of it's
114             own, with just enough twists and turns to it that I've felt the need
115             to write perl routines to help drive the process.
116              
117             At present, using Emacs::Run has one large portability advantage
118             over writing your own emacs invocation code: there are some
119             versions of GNU emacs 21 that require the "--no-splash" option,
120             but using this option would cause an error with earlier versions.
121             Emacs::Run handles the necessary probing for you, and generates
122             the right invocation string for the system's installed emacs.
123              
124             There are also some other, smaller advantages (e.g. automatic
125             adjustment of the load-path to include the location of a package
126             loaded as a file), and there may be more in the future.
127              
128             A raw "emacs --batch" run would suppress most of the usual init
129             files (but does load the essentially deprecated "site-start.pl").
130             Emacs::Run has the opposite bias: here we try to load all three
131             kinds of init files, though each one of these can be shut-off
132             individually if so desired. This is because one of the main
133             intended uses is to let perl find out about things such as the
134             user's emacs settings (notably, the B). And depending
135             on your application, the performance hit of loading these files
136             may not seem like such a big deal these days.
137              
138             =head2 METHODS
139              
140             =over
141              
142             =cut
143              
144 3     3   7497 use 5.8.0;
  3         15  
  3         253  
145 3     3   18 use strict;
  3         11  
  3         135  
146 3     3   20 use warnings;
  3         6  
  3         97  
147 3     3   16 use Carp;
  3         5  
  3         232  
148 3     3   2485 use Data::Dumper;
  3         12328  
  3         181  
149 3     3   5531 use Hash::Util qw( lock_keys unlock_keys );
  3         14616  
  3         24  
150 3     3   365 use File::Basename qw( fileparse basename dirname );
  3         5  
  3         3083  
151 3     3   151 use File::Spec;
  3         7  
  3         83  
152 3     3   39 use Cwd qw( cwd abs_path );
  3         6  
  3         1070  
153 3     3   22 use List::Util qw( first );
  3         6  
  3         398  
154 3     3   5572 use Env qw( $HOME );
  3         16906  
  3         19  
155 3     3   16462 use List::MoreUtils qw( any );
  3         12291  
  3         310  
156 3     3   3879 use File::Temp qw{ tempfile };
  3         120120  
  3         50068  
157              
158             our $VERSION = '0.15';
159             my $DEBUG = 0;
160              
161             # needed for accessor generation
162             our $AUTOLOAD;
163             my %ATTRIBUTES = ();
164              
165             =item new
166              
167             Creates a new Emacs::Run object.
168              
169             Takes a hashref as an argument, with named fields identical
170             to the names of the object attributes. These attributes are:
171              
172             =over
173              
174             =item emacs_path
175              
176             Indicates how to find the emacs program. Defaults to 'emacs', which
177             lets the system (e.g. the shell's PATH environment variable) find the
178             program if it can. If you have multiple emacsen installed in different
179             places and/or under different names, you can choose which one will be
180             used by setting this attribute.
181              
182             =item redirector
183              
184             A code that specifies how the default way of handling the
185             standard output and error streams for some methods, such as
186             L, L and L.
187              
188             This may be one of three values:
189              
190             =over
191              
192             =item stdout_only
193              
194             =item stderr_only
195              
196             =item all_output (object default -- some methods may differ)
197              
198             =back
199              
200             Alternately, one may enter Bourne shell redirection codes using
201             the L.
202              
203             =item shell_output_director
204              
205             A Bourne shell redirection code (e.g. '2>&1'). This is an
206             alternative to setting L.
207              
208             =item before_hook
209              
210             A string inserted into the built-up emacs commands immediately
211             after "--batch", but before any thing else is executed.
212             This is a good place to insert additional invocation options
213             such as "--multibyte" or "--unibyte". See .
214              
215             =item load_emacs_init
216              
217             Defaults to 1, if set to a false value, will suppress the use
218             of the user's emacs init file (e.g. "~/.emacs").
219              
220             =item load_site_init
221              
222             Defaults to 1, if set to a false value, will suppress the use
223             of the system "site-start.el" file (which loads before the
224             user's init file).
225              
226             =item load_default_init
227              
228             Defaults to 1, if set to a false value, will suppress the use
229             of the system "default.el" file (which loads after the user's
230             init file).
231              
232             =item load_no_inits
233              
234             A convenience flag, which may be set to disable all three types of emacs init
235             files in one step. Overrides the other three.
236              
237             =item emacs_libs
238              
239             A list of emacs libraries (with or without paths) to be loaded
240             automatically. This is recommended for most uses, though
241             to take full control over how your emacs libraries are handled,
242             see L.
243              
244             =item default_priority
245              
246             The global default for how all the emacs libraries should be loaded.
247             Normally this is set to "requested", but it can be set to "needed".
248              
249             A 'requested' library will be silently skipped if it is not available
250             (and any elisp code using it may need to to adapt to it's absense,
251             e.g. by doing 'featurep' checks).
252              
253             A 'needed' file will cause an error to occur if it is not available.
254              
255             Note: this error does not occur during object instantiation, but
256             only after a method is called that needs to load the libraries
257             (e.g. L L, L,
258             L, etc).
259              
260             =item lib_data
261              
262             Note: using L is usually preferrable to L.
263              
264             B is the internal representation that is
265             converted into, but the client programmer is provided access to it to
266             cover any unusual needs.
267              
268             The structure of B is an array of arrays of two elements each,
269             the first element is the library name (a string, with or without path),
270             the second element is a hash of library attributes: 'priority' (which can
271             be 'requested' or 'needed') and 'type' (which can be 'file' or 'lib').
272              
273             Example:
274              
275             $lib_data = [
276             [ 'dired', { type=>'lib', priority=>'needed' } ],
277             [ '/tmp/my-load-path.el', { type=>'file', priority=>'requested' } ],
278             [ '/tmp/my-elisp.el', { type=>'file', priority=>'needed' } ],
279             ];
280              
281             emacs library attributes:
282              
283             =over
284              
285             =item priority
286              
287             A 'requested' library will be silently skipped if it is not available,
288             but if a 'needed' file is not available it's regarded as an error condition.
289             The default priority is 'requested', but that can be changed via the
290             L attribute. See L for more
291             details.
292              
293             =item type
294              
295             A library of type 'file' should be a filesystem path to a file
296             containing a library of emacs lisp code. A library of type 'lib' is
297             specified by just the basename of the file (sans path or extension), and
298             we will search for it looking in the places specified in the emacs
299             variable load-path. When neither is specified, this module guesses the
300             lib is a file if it looks that way (i.e it has a path and/or extension).
301              
302             =back
303              
304             If both B and B are used, the B libraries
305             are loaded first, followed by the B libraries.
306              
307             These attributes are used to pass information to the client programmer,
308             they should be regarded as read-only:
309              
310             =over
311              
312             =item emacs_version
313              
314             The version number of emacs in use: this is set automatically by the
315             "probe_emacs_version" method during object initialization.
316              
317             =item emacs_type
318              
319             The flavor of emacs in use, e.g. 'Gnu Emacs'. Set automatically by
320             the "probe_emacs_version" method during object initialization.
321              
322             =back
323              
324             There are also a number of object attributes intended largely for
325             internal use. The client programmer has access to these, but
326             is not expected to need it. These are documented in L.
327              
328             =back
329              
330             =cut
331              
332             # Note: "new" is inherited from Class::Base and
333             # calls the following "init" routine automatically.
334              
335             =item init
336              
337             Method that initializes object attributes and then locks them
338             down to prevent accidental creation of new ones.
339              
340             Any class that inherits from this one should have an L of
341             it's own that calls this L.
342              
343             =cut
344              
345             sub init {
346 2     2 1 1009 my $self = shift;
347 2         6 my $args = shift;
348 2         7 unlock_keys( %{ $self } );
  2         22  
349              
350 2 50       25 if ($DEBUG) {
351 0         0 $self->debugging(1);
352             }
353              
354             # object attributes here, including arguments that become attributes
355 2         78 my @attributes = qw(
356             emacs_path
357             emacs_version
358             emacs_major_version
359             emacs_type
360              
361             load_emacs_init
362             load_site_init
363             load_default_init
364             load_no_inits
365              
366             emacs_libs
367             lib_data
368             lib_data_initial
369             default_priority
370              
371             before_hook
372             ec_lib_loader
373             shell_output_director
374              
375             redirector
376              
377             message_log
378             );
379              
380 2         7 foreach my $field (@attributes) {
381 34         49 $ATTRIBUTES{ $field } = 1;
382 34         108 $self->{ $field } = $args->{ $field };
383             }
384              
385 2 50 33     18 if( $self->{ redirector } && $self->{ shell_output_director } ) {
386 0         0 carp "redirector takes precedence: shell_output_director setting ignored.";
387             }
388 2 50       17 if( $self->{ redirector } ) {
    50          
389 0         0 $self->{ shell_output_director } = $self->redirector_to_sod( $self->redirector );
390             } elsif ( $self->{ shell_output_director } ) {
391 0         0 $self->{ redirector } = ''; # shouldn't matter now, in any case
392             } else {
393             # by default, we intermix STDOUT and STDERR
394 2         5 $self->{ shell_output_director } = '2>&1';
395 2         4 $self->{ redirector } = 'all_output'; # redundant? what the hell.
396             }
397              
398             # Define attributes (apply defaults, etc)
399 2         4 $self->{ec_lib_loader} = '';
400              
401             # If we weren't given a path, let the $PATH sort it out
402 2   100     13 $self->{ emacs_path } ||= 'emacs';
403              
404             # Determine the emacs version (if we haven't been told already - but why override TODO?)
405 2   33     16 $self->{ emacs_version } ||= $self->probe_emacs_version;
406 2 50       23 unless( $self->{ emacs_version } ) { # if emacs is not found, just bail
407 2         160 return;
408             }
409              
410             # By default, we like to load all init files
411 0 0       0 $self->{load_emacs_init} = 1 unless defined( $self->{load_emacs_init} );
412 0 0       0 $self->{load_site_init} = 1 unless defined( $self->{load_site_init} );
413 0 0       0 $self->{load_default_init} = 1 unless defined( $self->{load_default_init} );
414              
415 0 0       0 if( $self->{load_no_inits} ) { # ... but we make it easy to suppress all of them, too.
416 0         0 $self->{load_emacs_init} = 0;
417 0         0 $self->{load_site_init} = 0;
418 0         0 $self->{load_default_init} = 0;
419             }
420              
421 0   0     0 $self->{ before_hook } ||= '';
422 0 0       0 if($self->{load_no_inits} ) {
423 0         0 $self->append_to_before_hook( ' -Q ' );
424             }
425              
426 0   0     0 $self->{ default_priority } ||= 'requested';
427              
428             # preserving any given lib_data in the event of a need to reset.
429 0         0 $self->{lib_data_initial} = $self->{ lib_data };
430              
431 0 0       0 if( defined( my $emacs_libs = $self->{ emacs_libs } ) ) {
432 0         0 $self->process_emacs_libs_addition( $emacs_libs );
433             } else {
434             # called indirectly by process_emacs_libs_addition.
435             # no point in doing it again, *unless* no emacs_libs
436 0         0 $self->set_up_ec_lib_loader;
437             }
438              
439 0         0 lock_keys( %{ $self } );
  0         0  
440 0         0 return $self;
441             }
442              
443              
444             =back
445              
446             =head2 Simple Emacs Invocations
447              
448             Some simple methods for obtaining information from your emacs
449             installation.
450              
451             These methods default to returning STDOUT, suppressing anything
452             sent to STDERR. This behavior can be overridden: see
453             L.
454              
455             =over
456              
457             =item eval_function
458              
459             Given the name of an emacs function, this runs the function and
460             returns the value from emacs (when started with the the .emacs
461             located in $HOME, if one is found). After the function name, an
462             optional array reference may be supplied to pass through a list
463             of simple arguments (limited to strings) to the elisp function.
464             And further, an optional hash reference may follow that to
465             specify options to the "eval_function" method.
466              
467             By default the returned output is STDOUT only but this behavior
468             can be overridden: See L.
469              
470             As with L, this uses the emacs 'print' function
471             internally.
472              
473             Examples:
474              
475             my $name = $er->eval_function( 'user-full-name' );
476              
477             $er->eval_function( 'extract-doctrings-generate-html-for-elisp-file',
478             [ "$input_elisp_file",
479             "$output_file",
480             "The extracted docstrings" ] );
481              
482             =cut
483              
484             sub eval_function {
485 0     0 1 0 my $self = shift;
486 0         0 my $funcname = shift;
487 0         0 my $arg2 = shift;
488 0         0 my $subname = ( caller(0) )[3];
489              
490 0         0 my $devnull = File::Spec->devnull();
491              
492 0         0 my ($passthroughs, $opts, $passthru);
493 0 0       0 if (ref( $arg2 ) eq 'ARRAY') {
    0          
494 0         0 $passthroughs = $arg2;
495 0         0 $passthru = join " ", map{ qq{"$_"} } @{ $passthroughs };
  0         0  
  0         0  
496 0         0 $opts = shift;
497             } elsif (ref( $arg2 ) eq 'HASH') {
498 0         0 $opts = $arg2;
499             }
500              
501 0   0     0 my $redirector = $opts->{ redirector } || "stdout_only";
502             my $sod =
503             $opts->{ shell_output_director } ||
504 0   0     0 $self->redirector_to_sod( $redirector ) ||
505             "2>$devnull";
506              
507 0         0 my $elisp;
508 0 0       0 if( $passthru ) {
509 0         0 $elisp = qq{ (print ($funcname $passthru)) };
510             } else {
511 0         0 $elisp = qq{ (print ($funcname)) };
512             }
513              
514 0         0 my $return = $self->eval_elisp( $elisp, {
515             shell_output_director => $sod,
516             } );
517 0         0 return $return;
518             }
519              
520             =item get_variable
521              
522             Given the name of an emacs variable, returns the value from
523             emacs (when started with the the .emacs located in $HOME,
524             if one is found),
525              
526             Internally, this uses the emacs 'print' function, which can
527             handle variables containing complex data types, but the
528             return value will be a "printed representation" that may
529             make more sense to emacs than to perl code. For example,
530             the "load-path" variable might look like:
531              
532             ("/home/grunt/lib" "/usr/lib/emacs/site-lisp" "/home/xtra/lib")
533              
534             See L below for a more perl-friendly way of doing this.
535              
536             Ignores redirector/shell_output_director.
537              
538             =cut
539              
540             sub get_variable {
541 0     0 1 0 my $self = shift;
542 0         0 my $varname = shift;
543 0         0 my $opts = shift;
544 0         0 my $devnull = File::Spec->devnull();
545              
546 0         0 my $redirector = 'stdout_only';
547 0         0 my $sod = $self->redirector_to_sod( $redirector );
548              
549 0         0 my $subname = ( caller(0) )[3];
550 0         0 my $elisp = qq{ (print $varname) };
551 0         0 my $return = $self->eval_elisp( $elisp, {
552             shell_output_director => $sod,
553             } );
554 0         0 return $return;
555             }
556              
557             =item get_load_path
558              
559             Returns the load-path from emacs (by default, using the
560             user's .emacs, if it can be found) as a reference to a perl array.
561              
562             Changing the $HOME environment variable before running this method
563             results in loading the .emacs file located in the new $HOME.
564              
565             Ignores redirector/shell_output_director.
566              
567             =cut
568              
569             sub get_load_path {
570 0     0 1 0 my $self = shift;
571 0         0 my $opts = shift;
572 0         0 my $devnull = File::Spec->devnull();
573              
574 0         0 my $redirector = 'stdout_only';
575 0         0 my $sod = $self->redirector_to_sod( $redirector );
576              
577 0         0 my $elisp = q{ (print (mapconcat 'identity load-path "\n")) };
578              
579 0         0 my $return = $self->eval_elisp( $elisp, {
580             shell_output_director => $sod,
581             } );
582 0         0 my @load_path = split /\n/, $return;
583 0         0 \@load_path;
584             }
585              
586              
587              
588             =item probe_for_option_no_splash
589              
590             Looks for the emacs command line option "--no-splash", returning true (1)
591             if it exists, and false (0) otherwise.
592              
593             Ignores redirector/shell_output_director.
594              
595             =cut
596              
597             # earlier versions called this "no_splash_p"
598             sub probe_for_option_no_splash {
599 0     0 1 0 my $self = shift;
600 0         0 my $subname = ( caller(0) )[3];
601              
602 0         0 my $emacs = $self->emacs_path;
603 0         0 my $before_hook = $self->before_hook;
604 0         0 $before_hook .= ' --no-splash ';
605              
606 0 0       0 if ( $self->emacs_type eq 'XEmacs' ) {
607 0         0 return 0; # xemacs has no --no-splash
608             }
609              
610 0         0 my $sod = '2>&1';
611              
612 0         0 my $cmd = qq{ $emacs --batch $before_hook $sod };
613 0         0 $self->debug("$subname: cmd: $cmd\n");
614 0         0 my $retval = qx{ $cmd };
615 0         0 $retval = $self->clean_return_value( $retval );
616              
617 0   0     0 my $last_line = ( split /\n/, $retval )[-1] || '';
618              
619 0         0 $self->debug( "$subname retval:\n===\n$retval\n===\n" );
620              
621 0 0       0 if( $retval =~ m{ Unknown \s+ option \s+ .*? --no-splash }xms ) {
622 0         0 return 0;
623             } else {
624 0         0 return 1;
625             }
626             }
627              
628              
629              
630             =back
631              
632             =head2 Running Elisp
633              
634             These are general methods that run pieces of emacs lisp code.
635              
636             The detailed behavior of these methods have a number of things
637             in common:
638              
639             By default the method first loads the user's initialization
640             file ("$HOME/.emacs") if it can be found. It will also try to
641             load the libraries listed in the L and/or
642             L attributes.
643              
644             There are object attribute settings that can be used to suppress
645             loading any of the various init files. See L for the full
646             list. In particular, if the L attribute has
647             been turned off, it will not try to load the .emacs file.
648              
649             Unless specified otherwise, the methods return the
650             output from the elisp code with STDOUT and STDERR
651             mixed together, though this behavior can be overridden.
652             See L.
653              
654             (The advantage of intermixing STDOUT and STDERR is that the
655             emacs functions 'message' as well as 'print' both may be used
656             for interesting output. The disadvantage is that you may have
657             many inane messages from emacs sent to STDERR such as 'Loading
658             library so-and-so')
659              
660             =over
661              
662             =item eval_elisp
663              
664             Given a string containing a chunk of elisp code this method runs
665             it by invoking emacs in batch mode.
666              
667             Example:
668              
669             my $result = $er->eval_elisp( '(print (+ 2 2))' );
670              
671             =cut
672              
673             sub eval_elisp {
674 0     0 1 0 my $self = shift;
675 0         0 my $elisp = shift;
676 0         0 my $opts = shift;
677 0         0 my $subname = ( caller(0) )[3];
678              
679 0   0     0 my $redirector = $opts->{ redirector } || $self->redirector;
680             my $sod =
681             $opts->{ shell_output_director } ||
682 0   0     0 $self->redirector_to_sod( $opts->{ redirector } ) ||
683             $self->shell_output_director ||
684             $self->redirector_to_sod( $self->redirector );
685              
686 0         0 $elisp = $self->quote_elisp( $self->progn_wrapper( $elisp ));
687              
688 0         0 my $emacs = $self->emacs_path;
689 0         0 my $before_hook = $self->before_hook;
690              
691 0         0 my $ec_head = qq{ $emacs --batch $before_hook };
692 0         0 my $ec_tail = qq{ --eval "$elisp" };
693 0         0 my $ec_lib_loader = $self->set_up_ec_lib_loader;
694              
695 0         0 my $cmd = "$ec_head $ec_lib_loader $ec_tail $sod";
696 0         0 $self->debug("$subname: cmd:\n $cmd\n");
697              
698 0         0 my $retval = qx{ $cmd };
699 0         0 $retval = $self->clean_return_value( $retval );
700 0         0 $self->debug( "$subname retval:\n===\n$retval\n===\n" );
701              
702 0         0 return $retval;
703             }
704              
705             =item run_elisp_on_file
706              
707             Given a file name, and some emacs lisp code (which presumably
708             modifies the current buffer), this method opens the file, runs
709             the code on it, and then saves the file.
710              
711             Returns whatever value the elisp returns.
712              
713             Example usage:
714             $self->run_elisp_on_file( $filename, $elisp );
715              
716             =cut
717              
718             sub run_elisp_on_file {
719 0     0 1 0 my $self = shift;
720 0         0 my $filename = shift;
721 0         0 my $elisp = shift;
722 0         0 my $opts = shift;
723 0         0 my $subname = ( caller(0) )[3];
724              
725 0   0     0 my $redirector = $opts->{ redirector } || $self->redirector;
726              
727             my $sod =
728             ( $opts->{ shell_output_director } ) ||
729 0   0     0 ( $self->redirector_to_sod( $opts->{ redirector } ) ) ||
730             ( $self->shell_output_director ) ||
731             ( $self->redirector_to_sod( $self->redirector ) );
732              
733 0         0 $elisp = $self->quote_elisp( $elisp );
734              
735 0         0 my $emacs = $self->emacs_path;
736 0         0 my $before_hook = $self->before_hook;
737              
738             # Covering a stupidity with some versions of gnu emacs 21: "--no-splash"
739             # to suppress an inane splash screen.
740 0 0 0     0 if ( $self->emacs_major_version eq '21' &&
      0        
741             $self->emacs_type eq 'GNU Emacs' &&
742             $self->probe_for_option_no_splash ) {
743 0         0 $before_hook .= ' --no-splash ';
744             }
745              
746 0         0 my $ec_head = qq{ $emacs --batch $before_hook --file='$filename' };
747 0         0 my $ec_tail = qq{ --eval "$elisp" -f save-buffer };
748 0         0 my $ec_lib_loader = $self->ec_lib_loader;
749              
750 0         0 my $cmd = "$ec_head $ec_lib_loader $ec_tail $sod";
751 0         0 $self->debug("$subname: cmd: $cmd\n");
752              
753 0         0 my $retval = qx{ $cmd };
754 0         0 $retval = $self->clean_return_value( $retval );
755 0         0 $self->debug( "$subname retval:\n===\n$retval\n===\n" );
756              
757 0         0 return $retval;
758             }
759              
760             =item eval_elisp_full_emacs
761              
762             Runs the given chunk(s) of elisp using a temporarily launched
763             full scale emacs window (does not work via "--batch" mode).
764              
765             Returns an array reference of lines of output.
766              
767             Of necessity, this emacs sub-process must communicate through a
768             file (similar to "run_elisp_on_file"), so the elisp run by this
769             routine should be designed to output to the current buffer
770             (e.g. via "insert" calls).
771              
772             Any elisp functions such as "message" and "print" will have no
773             direct effect on output, and neither the or
774             have any effect here.
775              
776             As an option, a separate chunk of initialization elisp may also be
777             passed in: it will be run before the output file buffer is
778             opened, and hence any modification it makes to the current buffer
779             will be ignored.
780              
781             If the "output_filename" is not supplied, a temporary file will
782             be created and deleted afterwards. If the name is supplied, the
783             output file will be still exist afterwards (but note: any existing
784             contents will be over-written).
785              
786             The current buffer is saved at the end of the processing (so
787             there's no need to include a "save-buffer" call in the elisp).
788              
789             All arguments are passed into this method via a hashref of
790             options. These are:
791              
792             elisp_initialize
793             output_file
794             elisp
795              
796             Note that this last "option" is not optional: you need to supply
797             some "elisp" if you want anything to happen.
798              
799             Example use:
800              
801             my $er = Emacs::Run->new({
802             load_no_inits = 1,
803             emacs_libs => [ '~/lib/my-elisp.el',
804             '/usr/lib/site-emacs/stuff.el' ],
805             });
806              
807             # Using just the 'elisp' argument:
808             my $elisp =
809             qq{ (insert-file "$input_file")
810             (downcase-region (point-min) (point-max))
811             };
812              
813             my $output =
814             $er->eval_elisp_full_emacs( {
815             elisp => $elisp,
816             }
817             );
818              
819             # Using all options:
820             my $output =
821             $er->eval_elisp_full_emacs( {
822             elisp_initialize => $elisp_initialize,
823             output_file => $output_file,
824             elisp => $elisp,
825             message_log => '/tmp/message.log',
826             }
827             );
828              
829             This method only uses some of the usual Emacs::Run framework:
830              
831             The three individual init settings flags have no effect on this
832             method ("load_emacs_init", "load_site_init", "load_default_init").
833             If "load_no_inits" is set, the emacs init files will be ignored
834             (via "-q") unless, of course, they're passed in manually in the
835             "emacs_libs" array reference.
836              
837             Adding libraries to emacs_libs will not automatically add their
838             locations to the load-path (because the "ec_lib_loader" system is
839             not in use here).
840              
841             Ignores redirector/shell_output_director.
842              
843             If the option "message_log" contains the name of a log file
844             the emacs '*Messages*' buffer will be appended to it.
845              
846             =cut
847              
848             sub eval_elisp_full_emacs {
849 0     0 1 0 my $self = shift;
850 0         0 my $opts = shift;
851 0         0 my $subname = ( caller(0) )[3];
852              
853             # unpack options
854             # my $elisp = $opts->{ elisp };
855 0         0 my $elisp_initialize = $self->progn_wrapper( $opts->{ elisp_initialize } );
856 0         0 my $elisp = $self->progn_wrapper( $opts->{ elisp } );
857 0         0 my $output_file = $opts->{ output_file };
858              
859 0   0     0 my $message_log = $opts->{ message_log } || $self->message_log;
860              
861             # if $output_file is blank, need to pick a temp file to use.
862 0 0       0 unless( $output_file ) {
863 0         0 my $fh;
864 0         0 my $unlink = not( $DEBUG );
865 0         0 ($fh, $output_file) =
866             tempfile( "emacs_run_eval_elisp_full_emacs-$$-XXXX",
867             SUFFIX => '.txt',
868             UNLINK => $unlink );
869 0         0 close ($fh); # after it's written by the subprocess, we will read this file
870             }
871              
872             # Have to do this to ensure that exit condition works
873 0 0       0 unlink( $output_file ) if -e $output_file;
874              
875 0         0 my $emacs = $self->emacs_path;
876 0         0 my $before_hook = $self->before_hook;
877              
878             # need "--no-splash" for some versions of emacs
879 0 0 0     0 if ( $self->emacs_major_version eq '21' &&
      0        
880             $self->emacs_type eq 'GNU Emacs' &&
881             $self->probe_for_option_no_splash ) {
882 0         0 $before_hook .= ' --no-splash ';
883             }
884              
885 0 0       0 my $elisp_log_messages = $self->progn_wrapper(
886             $message_log ?
887             qq{
888             (find-file "$message_log")
889             (insert (format "\n $0 logging *Messages* - %s\n" (current-time-string)))
890             (goto-char (point-max))
891             (insert-buffer "*Messages*")
892             } : ''
893             );
894 0 0       0 ($DEBUG) && print STDERR "\n$elisp_log_messages\n\n";
895              
896 0         0 my $output_buffer = basename( $output_file );
897 0         0 my $elisp_back_to_output =
898             qq{
899             (switch-to-buffer "$output_buffer")
900             };
901 0 0       0 ($DEBUG) && print STDERR "\n", $elisp_back_to_output, "\n\n";
902              
903             # Build up the command arguments
904 0         0 my @cmd;
905 0         0 push @cmd, ( "emacs_from_" . "$$" ); # just the process label, not the binary
906              
907 0 0       0 push @cmd, @{ $self->parse_ec_string( $before_hook ) } if $before_hook;
  0         0  
908              
909 0         0 foreach my $lib ( @{ $self->emacs_libs } ) {
  0         0  
910 0 0       0 push @cmd, ( "-l", "$lib" ) if $lib;
911             }
912              
913 0 0       0 push @cmd, ( "--eval", "$elisp_initialize" ) if $elisp_initialize;
914 0         0 push @cmd, ( "--file", "$output_file" );
915 0         0 push @cmd, ( "--eval", "$elisp" );
916              
917 0 0       0 if ($message_log) {
918 0         0 push @cmd, ( "--eval", "$elisp_log_messages" );
919 0         0 push @cmd, ( "-f", "save-buffer" );
920             }
921              
922 0         0 push @cmd, ( "--eval", "$elisp_back_to_output" );
923 0         0 push @cmd, ( "-f", "save-buffer" );
924              
925 0         0 $self->debug("$subname: cmd: " . Dumper( \@cmd ) . "\n");
926              
927 0 0       0 if ( my $pid = fork ) {
928             # this is parent code
929 0 0       0 ($DEBUG) && print STDERR "I'm the parent, the child pid is $pid\n";
930              
931             # kill the child emacs when it's finished
932 0         0 LOOP: while(1) { # TODO needs to time out (what if *nothing* is written?)
933 0 0       0 if ( $self->full_emacs_done ({ output_file => $output_file,
934             pid => $pid }) ){
935 0         0 sleep 1; # a little time for things to settle down (paranoia)
936 0         0 my $status =
937             kill 1, $pid;
938 0 0       0 ($DEBUG) && print STDERR "Tried to kill (1) pid $pid, status: $status \n";
939 0         0 last LOOP;
940             }
941             }
942             } else {
943             # this is child code
944 0 0       0 die "cannot fork: $!" unless defined $pid;
945              
946 0 0       0 ($DEBUG) && print STDERR "This is the child, about to exec:\n";
947 0         0 exec { $emacs } @cmd;
  0         0  
948             }
949              
950 0 0       0 open my $fh, '<', $output_file or die "$!";
951 0         0 my @result = map{ chomp($_); s{\r$}{}xms; $_ } <$fh>;
  0         0  
  0         0  
  0         0  
952             # Note: stripping CRs is a hack to deal with some windows-oriented .emacs
953 0         0 return \@result;
954             }
955              
956              
957             =item full_emacs_done
958              
959             Internally used routine.
960              
961             When it looks as though the child process run by
962             eval_elisp_full_emacs is finished, this returns true.
963              
964             At present, this just watches to see when the output_file
965             has been written.
966              
967             =cut
968              
969             ### TODO - would be better to watch the process somehow and determine when it's idle.
970             sub full_emacs_done {
971 0     0 1 0 my $self = shift;
972 0         0 my $opts = shift;
973              
974 0         0 my $pid = $opts->{ pid };
975 0         0 my $output_file = $opts->{ output_file };
976              
977 0         0 my $cutoff = 0; # could increase, if this seems flaky
978 0 0 0     0 if ( (-e $output_file) && ( (-s $output_file) > $cutoff ) ) {
979 0         0 return 1;
980             } else {
981 0         0 return 0;
982             }
983             }
984              
985              
986             =back
987              
988             =head1 INTERNAL METHODS
989              
990             The following methods are intended primarily for internal use.
991              
992             Note: the common "leading underscore" naming convention is not used here.
993              
994             =head2 Utility Methods
995              
996             =over
997              
998             =item quote_elisp
999              
1000             Routine to quote elisp code before feeding it into an emacs batch
1001             shell command. Used internally by methods such as L.
1002              
1003             This just adds a single backslash to all the double-quote characters
1004             (essentially an empirically determined algorithm, i.e. hack).
1005              
1006             Example usage:
1007              
1008             $elisp = $self->quote_elisp( $elisp );
1009             $emacs_cmd = qq{ emacs --batch --eval "$elisp" 2>&1 };
1010             my $return = qx{ $emacs_cmd };
1011              
1012             =cut
1013              
1014             sub quote_elisp {
1015 0     0 1 0 my $self = shift;
1016 0         0 my $elisp = shift;
1017              
1018 0         0 $elisp =~ s{"}{\\"}xmsg; # add one backwhack to the double-quotes
1019 0         0 return $elisp;
1020             }
1021              
1022              
1023             =item progn_wrapper
1024              
1025             Takes a chunk of elisp, and adds a "progn" around it, to help
1026             make multi-line chunks of elisp Just Work.
1027              
1028             =cut
1029              
1030             sub progn_wrapper {
1031 0     0 1 0 my $self = shift;
1032 0         0 my $elisp = shift;
1033              
1034 0 0       0 $elisp = "(progn $elisp )" if $elisp;
1035 0         0 return $elisp;
1036             }
1037              
1038             =item parse_ec_string
1039              
1040             Takes a chunk of emacs command-line invocation in string form
1041             and converts it to a list form (suitable for feeding into "system"
1042             or "exec", stepping around the shell).
1043              
1044             Returns an aref of tokens (filenames, options, option-arguments).
1045              
1046             Limitation:
1047              
1048             The '--' option (which indicates that all following tokens are
1049             file names, even if they begin with a hyphen) is not yet handled
1050             correctly here.
1051              
1052             =cut
1053              
1054             # processing one char at a time
1055             # different tokens have different syntax - when we know we're
1056             # doing one type, we'll watch for it's ending
1057              
1058             # quoted strings are treated as an additional token-type
1059             # filenames are handled as option-arguments
1060              
1061             # remember when you see quotes (toggle state)
1062             # when you see an unquoted leading [-+], that begins an option
1063             # [\s=] closes the option
1064             # = means the following is an option-arg
1065             # otherwise, it's an option-arg or a file if no leading [-+]
1066              
1067             sub parse_ec_string {
1068 0     0 1 0 my $self = shift;
1069              
1070 0         0 my $ec_string = shift;
1071 0         0 my (@ec, $part);
1072              
1073             # drop leading and trailing whitespace
1074 0         0 chomp($ec_string);
1075 0         0 $ec_string =~ s/^\s//;
1076 0         0 $ec_string =~ s/\s$//;
1077              
1078             # state flags
1079 0         0 my $quoted = 0;
1080 0         0 my $opted = 1; # begin saving whatever is there at the outset
1081 0         0 my $arged = 0;
1082             # 1-char of memory
1083 0         0 my $prev = '';
1084              
1085 0         0 my @chars = split '', $ec_string;
1086 0         0 foreach (@chars) {
1087 0 0 0     0 if ( /\s/ and $prev =~ /\s/ ) { # turn multiple spaces into one
1088 0         0 next;
1089             }
1090 0 0 0     0 if ( not( $quoted) and /"/ ) {
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
1091 0         0 $quoted = 1;
1092             } elsif( ($quoted) and /"/ and $prev ne '\\') { # matches: " but not \"
1093 0         0 $quoted = 0;
1094 0         0 push @ec, $part; $part = '';
  0         0  
1095             } elsif ($quoted) {
1096             # fold double backwhacks into one
1097 0 0 0     0 if( $_ eq '\\' and $prev eq '\\' ){
1098 0         0 chop( $part );
1099             }
1100             # drop escapes from escaped quotes
1101 0 0 0     0 if( $_ eq '"' and $prev eq '\\' ) {
1102 0         0 chop( $part );
1103             }
1104 0         0 $part .= $_;
1105             } elsif( not( $opted ) and /[-+]/ and $prev ne '\\' ) {
1106 0         0 $arged = 1;
1107 0         0 $part .= $_;
1108             } elsif ( $opted and /[\s=]/ ) {
1109 0         0 $opted = 0;
1110 0         0 push @ec, $part; $part = '';
  0         0  
1111             } elsif ($opted) {
1112 0         0 $part .= $_;
1113             } elsif( not( $arged ) and ( $prev =~ /\s/ or ($prev eq '=') )) { # looks back ar prev char
1114 0         0 $arged = 1;
1115 0         0 $part .= $_; # must save-up this char (transition char was the previous one)
1116             } elsif ($arged and /\s/ ) {
1117 0         0 $arged = 0;
1118 0         0 push @ec, $part; $part = '';
  0         0  
1119             } elsif ($arged) {
1120 0         0 $part .= $_;
1121             }
1122 0         0 $prev = $_;
1123             }
1124 0 0       0 push @ec, $part unless( $part =~ /^\s*$/ ); # skipping blank lines (hack hack)
1125 0         0 return \@ec;
1126             }
1127              
1128              
1129             =item clean_return_value
1130              
1131             Cleans up a given string, trimming unwanted leading and trailing
1132             blanks and double quotes.
1133              
1134             This is intended to be used with elisp that uses the 'print'
1135             function. Note that it is limited to elisp with a single print
1136             of a result: multiple prints will leave embedded quote-newline
1137             pairs in the output.
1138              
1139             =cut
1140              
1141             sub clean_return_value {
1142 0     0 1 0 my $self = shift;
1143 0         0 my $string = shift;
1144 0         0 $string =~ s{^[\s"]+}{}xms;
1145 0         0 $string =~ s{[\s"]+$}{}xms;
1146 0         0 return $string;
1147             }
1148              
1149              
1150              
1151             =item redirector_to_sod
1152              
1153             Convert a redirector code into the equivalent shell_output_director
1154             (Bourne shell).
1155              
1156             =cut
1157              
1158             sub redirector_to_sod {
1159 2     2 1 4 my $self = shift;
1160 2         4 my $redirector = shift;
1161 2         12 my $devnull = File::Spec->devnull;
1162              
1163 2 50       25 unless ( $redirector ) {
1164 0         0 return;
1165             }
1166              
1167 2         5 my $sod;
1168 2 50       7 if( $redirector eq 'stdout_only' ) {
    0          
    0          
1169 2         4 $sod = "2>$devnull";
1170             } elsif ( $redirector eq 'stderr_only' ) {
1171 0         0 $sod = "2>&1 1>$devnull";
1172             } elsif ( $redirector eq 'all_output' ) {
1173 0         0 $sod = '2>&1';
1174             }
1175 2         14 return $sod;
1176             }
1177              
1178             =back
1179              
1180             =head2 Initialization Phase Methods
1181              
1182             The following routines are largely used internally in the
1183             object initialization phase.
1184              
1185             =over
1186              
1187             =item process_emacs_libs_addition
1188              
1189             Goes through the given list of emacs_libs, and converts the names into
1190             the lib_data style of data structure, appending it to lib_data.
1191              
1192             Note that this method works on the given argument, without
1193             reference to the object's "emacs_libs" field.
1194              
1195             Returns a reference to a structure containing the new additions to lib_data.
1196              
1197             =cut
1198              
1199             # Note: since set_up_ec_lib_loader qualifies the data and fills in
1200             # likely values for type and priority, it need not be done here.
1201             sub process_emacs_libs_addition {
1202 0     0 1 0 my $self = shift;
1203 0         0 my $libs = shift;
1204              
1205 0         0 my @new_lib_data;
1206 0         0 foreach my $name ( @{ $libs } ) {
  0         0  
1207 0         0 my $rec = [ $name, { type=>undef, priority=>undef } ];
1208 0         0 push @new_lib_data, $rec;
1209             }
1210              
1211 0         0 my $lib_data = $self->lib_data;
1212 0         0 push @{ $lib_data }, @new_lib_data;
  0         0  
1213 0         0 $self->set_lib_data( $lib_data ); # called for side-effects:
1214             # set_up_ec_lib_loader
1215 0         0 return \@new_lib_data;
1216             }
1217              
1218             =item process_emacs_libs_reset
1219              
1220             This converts the list of emacs_libs into the lib_data style of
1221             structure much like L, but this
1222             method resets the lib_data field to the given value at
1223             init time (if any) before appending the new data.
1224              
1225             Defaults to using the object's "emacs_libs" setting.
1226              
1227             Returns a reference to a structure containing the additions to lib_data
1228             from emacs_libs.
1229              
1230             =cut
1231              
1232             sub process_emacs_libs_reset {
1233 0     0 1 0 my $self = shift;
1234 0   0     0 my $libs = shift || $self->emacs_libs;
1235              
1236 0         0 $self->reset_lib_data;
1237              
1238 0         0 my @new_lib_data;
1239 0         0 foreach my $name ( @{ $libs } ) {
  0         0  
1240 0         0 my $rec = [ $name, { type=>undef, priority=>undef } ];
1241 0         0 push @new_lib_data, $rec;
1242             }
1243              
1244 0         0 my $lib_data = $self->lib_data;
1245 0         0 push @{ $lib_data }, @new_lib_data;
  0         0  
1246 0         0 $self->set_lib_data( $lib_data ); # called for side-effects:
1247             # set_up_ec_lib_loader
1248 0         0 return \@new_lib_data;
1249             }
1250              
1251             =item set_up_ec_lib_loader
1252              
1253             Initializes the ec_lib_loader attribute by scanning for the
1254             appropriate emacs init file(s) and processing the list(s) of emacs
1255             libraries specified in the object data.
1256              
1257             Returns the newly defined $ec_lib_loader string.
1258              
1259             This routine is called (indirectly) by L during object
1260             initialization.
1261              
1262             =cut
1263              
1264             sub set_up_ec_lib_loader {
1265 0     0 1 0 my $self = shift;
1266              
1267 0         0 $self->genec_load_emacs_init; # zeroes out the ec_lib_loader string first
1268              
1269 0         0 my $lib_data = $self->lib_data;
1270              
1271 0         0 foreach my $rec (@{ $lib_data }) {
  0         0  
1272              
1273 0         0 my $name = $rec->[0];
1274 0         0 my $type = $rec->[1]->{type}; # file/lib
1275 0         0 my $priority = $rec->[1]->{priority}; # needed/requested
1276              
1277             # qualify the lib_data
1278 0 0       0 unless ( $type ) {
1279 0         0 $type = $self->lib_or_file( $name );
1280 0         0 $rec->[1]->{type} = $type;
1281             }
1282 0 0       0 unless ( $priority ) {
1283 0         0 $priority = $self->default_priority;
1284 0         0 $rec->[1]->{priority} = $priority;
1285             }
1286              
1287 0         0 my $method = sprintf "genec_loader_%s_%s", $type, $priority;
1288 0         0 $self->$method( $name ); # appends to ec_lib_loader
1289             }
1290              
1291 0         0 my $ec_lib_loader = $self->ec_lib_loader;
1292              
1293 0         0 return $ec_lib_loader;
1294             }
1295              
1296             =back
1297              
1298             =head2 Generation of Emacs Command Strings to Load Libraries
1299              
1300             These are routines run by L that generate a
1301             string that can be included in an emacs command line invocation to
1302             load certain libraries. Note the naming convention: "generate emacs
1303             command-line" => "genec_".
1304              
1305             =over
1306              
1307             =item genec_load_emacs_init
1308              
1309             Generates an emacs command line fragment to load the
1310             emacs_init file(s) as appropriate.
1311              
1312             Side effect: zeroes out the ec_lib_loader before rebuilding with inits only.
1313              
1314             =cut
1315              
1316             sub genec_load_emacs_init {
1317 0     0 1 0 my $self = shift;
1318              
1319             # start from clean slate
1320 0         0 my $ec_lib_loader = $self->set_ec_lib_loader( '' );
1321              
1322 0         0 my $load_no_inits = $self->load_no_inits;
1323 0 0       0 if ( $load_no_inits ) {
1324 0         0 return $ec_lib_loader; # empty string
1325             }
1326              
1327 0         0 my $load_emacs_init = $self->load_emacs_init;
1328 0         0 my $load_site_init = $self->load_site_init;
1329 0         0 my $load_default_init = $self->load_default_init;
1330              
1331 0 0 0     0 if ( ( $load_site_init ) && ( $self->detect_site_init() ) ) {
1332 0         0 my $ec = qq{ -l "site-start" };
1333 0         0 $self->append_to_ec_lib_loader( $ec );
1334             }
1335              
1336 0 0       0 if ($load_emacs_init) {
1337 0         0 my $dot_emacs = $self->find_dot_emacs;
1338 0 0       0 if ( $dot_emacs ) {
1339 0         0 my $ec = qq{ -l "$dot_emacs" };
1340 0         0 $self->append_to_ec_lib_loader( $ec );
1341             }
1342             }
1343              
1344 0 0 0     0 if ( ($load_default_init) && ($self->detect_lib( 'default' )) ) {
1345 0         0 my $ec = qq{ -l "default" };
1346 0         0 $self->append_to_ec_lib_loader( $ec );
1347             }
1348              
1349 0         0 $ec_lib_loader = $self->ec_lib_loader;
1350 0         0 return $ec_lib_loader;
1351             }
1352              
1353             =item Genec Methods Called Dynamically
1354              
1355             The following is a set of four routines used by
1356             "set_up_ec_lib_loader" to generate a string that can be included
1357             in an emacs command line invocation to load the given library.
1358             The methods here are named according to the pattern:
1359              
1360             "genec_loader_$type_$priority"
1361              
1362             where type is 'lib' or 'file' and priority is 'requested' or 'needed'.
1363              
1364             All of these methods return the generated string, but also append it
1365             to the L attribute.
1366              
1367             =over
1368              
1369             =item genec_loader_lib_needed
1370              
1371             =cut
1372              
1373             # used by set_up_ec_lib_loader
1374             sub genec_loader_lib_needed {
1375 0     0 1 0 my $self = shift;
1376 0         0 my $name = shift;
1377              
1378 0 0       0 unless( defined( $name) ) {
1379 0         0 return;
1380             }
1381              
1382 0         0 my $ec = qq{ -l "$name" };
1383             # TODO what happens with names that contain double-quotes?
1384              
1385 0         0 $self->append_to_ec_lib_loader( $ec );
1386 0         0 return $ec;
1387             }
1388              
1389             =item genec_loader_file_needed
1390              
1391             =cut
1392              
1393             # used by set_up_ec_lib_loader
1394             sub genec_loader_file_needed {
1395 0     0 1 0 my $self = shift;
1396 0         0 my $name = shift;
1397              
1398 0 0       0 unless ( -e $name ) {
1399 0         0 croak "Could not find required elisp library file: $name.";
1400             }
1401 0         0 my $elisp =
1402             $self->quote_elisp(
1403             $self->elisp_to_load_file( $name )
1404             );
1405 0         0 my $ec = qq{ --eval "$elisp" };
1406 0         0 $self->append_to_ec_lib_loader( $ec );
1407 0         0 return $ec;
1408             }
1409              
1410             =item genec_loader_lib_requested
1411              
1412             =cut
1413              
1414             # used by set_up_ec_lib_loader
1415             sub genec_loader_lib_requested {
1416 0     0 1 0 my $self = shift;
1417 0         0 my $name = shift;
1418              
1419 0 0       0 unless ( $self->detect_lib( $name ) ) {
1420 0         0 return;
1421             }
1422              
1423 0         0 my $ec = qq{ -l "$name" };
1424 0         0 $self->append_to_ec_lib_loader( $ec );
1425 0         0 return $ec;
1426             }
1427              
1428             =item genec_loader_file_requested
1429              
1430             =cut
1431              
1432             # used by set_up_ec_lib_loader
1433             sub genec_loader_file_requested {
1434 0     0 1 0 my $self = shift;
1435 0         0 my $name = shift;
1436              
1437 0 0       0 unless( -e $name ) {
1438 0         0 return;
1439             }
1440              
1441 0         0 my $elisp =
1442             $self->quote_elisp(
1443             $self->elisp_to_load_file( $name )
1444             );
1445              
1446 0         0 my $ec = qq{ --eval "$elisp" };
1447 0         0 $self->append_to_ec_lib_loader( $ec );
1448 0         0 return $ec;
1449             }
1450              
1451             =back
1452              
1453             =back
1454              
1455             =head2 Emacs probes
1456              
1457             Methods that return information about the emacs installation.
1458              
1459             =over
1460              
1461             =item probe_emacs_version
1462              
1463             Returns the version of the emacs program stored on your system.
1464             This is called during the object initialization phase.
1465              
1466             It checks the emacs specified in the object's emacs_path
1467             (which defaults to the simple command "emacs", sans any path),
1468             and returns the version.
1469              
1470             As a side-effect, it sets a number of object attributes with
1471             details about the emacs version:
1472              
1473             emacs_version
1474             emacs_major_version
1475             emacs_type
1476              
1477             Ignores redirector/shell_output_director.
1478              
1479             =cut
1480              
1481             sub probe_emacs_version {
1482 2     2 1 3 my $self = shift;
1483 2         3 my $opts = shift;
1484 2         17 my $subname = ( caller(0) )[3];
1485 2         30 my $devnull = File::Spec->devnull();
1486              
1487 2         4 my $redirector = 'stdout_only';
1488 2         9 my $sod = $self->redirector_to_sod( $redirector );
1489              
1490 2         26 my $emacs = $self->emacs_path;
1491 2         7 my $cmd = "$emacs --version $sod";
1492 2         29807 my $retval = qx{ $cmd };
1493             # $self->debug( "$subname:\n $retval\n" );
1494              
1495 2         102 my $version = $self->parse_emacs_version_string( $retval );
1496 2         78 return $version;
1497             }
1498              
1499              
1500             =item parse_emacs_version_string
1501              
1502             The emacs version string returned from running "emacs --version"
1503             is parsed by this routine, which picks out the version
1504             numbers and so on and saves them as object data.
1505              
1506             See probe_emacs_version (which uses this internally).
1507              
1508             =cut
1509              
1510             # Note, a Gnu emacs version string has a first line like so:
1511             # "GNU Emacs 22.1.1",
1512             # followed by several other lines.
1513             #
1514             # For xemacs, the last line is important, though it's preceeded by
1515             # various messages about for libraries loaded.
1516              
1517             # Typical version lines.
1518             # GNU Emacs 22.1.1
1519             # GNU Emacs 22.1.92.1
1520             # GNU Emacs 23.0.0.1
1521             # GNU Emacs 21.4.1
1522             # XEmacs 21.4 (patch 18) "Social Property" [Lucid] (amd64-debian-linux, Mule) of Wed Dec 21 2005 on yellow
1523              
1524             sub parse_emacs_version_string {
1525 2     2 1 17 my $self = shift;
1526 2         11 my $version_mess = shift;
1527 2 50       38 unless( $version_mess ) {
1528 2         16 return;
1529             }
1530              
1531 0         0 my ($emacs_type, $version);
1532             # TODO assuming versions are digits only (\d). Ever have letters, e.g. 'b'?
1533 0 0       0 if ( $version_mess =~ m{^ ( GNU \s+ Emacs ) \s+ ( [\d.]* ) }xms ) {
    0          
1534 0         0 $emacs_type = $1;
1535 0         0 $version = $2;
1536             } elsif ( $version_mess =~ m{ ^( XEmacs ) \s+ ( [\d.]* ) }xms ) {
1537 0         0 $emacs_type = $1;
1538 0         0 $version = $2;
1539             } else {
1540 0         0 $emacs_type ="not so gnu, not xemacs either";
1541 0         0 $version = ''; # silence uninitialized value warnings
1542             }
1543 0         0 $self->debug( "version: $version\n" );
1544              
1545 0         0 $self->set_emacs_type( $emacs_type );
1546 0         0 $self->set_emacs_version( $version );
1547              
1548 0         0 my (@v) = split /\./, $version;
1549              
1550 0         0 my $major_version;
1551 0 0       0 if( defined( $v[0] ) ) {
1552 0         0 $major_version = $v[0];
1553             } else {
1554 0         0 $major_version = ''; # silence unitialized value warnings
1555             }
1556 0         0 $self->set_emacs_major_version( $major_version );
1557 0         0 $self->debug( "major_version: $major_version\n" );
1558              
1559 0         0 return $version;
1560             }
1561              
1562             =back
1563              
1564             =head2 Utilities Used by Initialization
1565              
1566             =over
1567              
1568             =item elisp_to_load_file
1569              
1570             Given the location of an emacs lisp file, generate the elisp
1571             that ensures the library will be available and loaded.
1572              
1573             =cut
1574              
1575             sub elisp_to_load_file {
1576 0     0 1 0 my $self = shift;
1577 0         0 my $elisp_file = shift;
1578              
1579 0         0 my $path = dirname( $elisp_file );
1580              
1581 0         0 my $elisp = qq{
1582             (progn
1583             (add-to-list 'load-path
1584             (expand-file-name "$path/"))
1585             (load-file "$elisp_file"))
1586             };
1587             }
1588              
1589             =item find_dot_emacs
1590              
1591             Looks for one of the variants of the user's emacs init file
1592             (e.g. "~/.emacs") in the same order that emacs would, and
1593             returns the first one found.
1594              
1595             Note: this relies on the environment variable $HOME. (This
1596             can be changed first to cause this to look for an emacs init
1597             in some arbitrary location, e.g. for testing purposes.)
1598              
1599             This code does not issue a warning if the elc is stale compared to
1600             the el, that's left up to emacs.
1601              
1602             =cut
1603              
1604             sub find_dot_emacs {
1605 0     0 1 0 my $self = shift;
1606 0         0 my @dot_emacs_candidates = (
1607             "$HOME/.emacs",
1608             "$HOME/.emacs.elc",
1609             "$HOME/.emacs.el",
1610             "$HOME/.emacs.d/init.elc",
1611             "$HOME/.emacs.d/init.el",
1612             );
1613              
1614 0     0   0 my $dot_emacs = first { -e $_ } @dot_emacs_candidates;
  0         0  
1615 0         0 return $dot_emacs;
1616             }
1617              
1618             =item detect_site_init
1619              
1620             Looks for the "site-start.el" file in the raw load-path
1621             without loading the regular emacs init file (e.g. ~/.emacs).
1622              
1623             Emacs itself normally loads this file before it loads
1624             anything else, so this method replicates that behavior.
1625              
1626             Returns the library name ('site-start') if found, undef if not.
1627              
1628             Ignores redirector/shell_output_director.
1629              
1630             =cut
1631              
1632             # runs an emacs batch process as a probe, and if the command
1633             # runs "successfully", it checks the return value, and parses
1634             # it to see if the library was in fact found.
1635              
1636             # Note that this routine can not easily be written to use
1637             # detect_lib below, because of the different handling of .emacs
1638              
1639             sub detect_site_init {
1640 0     0 1 0 my $self = shift;
1641 0         0 my $opts = shift;
1642 0         0 my $subname = ( caller(0) )[3];
1643              
1644 0         0 my $redirector = 'all_output';
1645 0         0 my $sod = $self->redirector_to_sod( $redirector );
1646              
1647 0         0 my $emacs = $self->emacs_path;
1648 0         0 my $before_hook = $self->before_hook;
1649 0         0 my $lib_name = 'site-start';
1650              
1651 0         0 my $cmd = qq{ $emacs --batch $before_hook -l $lib_name $sod };
1652 0         0 $self->debug("$subname cmd:\n $cmd\n");
1653              
1654 0         0 my $retval = qx{ $cmd };
1655 0         0 $self->debug("$subname retval:\n $retval\n");
1656              
1657 0 0 0     0 if ( defined( $retval ) &&
1658             $retval =~
1659             m{\bCannot \s+ open \s+ load \s+ file: \s+ $lib_name \b}xms ) {
1660 0         0 return;
1661             } else {
1662 0         0 return $lib_name;
1663             }
1664             }
1665              
1666             =item detect_lib
1667              
1668             Looks for the given elisp library in the load-path after
1669             trying to load the given list of context_libs (that includes .emacs
1670             as appropriate, and this method uses the requested_load_files as
1671             context, as well).
1672              
1673             Returns $lib if found, undef if not.
1674              
1675             Example usage:
1676              
1677             if ( $self->detect_lib("dired") ) {
1678             print "As expected, dired.el is installed.";
1679             }
1680              
1681             my @good_libs = grep { defined($_) } map{ $self->detect_lib($_) } @candidate_libs;
1682              
1683             Ignores redirector/shell_output_director.
1684              
1685             =cut
1686              
1687             sub detect_lib {
1688 0     0 1 0 my $self = shift;
1689 0         0 my $lib = shift;
1690 0         0 my $opts = shift;
1691 0         0 my $subname = (caller(0))[3];
1692              
1693 0 0       0 return unless $lib;
1694              
1695 0         0 my $redirector = 'all_output';
1696 0         0 my $sod = $self->redirector_to_sod( $redirector );
1697              
1698 0         0 my $emacs = $self->emacs_path;
1699 0         0 my $before_hook = $self->before_hook;
1700 0         0 my $ec_head = qq{ $emacs --batch $before_hook };
1701             # cmd string to load existing, presumably vetted, libs
1702 0         0 my $ec_lib_loader = $self->ec_lib_loader;
1703              
1704 0         0 my $cmd = qq{ $ec_head $ec_lib_loader -l $lib $sod};
1705 0         0 my $retval = qx{ $cmd };
1706              
1707 0 0 0     0 if ( defined( $retval ) &&
1708             $retval =~ m{\bCannot \s+ open \s+ load \s+ file: \s+ $lib \b}xms ) {
1709 0         0 return;
1710             } else {
1711 0         0 return $lib;
1712             }
1713             }
1714              
1715              
1716             =item lib_or_file
1717              
1718             Given the name of an emacs library, examine it to see if it
1719             looks like a file system path, or an emacs library (technically
1720             a "feature name", i.e. sans path or extension).
1721              
1722             Returns a string, either "file" or "lib".
1723              
1724             =cut
1725              
1726             sub lib_or_file {
1727 0     0 1 0 my $self = shift;
1728 0         0 my $name = shift;
1729              
1730 0         0 my $path_found;
1731 0         0 my ($volume,$directories,$file) = File::Spec->splitpath( $name );
1732 0 0 0     0 if( $directories || $volume ) {
1733 0         0 $path_found = 1;
1734             }
1735              
1736 0         0 my $ext_found = ( $name =~ m{\.el[c]?$}xms );
1737              
1738 0         0 my $type;
1739 0 0       0 if ($path_found) {
    0          
1740 0         0 $type = 'file';
1741             } elsif ($ext_found) {
1742 0         0 $type = 'file';
1743             } else {
1744 0         0 $type = 'lib';
1745             }
1746 0         0 return $type;
1747             }
1748              
1749              
1750             =back
1751              
1752             =head2 Routines in Use by Some External Libraries
1753              
1754             These aren't expected to be generally useful methods, but
1755             they are in use by some code (notably L).
1756              
1757             =over
1758              
1759             =item elisp_file_from_library_name_if_in_loadpath
1760              
1761             Identifies the file associated with a given elisp library name by
1762             shelling out to emacs in batch mode.
1763              
1764             =cut
1765              
1766             # used externally by Emacs::Run::ExtractDocs
1767             sub elisp_file_from_library_name_if_in_loadpath {
1768 0     0 1 0 my $self = shift;
1769 0         0 my $library = shift;
1770 0         0 my $subname = (caller(0))[3];
1771              
1772 0         0 my $elisp = qq{
1773             (progn
1774             (setq codefile (locate-library "$library"))
1775             (message codefile))
1776             };
1777              
1778 0         0 my $return = $self->eval_elisp( $elisp );
1779              
1780 0         0 my $last_line = ( split /\n/, $return )[-1];
1781              
1782 0         0 my $file;
1783 0 0 0     0 if ( ($last_line) && (-e $last_line) ) {
1784 0         0 $self->debug( "$subname: $last_line is associated with $library\n" );
1785 0         0 $file = $last_line;
1786             } else {
1787 0         0 $self->debug( "$subname: no file name found for lib: $library\n" );
1788 0         0 $file = undef;
1789             }
1790              
1791 0         0 return $file;
1792             }
1793              
1794             =item generate_elisp_to_load_library
1795              
1796             Generates elisp code that will instruct emacs to load the given
1797             library. It also makes sure it's location is in the load-path, which
1798             is not precisely the same thing: See "Loaded vs. in load-path".
1799              
1800             Takes one argument, which can either be the name of the library, or
1801             the name of the file, as distinguished by the presence of a ".el"
1802             extension on a file name. Also, the file name will usually have a
1803             path included, but the library name can not.
1804              
1805             =cut
1806              
1807             # used externally by Emacs::Run::ExtractDocs
1808             sub generate_elisp_to_load_library {
1809 0     0 1 0 my $self = shift;
1810 0         0 my $arg = shift;
1811              
1812 0         0 my ($elisp, $elisp_file);
1813 0 0       0 if ($arg =~ m{\.el$}){
1814 0         0 $elisp_file = $arg;
1815 0         0 $elisp = $self->elisp_to_load_file( $elisp_file );
1816             } else {
1817              
1818 0         0 $elisp_file = $self->elisp_file_from_library_name_if_in_loadpath( $arg );
1819              
1820 0 0       0 unless( $elisp_file ) {
1821 0         0 croak "Could not determine the file for the named library: $arg";
1822             }
1823              
1824 0         0 $elisp = $self->elisp_to_load_file( $elisp_file );
1825             }
1826 0         0 return $elisp;
1827             }
1828              
1829              
1830             =back
1831              
1832             =head2 Basic Setters and Getters
1833              
1834             The naming convention in use here is that setters begin with
1835             "set_", but getters have *no* prefix: the most commonly used case
1836             deserves the simplest syntax (and mutators are deprecated).
1837              
1838             Setters and getters exist for all of the object attributes which are
1839             documented with the L method (but note that these exist even for
1840             "internal" attributes that are not expected to be useful to the client
1841             coder).
1842              
1843             =head2 Special Accessors
1844              
1845             =over
1846              
1847             =item append_to_ec_lib_loader
1848              
1849             Non-standard setter that appends the given string to the
1850             the L attribute.
1851              
1852             =cut
1853              
1854             sub append_to_ec_lib_loader {
1855 0     0 1 0 my $self = shift;
1856 0         0 my $append_string = shift;
1857              
1858 0   0     0 my $ec_lib_loader = $self->{ ec_lib_loader } || '';
1859 0         0 $ec_lib_loader .= $append_string;
1860              
1861 0         0 $self->{ ec_lib_loader } = $ec_lib_loader;
1862              
1863 0         0 return $ec_lib_loader;
1864             }
1865              
1866              
1867             =item append_to_before_hook
1868              
1869             Non-standard setter that appends the given string to the
1870             the L attribute.
1871              
1872             Under some circumstances, this module uses the L for
1873             internal purposes (for -Q and --no-splash), so using an ordinary
1874             setter might erase something you didn't realize was there.
1875             Typically it's safer to do an append to the L by
1876             using this method.
1877              
1878             =cut
1879              
1880             sub append_to_before_hook {
1881 0     0 1 0 my $self = shift;
1882 0         0 my $append_string = shift;
1883              
1884 0   0     0 my $before_hook = $self->{ before_hook } || '';
1885 0         0 $before_hook .= $append_string;
1886              
1887 0         0 $self->{ before_hook } = $before_hook;
1888              
1889 0         0 return $before_hook;
1890             }
1891              
1892             =back
1893              
1894             =head2 accessors that effect the L attribute
1895              
1896             If either lib_data or emacs_libs is modified, this must
1897             trigger another run of L to keep
1898             the L string up-to-date.
1899              
1900             =over
1901              
1902             =item set_lib_data
1903              
1904             Setter for lib_data.
1905              
1906             =cut
1907              
1908             sub set_lib_data {
1909 0     0 1 0 my $self = shift;
1910 0         0 my $lib_data = shift;
1911 0         0 $self->{ lib_data } = $lib_data;
1912 0         0 $self->set_up_ec_lib_loader;
1913 0         0 return $lib_data;
1914             }
1915              
1916              
1917             =item reset_lib_data
1918              
1919             Reverts lib_data to the value supplied during
1920             initization (it empties it entirely, if none was supplied).
1921              
1922             Note: this does not (at present) trigger a re-build of L,
1923             because it's presumed that this will be triggered by some step
1924             following this one.
1925              
1926             =cut
1927              
1928             sub reset_lib_data {
1929 0     0 1 0 my $self = shift;
1930 0         0 @{ $self->{ lib_data } } = @{ $self->{ lib_data_given } };
  0         0  
  0         0  
1931 0         0 return $self->{ lib_data };
1932             }
1933              
1934              
1935              
1936             =item set_emacs_libs
1937              
1938             Setter for emacs_libs.
1939              
1940             Side effect: runs process_emacs_libs_rest on the given emacs_libs
1941             list.
1942              
1943             process_emacs_libs_reset indirectly calls set_up_ec_lib_loader
1944             so we don't need to do so explicitly here.
1945              
1946             =cut
1947              
1948             sub set_emacs_libs {
1949 0     0 1 0 my $self = shift;
1950 0         0 my $emacs_libs = shift;
1951 0         0 $self->{ emacs_libs } = $emacs_libs;
1952 0         0 $self->process_emacs_libs_reset( $emacs_libs );
1953 0         0 return $emacs_libs;
1954             }
1955              
1956             =item push_emacs_libs
1957              
1958             Pushes a new lib to the emacs_libs array.
1959              
1960             Takes a string, returns aref of the full list of emacs_libs.
1961              
1962             Side-effect: runs process_emacs_libs_addition on the new lib,
1963             (appending the new info to lib_data).
1964              
1965             process_emacs_libs_addition indirectly calls set_up_ec_lib_loader
1966             so we don't need to do so explicitly here.
1967              
1968             =cut
1969              
1970             sub push_emacs_libs {
1971 0     0 1 0 my $self = shift;
1972 0         0 my $newlib = shift;
1973              
1974 0         0 my $emacs_libs = $self->emacs_libs;
1975 0         0 push @{ $emacs_libs }, $newlib;
  0         0  
1976 0         0 $self->process_emacs_libs_addition( [ $newlib ] );
1977 0         0 return $emacs_libs;
1978             }
1979              
1980             =item set_redirector
1981              
1982             Setter for object attribute set_redirector.
1983             Automatically sets the shell_output_director field.
1984              
1985             =cut
1986              
1987             sub set_redirector {
1988 0     0 1 0 my $self = shift;
1989 0         0 my $redirector = shift;
1990 0         0 $self->{ redirector } = $redirector;
1991              
1992 0         0 $self->{ shell_output_director } = $self->redirector_to_sod( $redirector );
1993              
1994 0         0 return $redirector;
1995             }
1996              
1997              
1998              
1999              
2000             # automatic generation of the basic setters and getters
2001             sub AUTOLOAD {
2002 2 50   2   9 return if $AUTOLOAD =~ /DESTROY$/; # skip calls to DESTROY ()
2003              
2004 2         14 my ($name) = $AUTOLOAD =~ /([^:]+)$/; # extract method name
2005 2         5 (my $field = $name) =~ s/^set_//;
2006              
2007             # check that this is a valid accessor call
2008 2 50       8 croak("Unknown method '$AUTOLOAD' called")
2009             unless defined( $ATTRIBUTES{ $field } );
2010              
2011 3     3   48 { no strict 'refs';
  3         63  
  3         962  
  2         3  
2012              
2013             # create the setter and getter and install them in the symbol table
2014              
2015 2 50       17 if ( $name =~ /^set_/ ) {
    50          
2016              
2017             *$name = sub {
2018 0     0   0 my $self = shift;
2019 0         0 $self->{ $field } = shift;
2020 0         0 return $self->{ $field };
2021 0         0 };
2022              
2023 0         0 goto &$name; # jump to the new method.
2024             } elsif ( $name =~ /^get_/ ) {
2025 0         0 carp("Apparent attempt at using a getter with unneeded 'get_' prefix.");
2026             }
2027              
2028             *$name = sub {
2029 2     2   3 my $self = shift;
2030 2         15 return $self->{ $field };
2031 2         12 };
2032              
2033 2         66 goto &$name; # jump to the new method.
2034             }
2035             }
2036              
2037              
2038             1;
2039              
2040             ### end of code
2041              
2042             =back
2043              
2044             =head2 Controlling Output Redirection
2045              
2046             As described under L, the L is a code used to
2047             control what happens to the output streams STDOUT and STDERR (or
2048             in elisp terms, the output from "print" or "message"):
2049             B, B or B.
2050              
2051             The client programmer may not need to worry about the L at
2052             all, since some (hopefully) sensible defaults have been chosen for the
2053             major methods here:
2054              
2055             all_output (using the object default)
2056              
2057             eval_elisp
2058             run_elisp_on_file
2059              
2060             stdout_only (special method-level defaults)
2061              
2062             get_load_path
2063             get_variable
2064             eval_function
2065              
2066             In addition to being able to set L at instantiation
2067             (as an option to L), L can also often be set
2068             at the method level to temporarily override the object-level setting.
2069              
2070             For example, if "eval_elisp" is returning some messages to STDERR
2071             that you'd rather filter out, you could do that in one of two ways:
2072              
2073             Changing the object-wide default:
2074              
2075             my $er = Emacs::Run->new( { redirector => 'stdout_only' } );
2076             my $result = $er->eval_elisp( $elisp_code );
2077              
2078             Using an option specific to this method call:
2079              
2080             my $er = Emacs::Run->new();
2081             my $result = $er->eval_elisp( $elisp_code, { redirector => 'stdout_only' } );
2082              
2083             If you need some behavior not supported by these redirector codes,
2084             it is possible to use a Bourne-shell style redirect, like so:
2085              
2086             # return stdout only, but maintain an error log file
2087             my $er = Emacs::Run->new( { shell_output_director => "2>$logfile" } );
2088             my $result = $er->eval_elisp( $elisp_code );
2089              
2090             As with L, the L can be set
2091             at the object-level or (often) at the method-level.
2092              
2093             =over
2094              
2095             =item shell_output_director
2096              
2097             The B (sometimes called B for short) is a
2098             string appended to the internally generated emacs invocation commands to
2099             control what happens to output.
2100              
2101             Typical values (on a unix-like system) are:
2102              
2103             =over
2104              
2105             =item '2>&1'
2106              
2107             Intermix STDOUT and STDERR (in elisp: both "message" and "print"
2108             functions work).
2109              
2110             =item '2>/dev/null'
2111              
2112             return only STDOUT, throwing away STDERR (in elisp: get output
2113             only from "print"). But see L's B.
2114              
2115             =item "> $file 2>&1"
2116              
2117             send all output to the file $file
2118              
2119             =item ">> $file 2>&1"
2120              
2121             append all output to the file $file, preserving any existing
2122             content.
2123              
2124             =item "2 > $log_file"
2125              
2126             return only STDOUT, but save STDERR to $log_file
2127              
2128             =back
2129              
2130             =back
2131              
2132             =head1 internal documentation (how the code works, etc).
2133              
2134             =head2 internal attributes
2135              
2136             Object attributes intended largely for internal use. The client
2137             programmer has access to these, but is not expected to need it.
2138             Note: the common "leading underscore" naming convention is not used here.
2139              
2140             =over
2141              
2142             =item ec_lib_loader
2143              
2144             A fragment of an emacs command line invocation to load emacs libraries.
2145             Different attributes exist to specify emacs libraries to be loaded:
2146             as these are processed, the ec_lib_loader string gradually accumulates
2147             code needed to load them (so that when need be, the process can use
2148             the intermediate value of the ec_lib_loader to get the benefit of
2149             the previously processed library specifications).
2150              
2151             The primary reason for this approach is that each library loaded
2152             has the potential to modify the emacs load-path, which may be
2153             key for the success of later load attempts.
2154              
2155             The process of probing for each library in one of the "requested"
2156             lists has to be done in the context of all libraries that have been
2157             previously found. Without some place to store intermediate results
2158             in some form, this process might need to be programmed as one large
2159             monolithic routine.
2160              
2161             =item lib_data_initial
2162              
2163             The initial setting of L when the object is instantiated.
2164             As currently implemented, some operations here require resetting
2165             the state of L and re-building it. This attribute
2166             facilitates that process.
2167              
2168             =back
2169              
2170             =head2 Loaded vs. in load-path
2171              
2172             The emacs variable "load-path" behaves much like the shell's $PATH
2173             (or perl's @INC): if you try to load a library called "dired", emacs
2174             searches through the load-path in sequence, looking for an appropriately
2175             named file (e.g. "dired.el"), it then evaluates it's contents, and
2176             the features defined in the file become available for use. It is also possible
2177             to load a file by telling emacs the path and filename, and that works
2178             whether or not it is located in the load-path.
2179              
2180             There I at least a slight difference between the two, however.
2181             For example, the present version of the "extract-docstrings.el"
2182             library (see L) contains code like this, that
2183             will break if the library you're looking for is not in the load-path:
2184              
2185             (setq codefile (locate-library library))
2186              
2187             So some of the routines here (notably L)
2188             generate elisp with an extra feature that adds the location of the file
2189             to the load-path as well as just loading it.
2190              
2191             =head2 Interactive vs. Non-interactive Elisp Init
2192              
2193             Emacs::Run tries to use the user's normal emacs init process even
2194             though it runs non-interactively. Unfortunately, it's possible that
2195             the init files may need to be cleaned up in order to be used
2196             non-interactively. In my case I found that I needed to check the
2197             "x-no-window-manager" variable and selectively disable some code that
2198             sets X fonts for me:
2199              
2200             ;; We must do this check to allow "emacs --batch -l .emacs" to work
2201             (unless (eq x-no-window-manager nil)
2202             (zoom-set-font "-Misc-Fixed-Bold-R-Normal--15-140-75-75-C-90-ISO8859-1"))
2203              
2204             Alternately, L may be used to run elisp using a
2205             full, externally spawned emacs, without using the --batch option:
2206             you'll see another emacs window temporarily spring into life, and then
2207             get destroyed, after passing the contents of the current-buffer back
2208             by using a temporary file.
2209              
2210             =head2 INTERNALS
2211              
2212             =head3 The Tree of Method Calls
2213              
2214             The potential tree of method calls now runs fairly deep. A bug in a
2215             primitive such as L can have wide-ranging effects:
2216              
2217             new
2218             init
2219             append_to_before_hook
2220             process_emacs_libs_addition
2221             set_up_ec_lib_loader
2222             lib_or_file
2223             genec_load_emacs_init
2224             append_to_ec_lib_loader
2225             detect_site_init
2226             detect_lib
2227             genec_loader_lib_needed
2228             append_to_ec_lib_loader
2229             genec_loader_file_needed
2230             quote_elisp
2231             elisp_to_load_file
2232             append_to_ec_lib_loader
2233             genec_loader_lib_requested
2234             detect_lib
2235             append_to_ec_lib_loader
2236             genec_loader_file_requested
2237             quote_elisp
2238             elisp_to_load_file
2239             append_to_ec_lib_loader
2240             probe_emacs_version
2241             parse_emacs_version_string
2242              
2243              
2244             eval_elisp
2245             quote_elisp
2246             clean_return_value
2247             set_up_ec_lib_loader
2248             lib_or_file
2249             genec_load_emacs_init
2250             append_to_ec_lib_loader
2251             find_dot_emacs
2252             detect_site_init
2253             detect_lib
2254             genec_loader_lib_needed
2255             append_to_ec_lib_loader
2256             genec_loader_file_needed
2257             quote_elisp
2258             elisp_to_load_file
2259             append_to_ec_lib_loader
2260             genec_loader_lib_requested
2261             detect_lib
2262             append_to_ec_lib_loader
2263             genec_loader_file_requested
2264             quote_elisp
2265             elisp_to_load_file
2266             append_to_ec_lib_loader
2267              
2268             Note that as of this writing (version 0.09) this code ensures that
2269             the L string is up-to-date by continually re-generating
2270             it.
2271              
2272             =head1 TODO
2273              
2274             =over
2275              
2276             =item *
2277              
2278             Rather than use elisp's "print", should probably use "prin1" (does what
2279             you mean without need for a clean-up routine).
2280              
2281             =item *
2282              
2283             Look into cache tricks (just Memoize?) to speed things up a
2284             little. See L.
2285              
2286             =item *
2287              
2288             Have "new" fail (return undef) if emacs can not be
2289             found on the system. This way you can use the result
2290             of "new" to determine if you should skip tests, etc.
2291              
2292             =item *
2293              
2294             I suspect some quoting issues still lurk e.g. a library
2295             filename containing a double-quote will probably crash things.
2296              
2297             =item *
2298              
2299             Add a method to match an emacs regexp against a string. See:
2300             L
2301              
2302             (goto-char (point-min))
2303             (re-search-forward "$elisp_pattern")
2304             (setq first_capture (match-string 1))
2305              
2306             =item *
2307              
2308             In L, add support for skipping to a line number
2309             after opening a file
2310              
2311             =item *
2312              
2313             I think this feature of emacs invocation could be used to simplify
2314             things a little (I'm manipulating load-path directly at present):
2315              
2316             `-L DIR'
2317             `--directory=DIR'
2318             Add directory DIR to the variable `load-path'.
2319              
2320             =item *
2321              
2322             loop in eval_elisp_full_emacs needs to time-out (e.g. if no output is written)
2323              
2324             =item *
2325              
2326             Write an alternate to the eval_elisp_full_emacs that captures an
2327             image of the external emacs process. (Allows automated tests of
2328             syntax coloring, etc.) Can this be done portably?
2329              
2330             =item *
2331              
2332             Write more tests of redirectors -- found and fixed (?) bug in stderr_only.
2333              
2334             =back
2335              
2336             =head1 BUGS & LIMITATIONS
2337              
2338             =over
2339              
2340             =item *
2341              
2342             When an elisp library is marked as "needed", and it is not available,
2343             failure occurs relatively late: it does not happen during object
2344             instantiation, but waits until an attempted run with the object
2345             (that is, on a call such as "$er->eval_elisp", not "Emacs::Run->new").
2346              
2347             =item *
2348              
2349             This module was developed around Gnu emacs running on a
2350             Gnu/linux platform. Some attempts have been made to make it's
2351             use portable to other platforms. At present, using it with a
2352             non-gnu emacs such as xemacs is not likely to work.
2353              
2354             =item *
2355              
2356             The L routine strips leading and trailing
2357             newline-quote pairs, but that only covers the case of individual
2358             elisp print functions. Evaluating elisp code with multiple
2359             prints will need something fancier to clean up their behavior.
2360              
2361             =item *
2362              
2363             L runs into trouble if there's a bug in the .emacs
2364             file, because it proceeds when it can find the file via
2365             L, but doesn't verify it will load cleanly:
2366             it charges ahead and tries to use it while doing a L,
2367             which gets confused because it looks for a very specific message
2368             to indicate failure, and doesn't understand any error messages from
2369             an earlier stage. It would probably be better for L
2370             to also vet the file, and error out if it doesn't succeed.
2371              
2372             =back
2373              
2374             =head1 SEE ALSO
2375              
2376             L
2377              
2378             Emacs Documentation: Command Line Arguments for Emacs Invocation
2379             L
2380              
2381             A lightning talk about (among other things) using perl to test
2382             emacs code: "Using perl to test non-perl code":
2383              
2384             L
2385              
2386             =head1 OTHER EXAMPLES
2387              
2388             Examples of "advanced" features (i.e. ones you're unlikely to want to use):
2389              
2390             # Specify in detail how the emacs lisp libraries should be loaded
2391             # (initialization does not fail if a library that's merely "requested"
2392             # is unavailable):
2393             $lib_data = [
2394             [ 'dired', { type=>'lib', priority=>'needed' } ],
2395             [ '/tmp/my-load-path.el', { type=>'file', priority=>'requested' } ],
2396             [ '/tmp/my-elisp.el', { type=>'file', priority=>'needed' } ],
2397             ];
2398             my $er = Emacs::Run->new({
2399             lib_data => $lib_data,
2400             });
2401             my $result = $er->eval_lisp(
2402             qq{ (print (my-elisp-run-my-code "$perl_string")) }
2403             );
2404              
2405              
2406              
2407             # using a "redirector" code (capture only stderr, ignore stdout, like '1>/dev/null')
2408             $er = Emacs::Run->new({
2409             redirector => 'stderr_only'
2410             });
2411             my $result = $er->eval_elisp( '(message "hello world") (print "you can't see me"))' );
2412              
2413              
2414              
2415             # View your emacs load_path from the command-line
2416             perl -MEmacs::Run -le'my $er=Emacs::Run->new; print for @{ $er->get_load_path }';
2417              
2418             # Note that the obvious direct emacs invocation will not show .emacs customizations:
2419             emacs --batch --eval "(print (mapconcat 'identity load-path \"\n\"))"
2420              
2421             # This does though
2422             emacs --batch -l ~/.emacs --eval "(prin1 (mapconcat 'identity load-path \"\n\"))" 2>/dev/null
2423              
2424              
2425             =head1 AUTHOR
2426              
2427             Joseph Brenner, Edoom@kzsu.stanford.eduE,
2428             07 Mar 2008
2429              
2430             =head1 COPYRIGHT AND LICENSE
2431              
2432             Copyright (C) 2008 by Joseph Brenner
2433              
2434             This library is free software; you can redistribute it and/or modify
2435             it under the same terms as Perl itself, either Perl version 5.8.2 or,
2436             at your option, any later version of Perl 5 you may have available.
2437              
2438              
2439             =cut