NAME
Emacs::Lisp - Support for Perl embedded in GNU Emacs
SYNOPSIS
In Emacs
M-x load-library RET perl RET
M-x perl-eval-expression RET 2+2 RET
In Perl
use Emacs::Lisp;
&switch_to_buffer('*scratch*');
&insert("Hello, world!\n");
setq { $cperl_font_lock = t };
&add_hook(\*find_file_hooks,
sub { &message("found a file!") });
use Emacs::Lisp qw($emacs_version);
save_excursion {
&set_buffer(&get_buffer_create("whatever"));
&insert("This is Emacs version $emacs_version, sort of.\n");
&insert("Emacs::Lisp version is $Emacs::Lisp::VERSION.\n");
};
DESCRIPTION
Until now, you could customize your Emacs environment using Lisp. Now you can use Perl, too. This module allows Perl code to call functions and access variables of Lisp. It also maps some Perl syntax into Lisp semantics.
You still need to learn some Lisp in order to understand the elisp manual, which you will need if you wish to learn about the details of Emacs programming. Hopefully, this situation will be cured by the appearance of well-documented Perl modules that give everything in Emacs a nice, object-oriented wrapping.
EMACS SUPPORT FOR PERL
A patched emacs program with embedded Perl can compile and evaluate Perl code via Emacs Lisp or the command line, independently of the Emacs::Lisp module.
Functions
The Perlmacs patch builds some Perl-related functions into Lisp. Use C-h f function-name RET
within Emacs for documentation on these.
perl-eval EXPRESSION &optional CONTEXT
perl-call CODEREF &optional CONTEXT &rest ARGS
make-perl-interpreter &rest ARGV
perl-run &optional INTERPRETER
perl-destruct &optional INTERPRETER
You need to do M-x load-library RET perl RET
(or hack your ~/.emacs) to get the following functions.
perl-eval-expression EXPRESSION
perl-eval-region START END
perl-eval-buffer
perl-load-file NAME
Note that the exact meaning of perl-load-file is a topic of research and will likely change.
Data Conversions
When data is passed between Lisp and Perl within Emacs, some basic principles apply. These are goals that may never be entirely met, due to the differences between Perl and Lisp.
Whatever Perl gives to Lisp should get dereferenced once.
A Perl reference gets converted into a Lisp reference to the thing referenced, not a Lisp reference to the Perl reference. (I find this to be intuitively correct behavior.)
Converting a non-dereferenceable value requires some kind of primitive conversion.
For example, Lisp integers, floats, and strings all become Perl scalars. A scalar (other than a reference) converted to Lisp will become either an integer, a float, or a string. Glob references in Perl become symbols in Lisp (subject to the usual underscore-to-hyphen translation).
Lisp's `nil' is equivalent to Perl's `undef' or `()'.
In Lisp,
nil
is really a symbol. However, it is typically used as the boolean value false. Perl's equivalent of symbols (glob references) evaluate to true in boolean contexts. Convertingnil
to anything other thanundef
(()
in list context) would be disastrous for programmers' mental health!Generally, converted values can be converted back to Perl more or less unchanged.
But not always. For example,
\*nil
would becomeundef
.Lisp objects which are not converted Perl stuff and have no natural counterpart become `Emacs::Lisp::Object' blessed references.
These hold the actual Lisp data and a means of protecting it from garbage collection. An Emacs::Lisp::Object reference converted back to Lisp is the Lisp object.
Scripts
Emacs with embedded Perl can run Perl programs. If the first command-line argument is --perl, the rest will be parsed as if by the perl program.
When you use Emacs::Lisp
in a script started this way, a Perl sub named Emacs::main may be used to invoke the Emacs editor. This makes it possible to put customization code, which would normally appear in ~/.emacs, into a "Perlmacs script". For example, this startup code
(setq
user-mail-address "gnaeus@perl.moc"
mail-self-blind t
mail-yank-prefix "> "
)
(put 'eval-expression 'disabled nil)
(global-font-lock-mode 1 t)
(set-face-background 'highlight "maroon")
(set-face-background 'region "Sienna")
could be placed in a file myemacs.pl with the following contents:
#! /usr/local/bin/emacs --perl
use Emacs::Lisp;
setq {
$user_mail_address = 'gnaeus@perl.moc';
$mail_self_blind = t;
$mail_yank_prefix = '> ';
$eval_expression{\*disabled} = undef;
};
&global_font_lock_mode(1, t);
&set_face_background(\*highlight, "maroon");
&set_face_background(\*region, "Sienna");
exit Emacs::main($0, "-q", @ARGV);
When you wanted to run Emacs, you would invoke this program.
The arguments to Emacs::main
correspond to the argv of the main function in a C program. The first argument should be the program's invocation name, as in this example. -q inhibits running ~/.emacs (which is what we're trying to get away from, after all).
See also "BUGS".
PERL SUPPORT FOR LISP
The Emacs::Lisp module allows Perl programs to invoke Lisp functions and handle Lisp data using Perl's syntax.
You don't have to do any work, other than use Emacs::Lisp
, to make subs call their Lisp counterpart. However, tying Lisp variables to Perl variables is not quite so automatic. In all cases, hyphens appearing in Lisp names are translated to underscores in Perl, and vice versa.
Functions
This code calls the hypothetical Lisp function foo-bar
with arguments 4
and t
.
&foo_bar(4, t);
The Lisp syntax for the same call would be
(foo-bar 4 t)
The ampersand (&) is only really needed for calling Lisp functions such as read
, eval
, and print
, which are Perl keywords. But using it is a good habit.
Symbols
Many Lisp functions take arguments that may be, or are required to be, symbols. Lisp programs typically use the quote
operator to specify a symbol. For example, this Lisp code refers to the beep
symbol:
(run-at-time nil 1 'beep)
Perl uses glob references of package main
to specify symbols. A literal glob reference begins with a backslash followed by an asterisk, so the last example would be written as
&run_at_time(undef, 1, \*beep);
in Perl. (You may want to do &cancel_function_timers(\*beep)
soon after trying this.)
Note that only globs from package main
get converted to symbols, so code that is compiled in another package must use \*::sym
rather than \*sym
to refer to the Lisp symbol sym
.
Variables
In Lisp, variables play a role akin to that of Perl scalars. A variable may hold a number, a string, or a reference to any type of complex Lisp data structure. (They are not called references in Lisp, but rather "objects".)
You can create a Perl alias for any reasonably named Lisp variable by saying use Emacs::Lisp qw($varname)
. Thereafter, assignment to $varname
will update the Lisp value. Changes made to the variable in Lisp will be reflected in $varname
when used in Perl expressions.
This example saves and replaces the value of the Lisp variable window-system
:
use Emacs::Lisp qw($window_system);
$old_ws = $window_system;
$window_system = \*y;
This sort of thing could be accomplished in Lisp as follows:
(setq old-ws window-system)
(setq window-system 'y)
See also the setq
function below.
Property Lists
Lisp symbols all have an associated object called a plist (for "property list"). Although it is actually an object just like any other, the plist is typically used in a way vaguely resembling Perl hashes.
[INCOMPLETE]
Special Forms
So-called "special forms" in Lisp, such as setq
and defun
, do not work the same way functions do. Some of them are equivalent to Perl operators, such as if
and and
. Others have meanings peculiar to Lisp.
A few special forms are implemented in Emacs::Lisp. They are listed below. If you try to call one that's not been implemented, you will get an error message, which may propose an alternative.
- save_excursion BLOCK
-
Execute BLOCK within a Lisp
save-excursion
construct. This restores the current buffer and other settings to their original values after the code has completed.Please read the elisp manual for details.
- setq BLOCK
-
BLOCK is searched for assignments (at top level) of the form
$var = EXPR;
where $var is a scalar variable or hash element. Every such variable is imported from the Emacs::Lisp module. (That is, it is tied to the similarly-named Lisp variable or plist.)
Afterwards, BLOCK is executed. Thus, this code
use Emacs::Lisp qw(setq); setq { $A = 2*$foo[5]; $B{\*foo} = "more than $A"; };
would have exactly the same effect as
use Emacs::Lisp qw(setq $A %B); $A = 2*$foo[5]; $B{\*foo} = "more than $A";
The following, which does not tie or import any symbols, has the same effect on Lisp as the above:
use Emacs::Lisp (); &Emacs::Lisp::set( \*A, 2*$foo[5] ); &Emacs::Lisp::put( \*B, \*foo, "more than " . &Emacs::Lisp::symbol_value( \*A ));
SUGGESTIONS/HELP REQUESTED
The guiding principle for Perlmacs is:
"Every interface has an implementation."
to which one could add (citing the Least Upper Bound principle):
"Every interface has one or more /best/ implementations."
The best implementations are not necessarily good, but one may hope that they are at least fair-to-middling. This is especially relevant when gluing together such incompatibles as Perl and Lisp.
Don't be too concerned about the quality of the implementation yet. What matters most is to come up with a good interface between Emacs and Perl (as we know them).
I will happily accept additions and bugfixes to the Perl module. Trivial fixes in the Emacs source will be accepted, but anything meaty may have to undergo the Full FSF Rigmarole. For a description of the rigmarole, please consult http://www.cygnus.com/egcs/contribute.html.
BUGS
To be addressed probably in Emacs C source
Crashes during complex throw/die and similar jump operations.
I think this is fixable, it just hasn't been fixed yet. (Remember, this is an ALPHA version.)
Memory leaks.
%ENV, %SIG, `setenv'.
Perl and Emacs use environment variables and signal handlers in different, incompatible ways. This needs to be coordinated. This issue is not unique to Emacs but affects every nontrivial Perl embedding. I don't know whether it's been solved in a general way.
Input/Output.
If Perl code tries to read from STDIN, Emacs becomes unresponsive. This is very distressing. Also, Perl loves to print error and warning messages to STDERR, which can be disconcerting. Perl's use of Standard I/O must be controlled. (I shudder to think what would happen if you used Perl compiled with sfio.)
`Emacs::main' does not clean up.
The Emacs::main sub may open an X display and not close it. That is the most obvious of many problems with Emacs::main.
For best results, the value returned by Emacs::main should be passed to Perl's exit soon, as in this code:
exit (Emacs::main($0, @args));
Probably can't use a coderef as an error handler or protected form.
I think this will be easy to fix.
A crash is likely if Perl code modifies `&Emacs::Lisp::Object::DESTROY'.
So don't.
See also the (many) FIXMEs in src/perlmacs.c and elsewhere.
Other places
Perl's `local()' doesn't have the effect of Lisp's `let'.
It should. At least, there should be an easy way to make a local binding of a Lisp variable in Perl.
Equality operators don't do Lisp `eq' or `equal'.
This is at best counterintuitive for Perl programmers.
Lacks texinfo documentation
Need to update .gdbinit, make-dist, and other places
CAVEATS
Circular data structures are bad.
See "Two-Phased Garbage Collection" in perlobj. Lisp data structures may be recursive (contain references to themselves) without the danger of a memory leak, because Lisp uses a periodic-mark-and-sweep garbage collection model. However, if a recursive structure involves any Perl references, it may never be destroyable.
Cross-language references incur overhead.
For the benefit of Lisp's garbage collection, all Perl data that is referenced by Lisp participates in the mark phase. For the benefit of Perl's garbage collection, all Lisp objects that are referenced by Perl maintain a reference count.
A chain of Perl -> Lisp -> ... -> Perl references may take several garbage collection cycles to be freed. It is therefore probably best to keep the number and complexity of such references to a minimum.
To the extent that the Perl-to-Emacs interface is independent of the Lispish implementation of Emacs, these performance issues may be fixable by reimplementing Emacs' internals. Or by rewriting Perl in Lisp.... but don't hold your breath. ;-)
Perl and Lisp don't trap each other's exceptions.
Perl's eval won't trap Lisp errors. Lisp's condition-case won't trap Perl errors, although perl-eval will convert a Perl error into a Lisp error.
TODO
Special Forms
There needs to be better support for certain special forms (see %special in Lisp.pm).
The basic problem is that Perl evaluates every sub's arguments before running the sub. This translates fine for ordinary Lisp functions. However, certain things which appear to be functions in Lisp are really either special forms or macros, meaning that they receive their arguments from Lisp in an unevaluated list.
Many of the (fortunately finite) special forms play a role which in Perl would be filled by a builtin operator or syntactic construct. For example, the setq special form is analogous to the assignment operator =
. The while special form roughly corresponds to Perl's while construct.
It would be nice just to be able to say, "Special forms don't work in Perl, use the corresponding Perl syntax instead." However, in some cases, this leads to excessive code, while in others, there is really no Perl equivalent (cf. track-mouse).
Often, the problematic forms take an argument that is to be evaluated as code. In such cases, I think the syntax offered by Perl subs with a prototype containing &
may be best suited. (See "Prototypes" in perlsub) This allows a Perl sub to recieve a coderef as an argument whose syntax is a BLOCK ({...}
), just like that of several Perl builtin operators.
That should work fine for forms like track-mouse which do nothing more to their unevalled arguments than eval them. However, the most interesting and useful special forms, such as setq and defun, do more than eval certain of their arguments. They analyze the unevalled list before deciding what to do. This is unfortunate for Perl, which can perform (essentially) only one operation on a coderef: namely, run it.
Luckily (I guess), XS can do more. Perl's version of setq is implemented with the help of XS code. (See perlxs, Lisp.pm, and Lisp.xs if you're curious.)
New Lisp functions
current-perl-interpreter
set-perl-interpreter INTERP
(?) perl-error-text &optional INTERP
(?) perl-phase &optional INTERP
(?) perl-status &optional INTERP
perl-replace-regexp, and such.
Miscellany
Better support for Lisp macros.
Parse the cmd line as Perl unless prog name contains "emacs".
Find a way to convert filehandles to the Emacs equivalent.
Complete the plist TIEHASH interface.
Document or scrap the vector TIEARRAY interface.
Improve perl-eval-buffer, perl-load-file, et al. (in C?)
Design a scheme for autoloading Perl files as is done with Lisp.
Arrange for load-library and friends to recognize `.p[ml]' files.
Allow *pre-dump* Perl initialization.
Allow multiple Perl interpreters (incomplete).
ACKNOWLEDGMENTS
These are among the giants on whose shoulders we stand:
- Larry Wall.
-
'Nuff said.
- The developers of GNU, and Richard Stallman in particular.
-
Many thanks for the most beautiful code base that it has ever been, or will ever likely be, my pleasure to hack.
- The inventor of Lisp, whose name presently escapes me.
- The inventors of Perl's truest mother language, C.
- �Évariste Galois (1811-1832) and Wolfgang Amadeus Mozart (1756-1791).
-
Each of them demonstrated just how much a young man can accomplish with a good mind.
- Ludwig van Beethoven (1770-1827).
-
Showed that even neurotic, deaf, aging crabapples can, from time to time, engender lasting beauty.
- Tim Bunce, whom I associate with the `DynaLoader' module and the Perl5 Module List.
-
I was lucky enough to come onto the Perl scene soon after dynamic loading had reached its present form (well, but before swig appeared). How you all got by before then completely baffles me.
-
ExtUtils::Embed is a cornerstone of Perlmacs.
This list is incomplete.
Personal thanks to Nate Patwardhan, who sparked my early interest in Perl--and shared his .emacs with me--during our NFIC days. Nate also introduced me to gdb under gud-mode, O well was I served! :)
Thanks also to Ilya Zakharevich for (1) encouraging me in my first contribution to the Perl development effort (an xsubpp patch), and (2) a comment in cperl-mode.el about changing Emacs C source. If not for that comment, I may never have realized that it is even possible for mortals to change Emacs C source. ;-) Although I didn't implement the change he requested, I hope Ilya approves.
COPYRIGHT
Copyright (C) 1998 by John Tobey, jtobey@channel1.com. All rights reserved. This module may be distributed and modified under the same terms as GNU Emacs. You should have received a copy of the GNU General Public License along with Emacs::Lisp; see the file COPYING. If not, retrieve it from ftp://prep.ai.mit.edu/pub/gnu/COPYING .
SEE ALSO
perl, emacs, and the elisp manual (available where you got the Emacs source ...one would hope).
1 POD Error
The following errors were encountered while parsing the POD:
- Around line 751:
Non-ASCII character seen before =encoding in '�Évariste'. Assuming CP1252