| Allegro CL version 9.0 Minimally revised from 8.2. 8.2 version |
This document contains the following sections:
1.0 Introduction to the Emacs-Lisp interfaceSee franz.com/emacs/ for information on obtaining Emacs (which is no longer supplied with the Allegro CL distribution). That location links to a downloadable installer for GNU Emacs on Windows and to locations from which to download Emacs for Unix platforms.
Once you have Emacs installed on your machine, you need to have it load the Emacs-Lisp interface files when it starts up. You do this by putting the appropriate form in your .emacs file, as described:
That form assumes you installed Allegro CL in the standard location, Replace that with the correct location if it is different.
That form assumes you installed Allegro CL in the standard location, Replace that with the correct location if it is different.
The page at franz.com/emacs/ has additional recommendations for the .emacs file, along with a list of convenient key bindings. The rest of this document is a more complete description of the Emacs-Lisp interface.
ELI was previously incompatible with GNU Emacs on Windows which was compiled and run under Cygwin but was fixed with an update in March, 2006. For information on Cygwin, see www.cygwin.com.
An integral part of the Allegro CL programming environment is the interface between various implementations of Emacs (XEmacs or GNU Emacs) and Allegro CL, hereafter referred to as the Emacs-Lisp interface. This interface allows the editing and running of Common Lisp programs, and contains enhancements that allow a tight coupling between Emacs and Lisp, very similar to those which used to be available only on Lisp machines.
This document provides a technical description of the emacs-lisp interface. See Running Lisp as a subprocess of Emacs in startup.htm for information on starting Allegro CL from emacs. Be sure that the necessary definition files are loaded so that the commands to start Allegro CL (using fi:common-lisp) are defined. See Section 1.6 What should be in your .emacs file in this document.
Note that we do not include function definitions in this document. To
see the documentation for a specific object, do
C-h-f
and specify the function name (including the
fi:
). Similarly for variables, but with
C-h-v
instead of C-h-f
.
Unless otherwise specified, when we say Emacs in this document, we mean XEmacs or GNU Emacs.
We have tried to make the editor seem as if it is implemented in Lisp. However, such an editor would be able to manipulate objects not as text but as first-class Lisp objects and would then be able to know more about programs and be able easily to extract information from them. Emacs with the Emacs-Lisp interface cannot do all that.
Because the Emacs-Lisp interface uses Emacs, which runs as a separate OS process from Lisp, a protocol, called the Lisp-Editor protocol, was designed and implemented to make the communication of information between Emacs and Lisp easier and more natural. A strong requirement of this communication and information exchange is that the user not be aware of it--it must happen in the background. This hidden communication is accomplished by using multiprocessing (commonly called `threads') in Allegro CL and process filters in Emacs. The latter is necessary because Emacs does not have multiprocessing.
The Lisp-Editor protocol is not documented in this release of Allegro CL.
This document is broken into several sections:
In the remainder of this section we discuss a number of topics related to Emacs and the Emacs-Lisp interface. The following headings describe the topics discussed. Each heading appears in large type later in this section, followed by one or more paragraphs describing the topic.
Note particularly Section 1.6 What should be in your .emacs file. To use the Emacs-Lisp interface, you need only ensure that the correct files are loaded into your running Emacs. Section 1.6 What should be in your .emacs file tells you what to put in your .emacs file in your home directory in order to ensure the files are loaded.
The topics are:
If you have never used Emacs before, then you should obtain an Emacs manual. A good one that describes GNU Emacs specifically but is generally applicable to all three supported versions is the GNU Emacs Manual. It is available from the Free Software Foundation (www.gnu.org/software/emacs/.
We assume in this document that you are familiar with Emacs although we do provide occasional hints for beginners.
Emacs has a few different forms of on-line help. Type Control-h (also called C-h for short) three times to find out about the on-line Emacs help facilities. To start the Emacs tutorial, type Control-h t.
The entire Emacs manual is available on-line through the Emacs Info program. Type Control-h i to start up the Info program. To run the Info tutorial, type h after starting the Info program.
See Running Lisp as a subprocess of Emacs in startup.htm for information on starting Allegro CL as a subprocess of Emacs (the recomemnded way to use Allegro CL when developing applications, particularly on UNIX machines).
You cannot run two different Lisp images from the same running Emacs. However, it is possible to run two Emacs's and have each connected to a different Lisp, and you may wish to do this when one Lisp image is performing some general function (such as running a server of some sort) and you wish to do some different work in a separate Lisp. On both Windows and UNIX, this can be done by starting two Emacs's and using fi:common-lisp in each Emacs to start a Lisp.
This also works (try it, particularly on Windows, if using fi:common-lisp in both Emacs processes does not work for any reason).
(new-start-emacs-lisp-interface :port 9999
:announce-to-file "c:/tmp/eli")
.
(fi:start-interface-via-file "localhost" "*common-lisp*"
"c:/tmp/eli")
. Recall that you evaluate a form in the
*scratch* buffer by entering Control-J at the end of the form.
When discussing an editor, one needs to have a clear convention which identifies keyboard keys and combinations of keys. Also, Emacs needs to access certain files whose location depends on how Emacs was installed; we have to refer to these files in an unambiguous fashion even though we cannot know the exact location on your system.
We start with the conventions for files.
load-path
(the value will be one or more
directories).
Now we discuss the conventions for identifying keyboard keys. The important point is that most Emacs commands are effected by entering one or more keystrokes, with each keystroke being a single key or a combination of keys pressed simultaneously. The most common keys used in combination with others are the CONTROL key, the ESCAPE key and the META key. (Most keyboards do not have a key labeled META, so another key is usually designated as the META key. On PC keyboards, for example, the ALT key is used for the META key. On Sun keyboards the LEFT key is used for the META key. Note also that in most cases, pressing the META and another key simultaneously has the same effect as pressing ESCAPE and the other key sequentially. Of the keys mentioned, only ESCAPE is pressed prior to rather than simultaneously with another key.)
Some more points about designating keys. First we say press to mean enter or depress a keyboard key. Second, CONTROL-a and CONTROL-A are the same character; whereas ESCAPE-a and ESCAPE-A are two different characters.
ESC
This symbol stands for the ESCAPE key. It can be used alone or in conjunction with another key. If used in conjunction with another key, the ESCAPE is pressed first and the other key immediately after. ESC-v, therefore, means press ESCAPE and then press v (without pressing SHIFT, note!). Some keyboards do not have a META key. You may type META characters by using two character keystrokes starting with ESCAPE.
M-
This symbol stands for the META key (usually called something else, e.g. ALT on PC keyboards). The META key only has an effect when pressed simultaneously with another key (hence the - following the M). M-a means depress META and press a while META is down. M-Sh-a means depress META and SHIFT, then press a while META and SHIFT are down. Note that M-a and M-Sh-a are two distinct keystrokes. Note too that Emacs online documentation typically says M-A instead of M-Sh-a (that is, the case of the letter is important when M-[letter] appears in Emacs online documentation).
C-
This symbol stands for the CONTROL key. The CONTROL key only has an effect when pressed simultaneously with another key (hence the - following the C). C-a means depress CONTROL and press a while CONTROL is down.
RET
This symbol stands for the RETURN key, also called a carriage return. This key is not ever pressed in conjunction with another. Note that most Emacs commands are effected without a RETURN being necessary.
LF
This symbol stands for the LINE FEED key. This key is not ever pressed in conjunction with another. Note that this key is different from (and has a different effect than) the RETURN key.
DEL
This symbol stands for the DELETE key. This key is not ever pressed in conjunction with another. This key, rather than BACKSPACE deletes the character before the cursor. BACKSPACE (C-h) is the initial default help key and has no effect on typed-in text.
We loosely follow the format of the Emacs manuals in this document. That means that the templates for function and variable definitions are different from those used elsewhere in this manual. Each section starts with descriptive text describing the features of the section. At the end of each section, there is a complete list of the Emacs Lisp commands, functions, user options, and variables that apply to the general discussion in that section. The format of the function and variable descriptions follows the accepted documentation conventions in the GNU Emacs Lisp Reference Manual. Four types of objects are defined: interactive commands, program callable functions, user-settable options and variables. Here is how the definitions for each look.
command-name | [Emacs command] |
Arguments: formal arglist |
nil
,
meaning there is no prefix argument). Each command may use the prefix
argument or ignore it. One way of specifying a prefix argument is to
use the C-u command followed by a numeric argument just before
typing the command.
function-name |
[Emacs function] |
Arguments: formal arglist |
user-option-name |
[Emacs user option] |
Initial value: value |
variable-name |
[Emacs variable] |
Initial value: value |
The Emacs-Lisp interface works with all recent versions of GNU Emacs and XEmacs. Evaluating M-x emacs-version in your Emacs will print the version number. It is possible that the interface will not work with a version that was released after the release of Allegro CL. If that occurs, please contact us for assistance.
You should use the xeli/ directory instead of the eli/ directory. elc (compiled emacs) files are not compatible between the GNU Emacs and XEmacs. The correct compiled files are in the appropriate directory.
The Emacs function fi:verify-emacs-support will determine if your Emacs has the internal code necessary for the Emacs-Lisp interface. Evaluating M-x fi:verify-emacs-support in your Emacs will print:
everything looks fine!
in the minibuffer if it finds the required support. Otherwise an error is signaled specifying the missing feature(s).
The code for the Emacs-Lisp interface needs to be loaded into Emacs when Emacs starts up. There are different directories for GNU Emacs (the eli/ directory) and XEmacs (the xeli/ directory).
The simplest way to ensure that the interface is loaded is to have the proper forms in your $HOME/.emacs file (that is, the .emacs file in your home directory). On Windows, the "HOME" directory (not a defined concept) is c:\, so that is where Emacs will look for a .emacs file. You can use -l <filename> to specify a startup file to load and have that file be the equivalent of .emacs.
The exact forms depend on where Allegro CL was installed on your system.
Assuming that Allegro CL was installed into /usr/local/acl90/ on UNIX machines, here is the correct form to place in .emacs for GNU Emacs users:
(load "/usr/local/acl90/eli/fi-site-init")
Here is the correct form to place in .emacs for XEmacs users:
(load "/usr/local/acl90/xeli/fi-site-init")
In both cases, replace the directory with the correct directory if it is not what is shown.
On Windows machines, the standard location for the Allegro CL directory is c:\acl90\ (there may be additional characters like .64 or .smp or express). Use that or whatever directory was actually used in the .emacs file on Windows machines, again using eli/ or xeli/ as you are using GNU Emacs or XEmacs.
Two manuals available from the Free Software Foundation will help users of Emacs: the GNU Emacs Manual (mentioned above) and the GNU Emacs Lisp Reference Manual. The latter manual describes the version of Lisp used internally by Emacs (called Emacs Lisp, which is not Common Lisp). Both are available from the Free Software Foundation, whose address can be found above in the section Section 1.1 If you are new to Emacs.
All of the documentation available in the Emacs Info program may be printed on hardcopy, including the GNU Emacs Manual. To start the Emacs Info program, type C-h i. For information about printing hardcopy, see the Texinfo section of the Info program. Note that printing the Emacs manual is easiest if you have TeX.
Users of the Emacs-Lisp interface are bound by the GNU Emacs copyright agreement. Note that all of the Emacs code may be redistributed.
Files whose type is `el' may be distributed with GNU Emacs under the terms of the GNU Emacs license agreement. Files without the extension `el' are not covered by the GNU Emacs License agreement and use is restricted according to the Franz Inc. License Agreement.
Below is a brief list of Emacs-Lisp Interface features that have caused users trouble.
Evaluate the following expression while in a Common Lisp buffer:
M-x eval-expression RET fi:package
The string returned should make sense as a package. A legitimate sample return value is "mypackage".
You can limit the interface to the local host by modifying the value
of *eli-daemon-socket-hook*
as shown in the
description of that variable.
There are other security issues. The password chosen to protect the connection is a small number, which can be bruteforced in a few seconds and some LEP variables appear to get overwritten even on error. Please note that the ELI was engineered before threats in common use today existed. We make improvements from time to time but if you have reason to be concerned about security, ELI may not be for you.
You may report bugs and problems with the Emacs-Lisp interface to us, just like Common Lisp bugs. If you report a bug or problem, please be sure to include the version of Lisp that you are running. Bugs in Emacs may also be reported however we are not always able to fix them.
The Emacs/Lisp Interface was significantly changed in release 6.2. There have not been major changes since. In this section, we review the 6.2 changes.
There are five major areas of change, each described in its own section:
There are improved menus for Emacs and XEmacs 21 (and later). Previously in Emacs, Allegro CL-specific menu items were not mode specific. (They were mode-specific in XEmacs.) They are now mode-specific in Emacs. Previously, in both XEmacs and Emacs, there were several Allegro CL-specific menus on the menu-bar. Now, by default, there is a single Allegro CL-specific menu on the menu-bar, with sub-menus. The following variable can be used to retrieve previous functionality:
(defvar fi:menu-bar-single-item t "*If non-nil then put a single item onto the menu-bar. Otherwise, the sub-menus in the single menu are put onto the menu-bar. This variable is ignored in all but XEmacs and Emacs 21 and later.")
Set this variable to nil
in your
.emacs file before loading
"fi-site-init" if you want the previous behavior of multiple
menus on the menu-bar.
For Emacs (and not XEmacs) the following additional changes have been made:
We now offer the option of complying with the major mode conventions outlined in the GNU Emacs Lisp Reference Manual, edition 2.5.
The variable fi:legacy-keybindings
controls whether
you use major mode convention compliant keybindings, or not.
The compliant keybindings will be in
effect when fi:legacy-keybindings
is nil
. Its initial value is t
so that users downloading the patch will see only minimal behavior
change.
(defvar fi:legacy-keybindings t "*If non-nil then define the global, legacy keybindings, which in some cases are in violation of the Elisp major mode conventions outlined in the Emacs Lisp Manual. For compatibility reasons the value of this variable is `t' by default.")
More details on how keybindings relate to this variable are given
below. (fi:legacy-keybindings
subsumes the actions
of fi:define-global-lisp-mode-bindings
.) If you
want to change the value of fi:legacy-keybindings
,
it should be set in your .emacs file before
loading "fi-site-init".
Our goal with the patch was to minimize incompatibilities while offering compliance.
Consider the three different version/states of ELI:
fi:define-global-lisp-mode-bindings
unchanged from
the default value.
fi:legacy-keybindings
unchanged from the default
value (which is t
).
fi:legacy-keybindings
changed to
nil
.
The differences between first two and second two states are outlined under the heading User-visible changes after installing the patch just below and User-visible changes (post patch) with fi:legacy-keybindings set to nil below that.
Here are the changes to keybindings after the patch is
downloaded but fi:legacy-keybindings
has its
initial value t
. NEW
means a new binding, DEL means a removed binding,
FROM/TO denote a changed binding.
fi:common-lisp-mode: NEW C-c C-a fi:lisp-arglist NEW C-c i fi:insert-arglist NEW C-c C-f fi:lisp-function-documentation NEW C-c C-j fi:toggle-to-lisp NEW C-c C-y fi:kill-definition NEW C-c C-z fi:list-who-calls NEW C-c RET fi:lisp-macroexpand NEW C-c ( fi:lisp-macroexpand-recursively NEW C-c * fi:pop-definition-mark fi:inferior-common-lisp-mode: NEW C-a fi:subprocess-beginning-of-line NEW C-c C-f fi:lisp-function-documentation NEW C-c C-j fi:toggle-to-lisp NEW C-c C-z fi:list-who-calls NEW C-c ( fi:lisp-macroexpand-recursively NEW C-c * fi:pop-definition-mark DEL C-c - fi:log-functional-change FROM C-c C-a fi:subprocess-beginning-of-line TO C-c C-a fi:lisp-arglist FROM C-c C-y fi:pop-input TO C-c C-y fi:kill-definition FROM C-c RET fi:subprocess-input-region TO C-c RET fi:lisp-macroexpand
C-a
is added in accordance with the major mode
conventions: it is reasonable for a major mode to rebind a key
sequence with a standard meaning, if it implements a command that does
"the same job" in a way that fits the major mode better. This makes
C-c C-a
obsolete and available for
fi:lisp-arglist
.
fi:pop-input (C-c C-y)
was redundant (same as
C-c C-p
).
fi:subprocess-input-region (C-c RET)
was obscure
and little used, so C-c RET
was used for
fi:lisp-macroexpand
.
fi:lisp-listener-mode: NEW C-a fi:subprocess-beginning-of-line NEW C-c C-f fi:lisp-function-documentation NEW C-c C-j fi:toggle-to-lisp NEW C-c C-z fi:list-who-calls NEW C-c ( fi:lisp-macroexpand-recursively NEW C-c * fi:pop-definition-mark DEL C-c - fi:log-functional-change FROM C-c C-a fi:subprocess-beginning-of-line TO C-c C-a fi:lisp-arglist FROM C-c C-y fi:pop-input TO C-c C-y fi:kill-definition FROM C-c RET fi:subprocess-input-region TO C-c RET fi:lisp-macroexpand fi:emacs-lisp-mode: DEL C-c l fi:toggle-to-lisp fi:rlogin-mode, fi:shell-mode, fi:su-mode, fi:remote-su-mode: NEW C-a fi:subprocess-beginning-of-line NEW C-c C-g fi:telnet-start-garbage-filter NEW DEL backward-delete-char-untabify DEL C-c C-a fi:subprocess-beginning-of-line DEL C-c C-y fi:pop-input fi:telnet-mode: NEW C-a fi:subprocess-beginning-of-line NEW C-c C-g fi:telnet-start-garbage-filter NEW DEL backward-delete-char-untabify DEL C-c C-a fi:subprocess-beginning-of-line DEL C-c C-y fi:pop-input DEL C-c m fi:telnet-start-garbage-filter
The following are new to all Lisp editing modes:
NEW C-c < fi:previous-top-level-form NEW C-c > fi:next-top-level-form
This section details user-visible keybindings changes when the patch
is downloaded and fi:legacy-keybindings
has the
value nil
:
fi:common-lisp-mode: DEL C-c A fi:lisp-arglist DEL C-c C fi:list-who-calls DEL C-c D fi:describe-symbol DEL C-c F fi:lisp-function-documentation DEL C-c M fi:lisp-macroexpand DEL C-c T fi:toggle-trace-definition DEL C-c W fi:lisp-macroexpand-recursively DEL C-c a fi:lisp-arglist DEL C-c c fi:list-who-calls DEL C-c d fi:describe-symbol DEL C-c f fi:lisp-function-documentation DEL C-c k fi:kill-definition DEL C-c l fi:toggle-to-lisp DEL C-c m fi:lisp-macroexpand DEL C-c t fi:toggle-trace-definition DEL C-c w fi:lisp-macroexpand-recursively DEL ESC A fi:lisp-arglist DEL ESC C fi:list-who-calls DEL ESC D fi:describe-symbol DEL ESC F fi:lisp-function-documentation DEL ESC M fi:lisp-macroexpand DEL ESC T fi:toggle-trace-definition DEL ESC W fi:lisp-macroexpand-recursively FROM C-c C-t fi:trace-definer TO C-c C-t fi:toggle-trace-definition
The change of C-c C-t
was deemed necessary since
fi:toggle-trace-definition is more important than
fi:trace-definer.
fi:inferior-common-lisp-mode and fi:lisp-listener-mode: DEL C-c A fi:lisp-arglist DEL C-c C fi:list-who-calls DEL C-c D fi:describe-symbol DEL C-c F fi:lisp-function-documentation DEL C-c M fi:lisp-macroexpand DEL C-c T fi:toggle-trace-definition DEL C-c W fi:lisp-macroexpand-recursively DEL C-c a fi:lisp-arglist DEL C-c c fi:list-who-calls DEL C-c d fi:describe-symbol DEL C-c f fi:lisp-function-documentation DEL C-c k fi:kill-definition DEL C-c l fi:toggle-to-lisp DEL C-c m fi:lisp-macroexpand DEL C-c s fi:scan-stack DEL C-c t fi:toggle-trace-definition DEL C-c w fi:lisp-macroexpand-recursively DEL C-x RET fi:inferior-lisp-input-list DEL ESC A fi:lisp-arglist DEL ESC C fi:list-who-calls DEL ESC D fi:describe-symbol DEL ESC F fi:lisp-function-documentation DEL ESC M fi:lisp-macroexpand DEL ESC RET fi:inferior-lisp-input-sexp DEL ESC T fi:toggle-trace-definition DEL ESC W fi:lisp-macroexpand-recursively FROM C-c C-t fi:trace-definer TO C-c C-t fi:toggle-trace-definition NEW C-c & fi:scan-stack
Other than the rearranged keybindings listed above, the following are completely new key bindings providing new functionality:
fi:common-lisp-mode: C-c * fi:pop-definition-mark C-c < fi:previous-top-level-form C-c > fi:next-top-level-form SPC fi:arglist-lisp-space fi:inferior-common-lisp-mode: C-a fi:subprocess-beginning-of-line C-c * fi:pop-definition-mark SPC fi:arglist-lisp-space fi:lisp-listener-mode: C-a fi:subprocess-beginning-of-line C-c * fi:pop-definition-mark SPC fi:arglist-lisp-space
C-c *
is a convenient way to return to a
previous context after C-c .
.
fi:rlogin-mode, fi:shell-mode, fi:telnet-mode, fi:su-mode, fi:remote-su-mode: C-a fi:subprocess-beginning-of-line C-c C-g fi:telnet-start-garbage-filter
For the shell-related modes, C-c C-g
is a quick way
to get rid of those annoying ^M
's that occur on
some systems.
The default behavior is now to retrieve and display in the minibuffer arglist information, when a connection to Lisp has already been made and the arglist information is available for the symbol before the point at the time SPC is typed. The variable which controls this feature is:
(defvar fi:arglist-on-space t "*If non-nil, then bind SPC to a function that retrieves arglist information and displays it according to the value of the variable fi:auto-arglist-pop-up-style.")
The method by which the arglist is displayed is controlled by this variable:
(defvar fi:auto-arglist-pop-up-style '(minibuffer) "*The value of this variable is used to bind fi:pop-up-temp-window-behavior when (\\[fi:arglist-lisp-space]) is executed. A value of '(split . nil) is handy for insuring that the arglist information stays around long enough to be used.")
In Emacs 21 or later, the default behavior of the minibuffer is to grow dynamically, and this will allow even large arglists to be displayed without having a new buffer pop up. If you want more permanance to the arglist information, while you type in your program, use this in your .emacs:
(setq fi:auto-arglist-pop-up-style '(split . nil))
XEmacs does not have a dynamically resizing minibuffer, so if the
information being displayed is larger than one line, it will be put
into the *CL-Temp*
buffer.
Pop-up buffer handling has been improved. The value of
fi:pop-up-temp-window-behavior
can now be the list
'(minibuffer)
, which allows for the minibuffer to
be used for Lisp-queried information (e.g., arglist, macro
expansions), as well as evaluations of user code.
The documentation for
fi:pop-up-temp-window-behavior
has also been
improved:
(defvar fi:pop-up-temp-window-behavior '(other . t) "*The value of this variable determines the behavior of the popup temporary buffers used to display information which is the result of queries of the Lisp environment. As of version 2.4.0 of the interface, this includes output generated by arbitrary evaluations of user-written Lisp code, when the value of this variable is '(minibuffer). The value is a cons of the form (style . boolean). The possible values for the `style' (or the car of the cons) are the symbols minibuffer, split, other, and replace: - `minibuffer' causes the minibuffer to always be used, regardless of the number of lines of output. Recent versions of Emacs have dynamically resizing minibuffers, and this is useful in combination with these newer versions. - `split' causes the largest window to be split and the new window to be minimal in size. - `other' causes the other window to be used, splitting the screen if there is only one window. - `replace' causes the current window to be replaced with the help buffer. The possible values for the `boolean' (or cdr of the cons) are `t' or `nil'. `t' means use the minibuffer, and if the resulting text does not fit, use a window. `nil' means always use a window. A value of `nil' is handy since messages printed in the minibuffer can easily be erased. If the `style' is `minibuffer', then the `boolean' is ignored, since the minibuffer is always used, regardless of the amount of output.")
Many thanks to Bill Clementson for many of the suggestions and helping with testing.
Starting the Emacs-Lisp interface is actually a misnomer. Assuming the interface code has been loaded into Emacs, it is available whenever Emacs is running. (Below, in Section 3.0 Running Common Lisp, we describe how to start Lisp from within Emacs). Therefore, this section is really about ensuring that the interface is loaded into Emacs.
The simplest way to ensure that the interface is loaded is to have the proper forms in your $HOME/.emacs file (that is, the .emacs file in your home directory). See Section 1.6 What should be in your .emacs file for information on what to put in that file.
With the proper form in the .emacs file, the interface will be loaded when Emacs starts up. Note that in the following sections, we discuss many variables that customize the Emacs-Lisp programming environment. Forms changing the default values of these variables can also be put in the .emacs file, allowing you to customize the environment to your liking. Note that these forms should be placed before (above) the two forms specified above.
While putting the specified load form in $HOME/.emacs (as described in Section 1.6 What should be in your .emacs file) is the recommended method of loading the Emacs-Lisp interface, it is not required. If you are using Emacs and the Emacs-Lisp interface is not loaded, you can load it as follows.
For GNU Emacs users:
M-x load-file RET [Allegro directory]/eli/fi-site-init
For XEmacs users:
M-x load-file RET [Allegro directory]/xeli/fi-site-init
The [Allegro directory] is the directory where Allegro CL is installed.
If M-x fi:common-lisp is used to start a Common Lisp process on a remote machine (i.e. a different machine than the one running Emacs), and Emacs is exited without first exiting from Common Lisp, Common Lisp may continue running on the remote machine. While there seems to be no sure-fire way to prevent this, you can load code into Emacs which prevents you from exiting Emacs while Common Lisp is running. This code is contained in the file misc/dot-emacs (misc/dot-emacs.el on Windows) in the Allegro directory. Make use of this code if you wish by placing it in your .emacs file in your home directory (misc/dot-emacs is a sample .emacs file).
This section gives some hints about what may be wrong if either the Emacs-Lisp interface does not seem to be available at all or does not seem to work as described in this document. The interface is supported by Franz Inc. (although we do not support Emacs itself), so problems with the interface can be reported to us just like bugs or problems with Allegro CL and related products. We do ask, however, that you check out the suggestions here before reporting a problem to us. The following problems are discussed in this section, each under a heading in bold type.
Suppose you try to invoke the command fi:common-lisp (which starts up
Allegro CL within Emacs) and Emacs reports that function is
undefined. A likely cause is that the Emacs-Lisp interface is not
loaded. The variable fi:package-loaded is set to t when the interface
is loaded. Evaluate that variable in a *scratch* buffer (by typing its
name followed by a LINEFEED -- i.e Control-J
).
If the value is nil,
the interface is not loaded. Check your $HOME/.emacs file and make
sure the form that loads "fi-site-init" is in the file. If
the value of the variable is t, there is a more serious problem which
does not have an easily identifiable cause.
The cause of this problem cannot be known in advance. Here we suggest how to further investigate. Exit Emacs and restart it with the -q option (which suppresses the loading of the $HOME/.emacs file). Then type the following in the *scratch* buffer:
(setq debug-on-error t) LF (load "~/.emacs") LF
Note that you press LINEFEED (LF, typically Control-J) rather than RETURN (RET) after typing the forms.
If you run Emacs and Lisp on different machines, then you must be certain that the value of fi:emacs-to-lisp-transaction-directory is a directory which is accessible on both machines. Care must be taken to get the pathname just right, including the possible NFS prefix (/net/MACHINE-NAME/...).
If you are having trouble with the Emacs-Lisp interface, we recommend that you check for trouble involving your personal .emacs and .clinit.cl files.
[shell prompt]%
emacs -q
This will start up Emacs without reading your
.emacs file.
M-x fi:verify-emacs-support
. See
Section 1.5 Previous versions of Emacs for more information about
this command.
The most common cause of other strange or unexplained behavior is using the Emacs-Lisp interface with a version of Emacs other than the one distributed with Allegro CL. The Emacs-Lisp interface is only supported on that specific version. While only the person who installed Allegro CL and Emacs knows for sure, a simple test is to compare the version number specific in the Release Notes with the version number stored in the Emacs image itself, accessed with the function emacs-version. To evaluate this function, enter
M-x emacs-version
to Emacs. This function returns a string specifying the version number. Note that even if that number is the same as that in the Release Notes, it may not be the exact version from the Allegro CL distribution. However, if the numbers are different, it is certainly not the same.
Also note that fi: is not a package prefix (as it would be in Common Lisp). Instead, it is just part of the symbol name so you always must type it. (We use fi: to guarantee that the names of functions defined in our interface do not conflict with other function names.)
Interacting with Common Lisp occurs in an Emacs subprocess buffer. This interaction can even occur between Emacs and Common Lisp processes that reside on different machines. Common Lisp must be started with the function fi:common-lisp or with fi:start-interface-via-file. Although you can (using fi:start-interface-via-file) start Common Lisp in an Emacs shell and then initiate the interface, it is unusual to do so. Note that most of the Emacs-Lisp interface will not work with a Lisp image started in an Emacs shell and not connected to Lisp using fi:start-interface-via-file.
When called for the first time in an emacs session,
fi:common-lisp prompts in the minibuffer for
information on how you wish to invoke Lisp (see section
Section 3.3 Functions and variables for Interacting with a CL subprocess for
details on what questions are asked). Subsequent calls use the
previous answers unless qualified with C-u
. Once it
knows what to invoke, fi:common-lisp makes a Common
Lisp subprocess in a buffer named (in the default)
*common-lisp*
. After start-up,
*common-lisp*
might have contents which look
similar to this:
Allegro CL 7.0 Copyright (C) 1985-2004, Franz Inc., Berkeley, CA, USA ;; Optimization settings: safety 1, space 1, speed 1, ;; debug 2. For a complete description of all compiler ;; switches given the current optimization settings ;; evaluate (EXPLAIN-COMPILER-SETTINGS). ;; Starting socket daemon and emacs-lisp interface... USER(1):
First, what you in fact see will probably be different. In particular everything after `7.0' in the first line will likely be different (the information there specifies the exact version shipped to you); the notice in comments may be changed and anyway, we have changed the linebreaks to prevent wrapping; and the code changes faster than the documentation. However, what you see will be similar.
The user(N): is the Allegro CL prompt. The comment just before the first prompt signifies that an Allegro CL process that communicates with Emacs has started (see multiprocessing.htm for a definition of process). Meanwhile, in the Emacs minibuffer, you should see
Trying to start connection...done.
That message signifies that the hidden, or backdoor, communication between Emacs and Common Lisp has been initiated. Emacs and Common Lisp will be communicating over a network connection.
The Emacs-Lisp interface is currently started with the -e Allegro Common Lisp command line option. This allows the interface to be started for images that do not behave like a standard Common Lisp image (with a read-eval-print loop). For more information, see the description of fi:start-lisp-interface-arguments in Section 3.3 Functions and variables for Interacting with a CL subprocess below.
It is possible for the interface to fail to start up (failure will be indicated by the failure of `Starting socket daemon and emacs-lisp interface...' to appear in the *common-lisp* buffer or the failure of `Trying to start connection...done' to appear in the Emacs minibuffer. You can start the interface (or restart it if it dies) with the Allegro CL function
The emacs function fi:start-interface-via-file allows you to connect Emacs to a running Lisp after Lisp has started. This is typically done for debugging a running but apparently broken process. fi:start-interface-via-file takes arguments host buffer connection-file, specifying the host machine, the emacs buffer name, and the file created by that will be used for the connection. To start the interface using this method, on the lisp side, you would do something like this:
(excl:new-start-emacs-lisp-interface :port 7666 :announce-to-file"~/.eli-startup")
See for a discussion of the arguments. Then, sometime later on the emacs side, do this (the host is "pie"):
(fi:start-interface-via-file "pie" "*common-lisp*" "~/.eli-startup")
Please note that bindings in this mode are changed by a patch made
available in August, 2003. See
Section 1.12 Changes in the interface in Release 6.2 for details. The tables
in this section have been updated and describe the new behavior with
fi:legacy-keybindings
having its initial value
t
(fewest changes) and the value nil
(most changes).
Many of the key bindings in a *common-lisp* buffer behave much like a shell buffer does. The *common-lisp* buffer and a shell buffer have mode specific commands with the key prefix C-c. Both buffers have key bindings that will delete typed input (words or lines), send an EOF or interrupt, or send the input to the Allegro CL process.
The key bindings can be classified into four categories: (1) General subprocess interaction, (2) Editing, (3) Lisp environment queries, and (4) Superkeys (Superkeys are keybindings that have different effects according to whether they are entered at the end of a buffer or elsewhere in the buffer). We describe the key bindings in each category next.
The keys/functions in this category provide the functionality that a shell buffer would have. All the special characters (C-c, C-d, C-w, C-u, etc.) are handled by these functions:
key | binding |
---|---|
C-a | fi:subprocess-beginning-of-line |
C-c C-\ | fi:subprocess-quit |
C-c C-c | fi:interrupt-listener |
C-c C-d | fi:subprocess-send-eof (fi:remote-lisp-send-eof when Lisp is remote) |
C-c C-j | fi:toggle-to-lisp |
C-c C-k | fi:subprocess-kill-output |
C-c C-l | fi:list-input-ring |
C-c C-n | fi:push-input |
C-c C-o | fi:subprocess-send-flush |
C-c C-p | fi:pop-input |
C-c C-r | fi:re-search-backward-input |
C-c C-s | fi:re-search-forward-input |
C-c C-u | fi:subprocess-kill-input |
C-c C-v | fi:subprocess-show-output |
C-c C-w | fi:subprocess-backward-kill-word |
C-c = | fi:lisp-sync-current-working-directory |
C-x RET | fi:inferior-lisp-input-list if
fi:legacy-keybindings is non-nil,
no binding otherwise |
ESC RET | fi:inferior-lisp-input-sexp if
fi:legacy-keybindings is non-nil,
no binding otherwise |
RET | fi:inferior-lisp-newline |
Table 1: General Subprocess Keybindings
The keys/functions in this category provide the functionality to edit and enter expressions that will be processed by Common Lisp:
key | binding |
---|---|
TAB | fi:lisp-indent-line |
DEL | backward-delete-char-untabify |
; | fi:lisp-semicolon (if fi:lisp-do-indentation is non-nil) |
C-c ] | fi:super-paren |
C-c % | fi:extract-list |
C-c ; | fi:comment-region |
C-c ^ | fi:center-defun |
C-c C-e | fi:end-of-defun |
C-c C-q | fi:indent-sexp |
C-c C-y | fi:kill-definition |
ESC C-q | fi:indent-sexp |
Table 2: Editing Keybindings
The keys/functions in this category provide a way to obtain information from the Allegro CL environment. These functions use the hidden communication between Emacs and Lisp to simulate Lisp-machine like behavior:
key | binding |
---|---|
C-c C-a | fi:lisp-arglist |
C-c i | fi:insert-arglist |
C-c C-f | fi:lisp-function-documentation |
C-c TAB | fi:lisp-complete-symbol |
C-c RET | fi:lisp-macroexpand |
C-c C-t | fi:trace-definer if
fi:legacy-keybindings is t , fi:toggle-trace-definition if
fi:legacy-keybindings is nil |
C-c C-y | fi:kill-definition |
C-c C-z | fi:list-who-calls |
C-c ( | fi:lisp-macroexpand-recursively |
C-c * | fi:pop-definition-mark |
C-c . | fi:lisp-find-definition |
C-c 4 . | fi:lisp-find-definition-other-window |
C-c , | fi:lisp-find-next-definition |
C-c ? | fi:lisp-apropos |
C-c SPC | fi:lisp-delete-pop-up-window |
C-c & | fi:scan-stack |
C-c A | fi:lisp-arglist if
fi:legacy-keybindings is non-nil,
no binding otherwise |
C-c C | fi:list-who-calls if
fi:legacy-keybindings is non-nil,
no binding otherwse |
C-c D | fi:describe-symbol if
fi:legacy-keybindings is non-nil,
no binding otherwise |
C-c F | fi:lisp-function-documentation if
fi:legacy-keybindings is non-nil,
no binding otherwise |
C-c K | fi:kill-definition if
fi:legacy-keybindings is non-nil,
no binding otherwise |
C-c L | fi:toggle-to-lisp if
fi:legacy-keybindings is non-nil,
no binding otherwise |
C-c M | fi:lisp-macroexpand if
fi:legacy-keybindings is non-nil,
no binding otherwise |
C-c S | fi:scan-stack if
fi:legacy-keybindings is non-nil,
no binding otherwise |
C-c T | fi:toggle-trace-definition if
fi:legacy-keybindings is non-nil,
no binding otherwise |
C-c W | fi:lisp-macroexpand-recursively if
fi:legacy-keybindings is non-nil,
no binding otherwise |
C-c a | fi:lisp-arglist if
fi:legacy-keybindings is non-nil,
no binding otherwise |
C-c c | fi:list-who-calls if
fi:legacy-keybindings is non-nil,
no binding otherwse |
C-c d | fi:describe-symbol if
fi:legacy-keybindings is non-nil,
no binding otherwise |
C-c f | fi:lisp-function-documentation if
fi:legacy-keybindings is non-nil,
no binding otherwise |
C-c k | fi:kill-definition if
fi:legacy-keybindings is non-nil,
no binding otherwise |
C-c l | fi:toggle-to-lisp if
fi:legacy-keybindings is non-nil,
no binding otherwise |
C-c m | fi:lisp-macroexpand if
fi:legacy-keybindings is non-nil,
no binding otherwise |
C-c s | fi:scan-stack if
fi:legacy-keybindings is non-nil,
no binding otherwise |
C-c t | fi:toggle-trace-definition if
fi:legacy-keybindings is non-nil,
no binding otherwise |
C-c w | fi:lisp-macroexpand-recursively if
fi:legacy-keybindings is non-nil,
no binding otherwise |
Table 3: Lisp Environment Query Keybindings
The functions in this category that read symbols also do dynamic completion of symbols present in the Allegro CL environment. The Emacs-Lisp interface has no static symbols database, so a symbol is available for completion just after it is created. See the description of fi:lisp-complete-symbol in Section 5.1 Finding the definitions of functions below.
Because there is a set of process-related functions that are needed in the *common-lisp* buffer, these key bindings have a special meaning at the end of the buffer. That is, there are certain key sequences which have behavior determined by fi:inferior-common-lisp-mode when typed at the end of the buffer, but have their global meaning when typed anywhere else in the buffer. The key sequences and their meanings are given below, and they are only in effect when fi:subprocess-enable-superkeys is non-nil (before fi:inferior-common-lisp-mode is entered for the first time)
key | binding |
---|---|
C-\ | send "kill -QUIT" (UNIX quit) to Common Lisp |
C-d | send EOF to Common Lisp |
C-o | flush output (from "stty flush") |
C-u | delete the current input (from "stty kill") |
C-w | delete the last word (from "stty werase") |
C-z | suspend job (from "stty susp"), only for shell-related modes |
Table 4: Superkeys
C-w
, C-u
, and
C-o
are chosen because those are the (default) keys
used by stty werase, kill, and flush in Unix.
So, C-d at the end of the *common-lisp* buffer will send Common
Lisp an end of file, and at other places in the buffer will delete the
next character (unless you have rebound C-d to call another
function). See the entry for
fi:superkey-shadow-universal-argument
for ways to
control the universal argument C-u.
The Emacs Lisp function bound to RET is more than just "send the current line to the Common Lisp process". In fact, it sends only entire s-expressions, or forms, to Common Lisp. This allows editing of incomplete, multi-line expressions before Common Lisp sees them.
To accomplish the advanced input features, Emacs needs to know the
form of the Common Lisp prompt. The prompt in Allegro CL is defined by
the value of the variable *prompt*
. This value must be a string
acceptable as the second argument to format. Although the prompt can
be changed at any time, it is typically set in the file
$HOME/.clinit.cl
. But however the prompt is
changed, the Emacs user option
fi:common-lisp-prompt-pattern
must be changed as
well -- so that the default value of *prompt*
(in Common Lisp) and
fi:common-lisp-prompt-pattern
(in Emacs Lisp) are
in agreement.
See the file misc/prompts.cl in the Allegro directory for examples of other prompts. See top-level.htm for information on the prompt itself.
The subprocess input ring helps to minimize typing in many different modes of the Emacs-Lisp interface. The Emacs-Lisp interface shell modes and Common Lisp modes have subprocess input rings. The subprocess input ring is similar to the Emacs kill ring, except each subprocess buffer has a separate subprocess input ring. Previously typed input can be yanked to the prompt at the end of the Common Lisp subprocess buffer. It can then be edited before sending it to Common Lisp. The selection of which input to yank can be the previous, next or selected by regular expression search through the input ring. See the Emacs-Lisp interface commands fi:list-input-ring, fi:pop-input, fi:push-input, fi:re-search-backward-input, and fi:re-search-forward-input.
Top-level commands to change the directory in the Common Lisp process are watched by Emacs, so that the Emacs variable default-directory can be changed when the Common Lisp current working directory is changed. The Common Lisp top-level commands :cd, :pushd, and :popd are tracked, and when typed in the *common-lisp* buffer the new directory is saved in default-directory.
The Common Lisp top-level commands :dirs and :pwd do exactly what their C shell counterparts do: print the directory stack and current working directory.
Another Common Lisp top-level command, :package, is tracked by the Emacs-Lisp
interface. When package changes are done either via the top-level
command :package or the macro
in-package, Emacs tracks the
current package of the *common-lisp*
buffer. The current package is used by many Emacs-Lisp interface
functions that query the Common Lisp environment, such as
fi:lisp-arglist and fi:insert-arglist.
The current package is displayed in the mode-line. So, when
:package foo
is entered in the *common-lisp*
buffer, the
mode-line will be updated to contain the string pkg:foo after
the mode identifier. See
Section 4.2 Packages and readtables for more
information.
Because Allegro CL has multiprocessing (see multiprocessing.htm for more information), multiple threads of control can be created--multiple user interactions, or top-levels, can be created within the same UNIX process. Within one Common Lisp process, any number of lisp listeners, as these top-levels are called, can be created.
The Emacs-Lisp interface has a function for creating a lisp listener onto an existing Common Lisp subprocess: fi:open-lisp-listener. This can be used to debug multiprocessing applications or to execute forms while Common Lisp is doing other processing. See also Section 5.5 Lisp Listeners and multiprocessing.
When an open parenthesis and an operator name is typed, the argument list is displayed is the minibuffer if it is known (see fi:arglist-on-space and fi:auto-arglist-pop-up-style). The argument list is also displayed by fi:lisp-arglist (C-c C-a).
A new command, fi:insert-arglist, was added in a Summer, 2006 update. Its binding is C-c i and when invoked after '(<operator-name> ', it inserts the argument list into the code being written. The user can then edit the insertion with the desired argument values. Here are some examples:
;; In each case, we define a function (except where we use a standard ;; CL function), and the type '(<fun-name> C-c i'. We show ;; what is inserted: cl-user(198): (defun foo (a &key (b 'bee) (c 'cee)) (list a b c1)) foo cl-user(199): (foo a :b b :c c) cl-user(201): (defun foo (a b &rest c) (list a b c)) foo cl-user(202): (foo a b c...) cl-user(202): (defun foo (a &optional b c d) (list a b c d)) foo cl-user(203): (foo a [b] [c] [d]) cl-user(203): (find item sequence :from-end from-end :test test :test-not test-not :start start :end end :key key) ;; Even uncommon constructions are supported. In the following definition, ;; the designator name of the second keyword argument is the symbol C ;; (not the keyword :C) while the argument name is C1. Anyway, C-c i ;; does the right thing: cl-user(203): (defun foo (a &key (b 'bee) ((c c1) 'cee)) (list a b c1)) foo cl-user(204): (foo a :b b 'c c)
The function fi:common-lisp starts Common Lisp from within Emacs.
Below is a fragment of code which can be placed in your .emacs file that defines a function run-common-lisp, which will start up a Lisp with default arguments. run-common-lisp is useful if the user frequently uses the same Lisp.
(setq fi:common-lisp-host "ultra") ;; This function starts up lisp with your defaults. (defun run-common-lisp () (interactive) (fi:common-lisp fi:common-lisp-buffer-name fi:common-lisp-directory fi:common-lisp-image-name fi:common-lisp-image-arguments fi:common-lisp-host fi:common-lisp-image-file)) ;; This function uses specific values rather than variables. ;; Either way works and one may be more suitable for you than ;; another (this example runs a Lisp on Windows from an Emacs ;; running on Windows: ;; Set up a keybinding for `run-common-lisp', two possible ways ;; (keybindings for run-ide are analogous): (progn (setq ctlx-3-map (make-keymap)) (define-key ctl-x-map "3" ctlx-3-map) (define-key ctlx-3-map "l" 'run-common-lisp)) ;; or this: (define-key global-map "\C-xl" 'run-common-lisp) ;; Run cl each time emacs is run: (run-common-lisp)
fi:emacs-lisp-interface-version fi:verify-emacs-support fi:common-lisp fi:open-lisp-listener fi:common-lisp-buffer-name fi:common-lisp-directory fi:common-lisp-image-name fi:common-lisp-image-file fi:common-lisp-image-arguments fi:common-lisp-host fi:common-lisp-prompt-pattern fi:common-lisp-subprocess-timeout fi:common-lisp-subprocess-wait-forever fi:legacy-keybindings fi:define-global-lisp-mode-bindings fi:menu-bar-single-item fi:compile-at-load-time fi:toggle-to-lisp fi:connect-to-windows fi:start-lisp-interface-arguments fi:use-background-streams fi:start-lisp-interface-hook fi:start-interface-via-file fi:reset-lep-connection fi:in-package-regexp fi:default-in-package-regexp fi:inferior-common-lisp-mode fi:inferior-lisp-input-list fi:inferior-lisp-input-sexp fi:inferior-lisp-newline fi:inferior-lisp-send-input fi:lisp-sync-current-working-directory fi:list-input-ring fi:pop-input fi:push-input fi:re-search-backward-input fi:re-search-forward-input fi:remote-lisp-send-eof fi:subprocess-backward-kill-word fi:subprocess-beginning-of-line fi:subprocess-input-region fi:subprocess-interrupt fi:subprocess-kill fi:subprocess-kill-input fi:subprocess-kill-output fi:subprocess-quit fi:subprocess-send-input fi:subprocess-send-eof fi:subprocess-send-flush fi:subprocess-show-output fi:subprocess-suspend fi:lisp-listener-mode fi:interrupt-listener fi:tcp-lisp-listener-kill-process fi:tcp-lisp-listener-send-eof fi:emacs-to-lisp-transaction-directory fi:default-input-ring-max fi:display-buffer-function fi:new-screen-for-common-lisp-buffer fi:eval-in-lisp fi:eval-in-lisp-asynchronous fi:filename-frobber-hook fi:lisp-evalserver-number-reads fi:shell-cd-regexp fi:shell-popd-regexp fi:shell-pushd-regexp fi:subprocess-continuously-show-output-in-visible-buffer fi:subprocess-enable-superkeys fi:user-env-vars fi:subprocess-env-vars fi:subprocess-max-buffer-lines fi:superkey-shadow-universal-argument
This section and its subsections discuss the Emacs mode for editing Common Lisp programs.
Common Lisp editing mode, fi:common-lisp-mode, is automatically entered when a Common Lisp source file is visited. The Emacs Lisp variable fi:common-lisp-file-types specifies the file types of Common Lisp source files. The following sections discuss the various aspects of fi:common-lisp-mode. Please note that bindings in this mode are changed by a patch made available in August, 2003. See Section 1.12 Changes in the interface in Release 6.2 for details.
Indentation of a form can be performed with C-M-q, (Hold the CONTROL and META keys while depressing the q key) when the point is on an opening parenthesis. Indentation of the current line can be performed by typing TAB.
All Common Lisp forms are indented with the generally accepted amount of indentation. At the current time, the user interface to the indentation method specification is not documented. It is, however, available for your perusal in the file fi/indent.el - -there are many examples at the end of this file.
Comments in Common Lisp begin with a semicolon (;). Comments starting
with different numbers of semicolons are indented differently. The
Emacs Lisp variable
fi:lisp-comment-indent-specification
specifies how
the indentation is done.
fi:lisp-comment-indent-specification
is a list,
where the Nth element (counting from 1) specifies how N semicolons
will be indented. That is, the first element specifies how a single
semicolon will be indented. The values in the list are either:
The initial value of fi:lisp-comment-indent-specification is
`(list 40 t nil 0)
which means indent one semicolon to column 40, two semicolons to the column s-expressions would indent to, three semicolons should be left alone, and four semicolons are left justified.
NOTE: if the buffer-local variable comment-column is changed, then the
first element of
fi:lisp-comment-indent-specification
is changed to
contain the value of comment-column.
Additionally, if fi:lisp-electric-semicolon
is
non-nil
, then semicolon placement will happen
automatically when semicolons are inserted into the buffer--no TAB is
required to indent the current line. The value of this variable
defaults to nil
.
Here is an example of each type, using default values:
;;;; Foo the Bar (in-package :foo) (defun bar (thang) ;; BAR the THANG ;;;; WARNING: frobs beware (frob-the-frammis thang) ; out in right margin field ;;; leave me where I lie... ;; but indent by right... )
fi:lisp-comment-indent-specification
The Common Lisp package in which a source file is defined is an important quantity which must be known to Emacs. Readtables, though less essential, are also useful when known to Emacs. Such information is used by Emacs, when communicating with Common Lisp, to insure that the operations performed in the Common Lisp environment are with respect to the correct package and expressions are read with the correct readtable.
There are two methods for telling Emacs about which package to use.
The file mode line can also be used to specify a readtable and the Emacs mode. A file mode line must be the first line of text in the file and has the following form:
; -*- ... -*-
where ... has the following fields:
mode: mode-name: mode-name is the name of the function that will enter the mode for this file. It overrides the mode chosen based on the file name's type (suffix). This is a feature available in standard Emacs. |
package: name: name is the name of the package for the file. For compatibility with Lisp machines, name can be a list--everything but the first element is ignored, which should be the name of the package. This value overrides the package specified by an in-package form (if there is one). |
readtable: name name is the name of the readtable for this buffer. See the description of excl:named-readtable in named-readtable for information on creating and using named readtables. |
Fields in the file mode line are separated by semicolons. The following example illustrates a file mode line: With the in-package and eval-when forms, loading this file into Emacs will result in the correct package and readtable being used by Lisp operations on the file:
;; -*- mode: fi:common-lisp-mode; package: mypack; readtable: myrt -*- (in-package :mypack) (eval-when (compile load ;; see note below eval) (setq *readtable* (named-readtable :myrt))) ; ... [rest of code]
Note: load is not needed in the eval-when form when no extraneous reading will happen when the compiled version of this file is loaded. load must be omitted if the named readtable does not actually exist at runtime (when, for example, you use a special readtable for developing an application but it is not included in the application when it is finished).
The file mode line is parsed by the standard Emacs Lisp function set-auto-mode, which has been modified by this interface to look for the package and readtable fields. If you change the file mode line or in-package form in a buffer, you may execute the Emacs Lisp function fi:parse-mode-line-and-package to re-parse the package. A file mode line, if supplied, overrides the value of an in-package form.
The display mode line is used to display status information about buffers (and it appears, usually in a contrasting color, at the bottom of the buffer). In particular, the package and readtable (if any) are displayed in the display mode line.
If a file contains neither a file mode line nor an in-package form, the following supplies the package:
fi:default-package fi:package fi:readtable
Users of Emacs Lisp mode in standard Emacs will be familiar with the many ways to manipulate Lisp expressions. We mention three additional functions available in fi:common-lisp-mode. A full description of these functions and the keybindings defined for the functions is provided later.
fi:extract-listfi:comment-regionTake the list on which the point resides and move it up one level. That is, delete the enclosing expression. With an optional integer prefix argument n, take the list on which the point resides and move it up n times.
fi:super-parenComment the region between the point and the mark. With a non-nil prefix argument, uncomment the region.
Close the current top-level form by inserting as many parentheses as are necessary.
Please note that bindings in this mode are changed by a patch made
available in August, 2003. See
Section 1.12 Changes in the interface in Release 6.2 for details. The tables
in this section have not yet been updated and describe the pre-patch
behavior. In the lists below, we mark the changed bindings (indicating
whether the change occurs with
fi:legacy-keybindings
set to its initial value t
(the fewest changes) or set to nil (the most changes).
The commands that were discussed that query the Common Lisp environment, in Section 3.1 Key bindings in Common Lisp subprocess mode, also apply to Common Lisp editing mode, with several additional commands:
key | binding | description |
---|---|---|
C-c C-b | fi:lisp-eval-or-compile-current-buffer | evaluate or compile the entire current buffer |
C-c C-r | fi:lisp-eval-or-compile-region | evaluate or compile the region bounded by the point and mark |
C-c C-s | fi:lisp-eval-or-compile-last-sexp | evaluate or compile the last S-expression |
C-c C-x | fi:lisp-eval-or-compile-defun | evaluate or compile the entire current top-level form |
ESC C-x | fi:lisp-eval-or-compile-defun if fi:legacy-keybindings is t, no binding otherwise |
If fi:lisp-evals-always-compile
is
non-nil, then the above group of functions compile without a prefix
argument and evaluate the source without compilation when a prefix
argument is provided.
key | binding | description |
---|---|---|
C-c C-m | fi:lisp-macroexpand | Cause the form at the point to be macroexpanded. |
C-c M | fi:lisp-macroexpand
if fi:legacy-keybindings is t,
no binding otherwise
|
|
C-c m | fi:lisp-macroexpand
if fi:legacy-keybindings is t,
no binding otherwise
|
|
ESC M | fi:lisp-macroexpand
if fi:legacy-keybindings is t,
no binding otherwise
|
|
C-c ( | fi:lisp-macroexpand-recursively | Cause the form at the point to be recursively macroexpanded. If given a prefix argument, the recursive macroexpansion is done as the compiler would. The compiler simulation is approximate only and does not preserve the precise semantics of the form. |
C-c W | fi:lisp-macroexpand-recursively
if fi:legacy-keybindings is t,
no binding otherwise
|
|
C-c w | fi:lisp-macroexpand-recursively
if fi:legacy-keybindings is t,
no binding otherwise
|
|
ESC W | fi:lisp-macroexpand-recursively
if fi:legacy-keybindings is t,
no binding otherwise
|
The following table contains the remainder of the Lisp querying functions.
key(s) | binding | description |
---|---|---|
C-c C-a | fi:lisp-arglist | Show the argument Lisp for the symbol at the point. See fi:arglist-on-space and fi:auto-arglist-pop-up-style. |
C-c i | fi:insert-arglist | insert the argument list template into a function call. |
C-c A | fi:lisp-arglist bound if fi:legacy-keybindings is non-nil |
|
C-c a | ||
ESC A | ||
SPC | fi:arglist-lisp-space no binding if fi:arglist-on-space is nil. |
Cause the arglist to be automatically shown for symbols as you type. |
C-c ? | fi:lisp-apropos | Run apropos in the Lisp on a symbol read from the minibuffer and display the results. |
C-c D | fi:describe-symbol bound if fi:legacy-keybindings is non-nil |
Run describe in the Lisp on a symbol read from the minibuffer and display the results. |
C-c d | ||
ESC D | ||
C-c C-f | fi:lisp-function-documentation | Show the documentation for a symbol read from the minibuffer. |
C-c F | fi:lisp-function-documentation bound if fi:legacy-keybindings is non-nil |
|
C-c f | ||
ESC F | ||
C-c C-z | fi:lisp-who-calls | Show the callers of a function, the symbol for which is read from the minibuffer. |
C-c C | fi:lisp-who-calls bound if fi:legacy-keybindings is non-nil |
|
C-c c | ||
ESC C | ||
C-c C-t | fi:trace-definer if fi:legacy-keybindings is non-nil |
Toggle tracing for the function defined by the top-level form around the cursor position. The form can be a defun, defgeneric, defmethod, define-compiler-macro, or deftype. The defmethod case is most useful, as the function spec for the particular method is extracted from the qualifiers and specializers. If tracing is already turned on, then it will be turned off. With a prefix arg, cause the debugger to be invoked via a call to break when the function is called. |
C-c C-t | fi:toggle-trace-definition if fi:legacy-keybindings is nil |
Toggle tracing of a function, the symbol for which is read from the minibuffer. If tracing is already turned on, then it will be turned off. |
C-c T | fi:toggle-trace-definition bound if fi:legacy-keybindings is non-nil |
|
C-c t | ||
ESC T | ||
C-c TAB
ESC TAB | fi:lisp-complete-symbol | Dynamically comple the symbol at the
point using information in the Lisp environment. This means that you may define a function or variable in
Common Lisp, go into Common Lisp source buffer, and complete the name. Each time completion is done it looks up the possible
completions, dynamically, and does not use a static table.
Abbreviations are also expanded. For example, in the initial `user' package, which inherits symbols from the `common-lisp' package, ``m-p-d-'' will expand to ``most-positive-double-float''. The hyphen (-) is a separator that causes the sub-string before the hyphen to be matched at the beginning of words in target symbols. |
C-c C-y | fi:kill-definition | Insert a form to kill, or un-define, the definition that starts at the point. The un-defining form is inserted after the form to un-define. With prefix argument then actually un-define the form in the Common Lisp environment instead of inserted the un-defining form. |
C-c k | fi:kill-definition
bound if fi:legacy-keybindings is non- nil |
|
C-c . | fi:lisp-find-definition | Find the definition of the symbol at the point using information in the Lisp environment. With prefix argument, find the next occurance of the last definition. The current or other window is used, depending on which key is used. No mark is set in the definition file by this command. |
C-c 4 . | fi:lisp-find-definition-other-window | |
C-c , | fi:lisp-find-next-definition | Continue last definition search, started by fi:lisp-find-definition. |
C-c * | fi:pop-definition-mark | Pop back to where the find definition was last invoked. |
For more information on the group of functions for finding definitions
of objects defined in the Common Lisp environment, see the documents
source-file-recording.htm and
cross-reference.htm for information on this. In
short, you will need to set the Common Lisp special variables *record-source-file-info*
and
*record-xref-info*
to
non-nil
values before loading any files into
Common Lisp.
fi:common-lisp-mode fi:center-defun fi:beginning-of-defun fi:next-top-level-form fi:previous-top-level-form fi:lisp-semicolon fi:comment-region fi:uncomment-region fi:end-of-defun fi:extract-list fi:indent-sexp fi:lisp-apropos fi:lisp-arglist fi:insert-arglist fi:arglist-lisp-space fi:arglist-on-space fi:auto-arglist-pop-up-style fi:lisp-complete-symbol fi:describe-symbol fi:lisp-evals-always-compile fi:lisp-eval-current-buffer fi:lisp-eval-or-compile-current-buffer fi:lisp-eval-defun fi:lisp-compile-current-buffer fi:lisp-compile-defun fi:lisp-eval-or-compile-defun fi:lisp-eval-last-sexp fi:lisp-compile-last-sexp fi:lisp-eval-or-compile-last-sexp fi:lisp-eval-region fi:lisp-compile-region fi:lisp-eval-or-compile-region fi:lisp-find-definition fi:lisp-find-definition-other-window fi:lisp-find-next-definition fi:pop-definition-mark fi:lisp-function-documentation fi:lisp-indent-line fi:lisp-macroexpand fi:lisp-macroexpand-recursively fi:lisp-mode-auto-indent fi:lisp-mode-newline fi:log-functional-change fi:super-paren fi:trace-definition fi:toggle-trace-definition fi:trace-definer
fi:definition-mode fi:inverse-definition-mode fi:maintain-definition-stack fi:compare-source-files fi:list-buffer-definitions fi:list-undefined-functions fi:list-unused-functions fi:definition-mode-goto-definition fi:definition-mode-goto-next fi:definition-mode-goto-previous fi:definition-mode-quit fi:definition-mode-undo fi:definition-mode-toggle-trace fi:inverse-definition-mode-quit fi:inverse-definition-who-calls
The Emacs-Lisp interface is a rich programming environment for the construction and debugging of Common Lisp programs. The debugging aids are classified into several categories. In Emacs:
In addition to the interface from Emacs to debugging programs, Allegro CL provides a rich set of tools to debug programs (see debugging.htm). Functions in Allegro CL which are implemented with the help of the Emacs-Lisp interface are the top-level command :edit and the function common-lisp:ed - both allow the source code for a particular function to be edited. The editing operation is initiated from Emacs, but the action is performed by Allegro CL. :edit edits the function associated with the current stack frame and common-lisp:ed allow the editing of arbitrary functions or functions associated with symbols or function specs. For example, a call to lisp:ed returns a value immediately
USER(1): (ed 'frob) <mp:process Metdot Session 0 @ #x90e7a6> USER(2):
but causes a buffer to be created and made visible in Emacs displaying the definition of frob.
See:
fi:auto-fill fi:check-unbalanced-parentheses-when-saving fi:common-lisp-file-types fi:compile-file fi:echo-evals-from-buffer-in-listener-p fi:fill-paragraph fi:find-tag-lock fi:find-unbalanced-parenthesis fi:indent-code-rigidly fi:indent-methods-case-sensitive fi:lisp-package fi:kill-definition fi:lisp-do-indentation fi:lisp-electric-semicolon fi:load-file fi:parse-mode-line-and-package fi:pop-to-sublisp-buffer-after-lisp-eval
An important programming aid is being able to easily locate the source for functions. Sometimes the name of a function is not entirely known, so substrings or regular expressions need to be used to locate possible definitions.
Additionally, Emacs provides a tags facility, which does precisely what is described above, except it uses a static database created by the program etags. This is, obviously, of limited value since as the database becomes out of date the ability to find definitions diminishes.
The approach taken in this interface is to use the information present in the Common Lisp environment, and, if that lookup fails, to use the Emacs tags mechanism.
The information that is saved in the Common Lisp environment when
files are loaded into Common Lisp uses the Source-file recording
facility of Allegro CL, which is described in
source-file-recording.htm. Source-file information
will be recorded and loaded if the values of the Common Lisp variables
*record-source-file-info*
and
*load-source-file-info*
are non-nil.
During the course of debugging or programming, it is useful to have access to the wealth of information present in the Common Lisp environment. The arglist of a function, for example, is useful when composing a call to a particular function, but only if it is inexpensive to look it up.
The following functions are specifically available in Common Lisp editing mode because they are bound to a key sequence:
key action --- ------- C-c ? LISP:APROPOS on a string or regular expression C-c a print the arglist of a function C-c c list the who calls a function C-c d LISP:DESCRIBE a symbol C-c f print the function documentation of a symbol C-c m macroexpand the form at the point C-c w recursively macroexpand the form at the point C-c TAB present completions of a partially named symbol C-c . find the source for a function C-c 4 . find the source for a function, in the other window C-c , find the next definition, when there is more than one C-c * pop back to the window context of the previous match
Table of Bindings for Retrieving information from the Common Lisp environment
in addition to the above functions bound to key sequences, the following functions are available as extended commands:
fi:edit-who-calls Edit all the callers of a function. fi:list-who-is-called-by fi:edit-who-is-called-by List or edit all the functions that are called by a function. fi:list-generic-function-methods fi:edit-generic-function-methods List or edit all the methods of a generic function. fi:describe-class fi:describe-function Describe a named class or function. fi:list-undefined-functions List the functions which are called but not defined.
`List' means to display the names in definition mode, which allows for
easily finding the source associated with a definition. See the
description of fi:definition-mode `Edit' means to find the source
associated with a definition, making the additional definitions
available via C-c ,
.
Many of the above commands create a buffer named *CL-temp* to display the information they retrieve from the Lisp environment. After viewing the contents of this buffer, you may restore the arrangement of windows, as they were before the *CL-temp* buffer was made visible, by invoking the function fi:lisp-delete-pop-up-window. The keybinding C-c SPC will run this function.
fi:lisp-delete-pop-up-window fi:pop-up-temp-window-behavior fi:list-who-calls fi:list-who-is-called-by fi:edit-who-calls fi:edit-who-is-called-by fi:list-generic-function-methods fi:edit-generic-function-methods fi:describe-class fi:describe-function
The following Emacs functions allow interaction with the various components of Allegro Composer. To use them, Allegro Composer must be running. Note that these Emacs functions are formally defined later.
fi:inspect-class fi:inspect-function fi:inspect-value
Inspect a named class, function or arbitrary value. These functions work in conjunction with Allegro Composer to create an inspector window containing the indicated object.
fi:show-calls-to fi:show-calls-from
Show graphs of calls to/from a specific function. The Allegro Grapher is used to display a graph with the indicated information.
fi:show-subclasses fi:show-superclasses
Show graphs of the subclasses/superclasses of a class. The Allegro Grapher is used to display a graph with the indicated information.
fi:inspect-class fi:inspect-function fi:inspect-value fi:show-calls-to fi:show-calls-from fi:show-subclasses fi:show-superclasses
In the course of programming it is often necessary to make changes in the Common Lisp environment. Being able to do this without having to actually type commands to a Common Lisp prompt can be valuable, especially when there would be a good deal of typing involved.
The following functions are specifically available in Common Lisp editing mode because they are bound to a key sequence:
key action --- ------- C-c C-r evaluate the region C-c C-s evaluate the last s-expression C-c C-b evaluate the entire current buffer ESC C-x evaluate the current top-level form ESC T toggle tracing a function, optionally break on entry
Table of Bindings to modify the Common Lisp environment
Additionally, the above commands to evaluation will compile the expressions sent to Common Lisp if a prefix argument is given to the command.
The commands to evaluate portions of Emacs buffers are useful, but require the programmer to indicate which portions of the buffer are evaluated. Sometimes the act of making changes to source code is deeper than just fixing one or two functions. The following functions, available as extended commands (M-x) help ease the demand on remembering what changes have been made or having to recompile more than is necessary, which can be time consuming in a large system:
fi:list-buffer-changed-definitions fi:list-changed-definitions
List the definitions that have been added, deleted or modified in the current buffer or in all buffers visiting Common Lisp source code (in mode fi:common-lisp-mode). Listing the definitions creates a buffer showing one-line descriptions of the definitions, in fi:definition-mode. Each line contains a `name' and `type'. The current list of types are:
:operator |
for functions, methods, generic functions and macros |
:type |
for classes (types) |
:setf-method |
for setf methods |
:variable |
for constants and variables |
fi:eval-buffer-changed-definitions fi:eval-changed-definitions fi:compile-buffer-changed-definitions fi:compile-changed-definitions
Evaluate each of the definitions that have been added or modified in the current buffer or in all buffers visiting Common Lisp source code. C-c , finds subsequent definitions, if there is more than one. This synchronizes the definitions of the currently in-core versions of files being edited by Emacs with Common Lisp. The last two functions compile the changed definitions in the Common Lisp environment, whereas the first two load the interpreted versions of the changed definitions.
fi:copy-buffer-changed-definitions fi:copy-changed-definitions
Copy into the kill ring the definitions that have been added or modified in the current buffer or in all buffers visiting Common Lisp source code.
All the above functions take a prefix argument, since, which defaults to the value of the variable fi:change-definitions-since-default. The value of since causes the above functions to operate on the changes:
thus allowing fine control over which types of changed definitions are used listed, evaluated, compiled or yanked.
Useful in comparing two files of similar origin is fi:compare-source-files, which lists the definitions that have been added, deleted or modified between the two file name arguments read from the minibuffer, if called interactively.
Lastly, it is sometimes useful to remove or kill definitions in the Common Lisp environment. fi:kill-definition inserts after the defining form at the point a form which, when evaluated, will kill the definition. With a prefix argument, fi:kill-definition will, instead of inserting the killing form, evaluate the kill definition form in the Common Lisp environment.
Here is the definition of fi:change-definitions-since-default:
fi:change-definitions-since-default
All of these functions act on definitions which have changed since:
The since prefix argument controls the behavior. You can specify it
explicitly (by C-u since M-x [function of
interest] where since is 1, 2, or
3), or accept the default, which is controlled by the variable
fi:change-definitions-since-default
defined
above. Its initial value is last-compile-or-eval
,
which is equivalent to since = 1.
(fi:list-buffer-changed-definitions SINCE) List the definitions in the current buffer which have been added, deleted or changed. See the documentation for the variable fi:change-definitions-since-default for information on the behavior of SINCE. (fi:eval-buffer-changed-definitions SINCE) Eval the definitions in the current buffer which have been added or changed. See the documentation for the variable fi:change-definitions-since-default for information on the behavior of SINCE. (fi:eval-changed-definitions SINCE) Eval the definitions in all buffers which have been added or changed. See the documentation for the variable fi:change-definitions-since-default for information on the behavior of SINCE. (fi:compile-buffer-changed-definitions SINCE) Compile the definitions in the current buffer which have been added or changed. See the documentation for the variable fi:change-definitions-since-default for information on the behavior of SINCE. (fi:compile-changed-definitions SINCE) Compile the definitions in all buffers which have been added or changed. See the documentation for the variable fi:change-definitions-since-default for information on the behavior of SINCE. (fi:copy-buffer-changed-definitions SINCE) Copy into the kill ring the definitions in the current buffer which have been added or changed. See the documentation for the variable fi:change-definitions-since-default for information on the behavior of SINCE. (fi:copy-changed-definitions SINCE) Copy into the kill ring the definitions in all buffers which have been added or changed. See the documentation for the variable fi:change-definitions-since-default for information on the behavior of SINCE.
Without a window debugger, which presents a graphical view of the runtime stack, programmers debugging Common Lisp programs must resort to examining the stack with the debugger commands described in debugging.htm. It is often the case, however, that much moving up and down the stack must be done to find the proper point of error. Scan stack mode allows a snapshot of the Common Lisp runtime stack to be taken, and for navigation through the stack to proceed in a Emacs buffer with a host of local commands to make this a painless experience.
Consider the following example, typed in the *common-lisp* buffer created by fi:common-lisp:
user(1): (defun foo (x) (bar x)) foo user(2): (defun bar (x) (1+ x)) bar user(3): (foo `foo) Error: foo is an illegal argument to + [1] user(4):
At this point, the problem can be debugged using :zoom, the offended function identified and fixed. A :zoom would look like:
[1] user(4): :zoom Evaluation stack: ->(error "~s is an illegal argument to +" foo) (excl::+_2op foo 1) (1+ foo) (bar foo) (foo foo) ... more older frames ... [1] user(5):
It is now desirable to move the current frame pointer down the stack to find the problem. The inconvenience here is that much output is generated moving around in the stack to find the frame which contains the useful information.
Scan stack mode makes the perusal of the stack much easier. At the point of error, if C-c s is typed, then the following question is asked, in the minibuffer:
Process to debug: Initial Lisp Listener
where the Initial Lisp Listener is the default input to the query. Unless a multiprocessing application is being run, then most errors occur in the initial process created when Common Lisp is run, which is called the Initial Lisp Listener. Typing RET to this query will cause a debugger buffer to be created and displayed. The buffer will be named *debugger:XXX where XXX is the pretty form of the process name of the Allegro Common Lisp process which is being debugged. For the example above, it will have the following contents:
Debugger commands: C-cC-c :continue C-cC-p :pop C-cC-r :reset . make frame under the point the current frame D disassemble the function R restart function (give prefix to specify different form) a toggle visibility of all frames (by default a subset are visible) d next line e edit source corresponding to function g revert stack from Lisp h Causes this help text to become visible l display the lexical variables p pretty print q switch back to "*common-lisp*" buffer r return a value u previous line Type SPACE to hide this help summary. Evaluation stack: ->(error "~s is an illegal argument to +" foo) (excl::+_2op foo 1) (1+ foo) (bar foo) (foo foo) (eval (foo 'foo)) (apply #<Function top-level-read-eval-print-loop @ #x4854ce> nil) (excl::start-reborn-lisp)
where the first section of the buffer is help text, which can be made to disappear by typing SPC. The commands in this mode can be grouped according to functionality:
|
|
|
|
|
|
|
fi:scan-stack fi:scan-stack-mode fi:scan-stack-mode-display-help fi:ss-continue fi:ss-disassemble fi:ss-edit fi:ss-hide-help-text fi:ss-locals fi:ss-next-frame fi:ss-pop fi:ss-pprint fi:ss-previous-frame fi:ss-quit fi:ss-reset fi:ss-restart fi:ss-return fi:ss-revert-stack fi:ss-set-current fi:ss-toggle-all fi:ss-unhide-help-text
gdb is a source level debugger provided by the Free Software Foundation. Its functionality is broadly similar to adb and dbx. You can call gdb on a Lisp image with the following command.
fi:gdb
During the course of debugging multi-process applications, it is often useful to be able to type to an additional listener in the same Common Lisp. That is, within one UNIX Common Lisp process it is possible to run multiple threads, each executing different processes in the Common Lisp address space. The function fi:open-lisp-listener will open a Lisp listener on an existing Common Lisp process started with fi:common-lisp.
The following Allegro CL debugging commands are also useful in debugging multi-process applications:
The scan stack mode above is also useful for multi-process applications, however a process must be `quiescent' for fi:scan-stack-mode to be used on it. `quiescent' means the process must have called error or break and be in a read-eval-print loop waiting for debugging commands. The above process related top-level commands, however, can be used to stop running processes for examination.
This section lists the miscellaneous programming and debugging aids which do not fit into the above sections:
Finally, we end our discussion on debugging by mentioning a function,
fi:bug-report
,
which will allow Franz Inc. to be sent a bug report with all the right
information:
fi:bug-report
The Emacs-Lisp interface defines many useful functions to interact with various types of shells. Below is a description of the functions and variables associated with various shell modes.
The main differences between the standard Emacs shell mode and the Franz Emacs-Lisp interface are described below:
fi:subprocess-enable-superkeys
. fi:superkey-shadow-universal-argument
controls how C-u behaves.
fi:su-initial-input
,
fi:telnet-initial-input
and
fi:rlogin-initial-input
.
fi:shell fi:shell-command-completion fi:shell-do-completion fi:shell-file-name-completion fi:shell-image-arguments fi:shell-image-name fi:shell-mode fi:shell-mode-bang fi:shell-mode-use-history fi:shell-prompt-pattern fi:shell-sync-current-working-directory fi:shell-token-pattern
fi:su fi:su-initial-input fi:su-mode fi:su-prompt-pattern fi:remote-root-login fi:remote-su-mode
fi:telnet fi:telnet-mode fi:telnet-image-arguments fi:telnet-image-name fi:telnet-initial-input fi:telnet-prompt-pattern fi:telnet-start-garbage-filter
fi:rlogin fi:rlogin-new-user fi:rlogin-mode fi:rlogin-image-arguments fi:rlogin-image-name fi:rlogin-initial-input fi:rlogin-prompt-pattern fi:rlogin-send-eof fi:rlogin-send-interrupt fi:rlogin-send-quit fi:rlogin-send-stop
This section and its subsections discuss advanced features of the Emacs-Lisp interface.
fi:define-emacs-lisp-mode fi:emacs-lisp-mode
Some functions in Emacs will call one or more hook functions. A hook is a user settable variable whose value is a hook function. Hooks allow the user to customize features of emacs. Hooks are usually set in the .emacs file, but may be changed by other emacs functions. Many of the mode functions in the Emacs-Lisp Interface run one or more hooks. The hooks and the order they are called are listed in the table below. Note that the documentation for each mode function also lists the hook called (if any). For more information about hooks, please see the FSF Emacs and Emacs Lisp documentation.
Function Called Hooks run (in order) fi:inferior-common-lisp-mode fi:lisp-mode-hook fi:subprocess-mode-hook fi:inferior-common-lisp-mode-hook fi:lisp-listener-mode fi:lisp-mode-hook fi:subprocess-mode-hook fi:lisp-listener-mode-hook fi:common-lisp-mode fi:lisp-mode-hook fi:common-lisp-mode-hook fi:definition-mode fi:definition-mode-hook fi:inverse-definition-mode fi:inverse-definition-mode-hook fi:scan-stack-mode fi:scan-stack-mode-hook fi:shell-mode fi:subprocess-mode-hook fi:shell-mode-hook fi:su-mode fi:subprocess-mode-hook fi:su-mode-hook fi:remote-su-mode fi:subprocess-mode-hook fi:rlogin-mode-hook fi:telnet-mode fi:subprocess-mode-hook fi:telnet-mode-hook fi:rlogin-mode fi:subprocess-mode-hook fi:rlogin-mode-hook
Hooks are commonly used to customize the key-map of a particular mode. The Emacs code fragment below would cause the C-i keystroke to invoke the function fi:shell-do-completion. Note that C-i is also the TAB key.
(setq fi:subprocess-mode-hook '(lambda () (interactive) (define-key (current-local-map) "\C-i" 'fi:shell-do-completion)))
Just about everything we have said so far in this document about the Emacs-Lisp interface has assumed that the Lisp image was created with build-lisp-image in a relatively standard fashion.
Problems starting the Emacs-Lisp interface can arise, however, when starting images created with dumplisp called with a non-nil value specified for the :ignore-command-line-arguments keyword argument.
This will cause problems because of how the Emacs-Lisp interface is started, as we describe next.
As we said in section 3 (and elsewhere), the Emacs-Lisp interface is started by invoking within Emacs the function fi:common-lisp. That function either asks you for command line arguments for Lisp or (typically after the first invocation within an Emacs session) simply takes the value of the Emacs Lisp variable fi:start-lisp-interface-arguments. Here is what happens then:
Because information is passed between Lisp and Emacs in this special way, the connection between Emacs and Lisp can only be established by running Common Lisp with fi:common-lisp. Prior to starting the connection between Lisp and Emacs, Emacs can only communicate to Lisp via the command line. Therefore, the Lisp side of the connection is started using the command line. The problem with images that ignore command-line arguments should be apparent.
If, because command-line arguments are ignored, the Emacs-Lisp interface does not start up (or if it does not start up for any other reason), you can start it directly from within Lisp by calling excl:new-start-emacs-lisp-interface. We remind you again that the image must have been started with fi:common-lisp for this to work.
Copyright (c) 1998-2019, Franz Inc. Oakland, CA., USA. All rights reserved.
This page has had minimal revisions compared to the 8.2 page.
Created 2019.8.20.
| Allegro CL version 9.0 Minimally revised from 8.2. 8.2 version |