1. Introduction to the Emacs-Lisp interface
2. Starting the Emacs-Lisp interface
3.1. Key bindings in Common Lisp subprocess mode
3.2. Typing input to Common Lisp
3.3. Functions and variables for Interacting with a CL subprocess
4. Editing Common Lisp Programs
4.1. Indentation
4.2. Packages and readtables
4.3. Syntactic modification of Common Lisp source code
4.4. Information sharing between Common Lisp and Emacs
4.5. common-lisp-mode functions and variables
4.6. definition-mode functions and variables
5. Writing and Debugging Common Lisp Programs
5.1. Finding the definitions of functions
5.2. Interaction with Allegro Composer
5.3. Modifying the state of the Common Lisp environment
5.4. Debugging Common Lisp processing in Emacs
5.5. Lisp Listeners
5.6. Miscellaneous programming aids
5.7. Bug reports
7. Advanced miscellaneous features
7.1. Emacs hooks
7.2. The Emacs-Lisp interface and excl:dumplisp
7.3. Raw mode
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.
Unless otherwise specified, when we say Emacs in this document, we mean Xemacs or GNU Emacs. Versions of Xemacs and GNU Emacs are distributed with Allegro CL.
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 UNIX 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. We expect that it will be documented in the future, after we have had more experience with the fundamentally new design.
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. 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. Their address is:
Free Software Foundation, Inc.
675 Massachusetts Avenue
Cambridge, MA 02139, USA
+1 617-876-3296
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. All of the documentation available in the Info program may be printed on hardcopy, see the Texinfo section of Info. Note that printing the Emacs manual is easiest if you have TeX.
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.
$HOME
This refers to the value of the $HOME shell environment variable in the shell where Emacs is running. The value of this variable is typically the home directory of the user running Emacs.
$HOME/.emacs
This file is an initialization file which is read by Emacs when it starts up. Forms in this file customize Emacs to the user's specifications. The Emacs-Lisp interface described in this document is typically loaded by forms put in this file.
fi/xxx
Files in the fi directory implement the Emacs-Lisp interface. This directory must be accessible while Emacs is running. When the interface is installed, the fi directory is placed in a directory associated with Emacs. To find the exact path of this directory, within Emacs evaluate the variable load-path (the value will be one or more directories). If installed correctly, the fi directory will be a subdirectory of the first directory which ends in .../lisp/. If the fi directory is not a subdirectory of the first .../lisp/ directory then certain features, such as the on-line manual may not work. This pathname can be used to find the file xxx in the .../lisp/fi directory.
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 Sun keyboards, for example, the LEFT key is used for the META key. Note also that in most cases, pressing LEFT 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 (as you have noticed) 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. LEFT on Sun 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 | |
| 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 has been tested and does work with the following versions of Emacs. No changes to these versions is required. Note that in each case, we list the range of versions with which the interface is known to work. The interface will not work and is not supported with earlier versions. In each case, the interface was tested with the latest version available. 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 with after this manual was printed. If that occurs, please contact us for assistance.
| Emacs Type | Range of Supported Versions |
|---|---|
| GNU Emacs | 19.34, 20.2 |
| Xemacs | 19.16, 20.3 (with and without Mule support) |
Table 1: Supported versions of Emacs
GNU Emacs 20.2 is supported with the following caveat: eli works, but a bug in the handling of `load-file-name' prevents loading the interface the normal way, by just loading "fi-site-init.el". You must put the directory which contains fi-site-init.el in your `load-path'. See examples/emacs.el for an example of how to do this. The bug should be fixed in GNU Emacs 20.3, when it comes out.
You must recompile the .el files because of incompatibilities between GNU Emacs and XEmacs. You can do this by:
% cd <Allegro directory>/eli % make clean % make emacs=xemacs xemacs=xemacs
You will need GNU Make to execute the above command, and you should substitute the real name of your XEmacs for xemacs.
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).
Previous versions of the Emacs-Lisp interface have been distributed with Allegro CL and also via anonymous FTP. The version at the time this document was written was 2.0.21 and this document describes this version only. Versions before 2.0 contain substantially less functionality.
Versions of this interface prior to 2.0 worked (for the most part, at least) on a variety of implementations of Common Lisp. This latest version is much more specific to Allegro CL and uses internal features of Allegro CL which are not available in other Lisp implementations. Therefore, many features in version 2.0 and later of the Emacs-Lisp interface will not work on implementations other than Allegro Common Lisp. The Emacs variable fi:emacs-lisp-interface-version contains the version information.
The code for the Emacs-Lisp interface needs to be loaded into Emacs when Emacs starts up. 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). The exact forms depend on where Allegro CL was installed on your system (since starting with Allegro CL 4.3, the Emacs-Lisp interface code is not merged into the standard Emacs library). Assuming that Allegro CL was installed into /usr/acl50. Here is the correct form to place in .emacs:
(load "/usr/acl50/eli/fi-site-init")
Note: replace /usr/acl50 with the correct directory if that is not where Allegro CL was installed. (/usr/acl50 is the suggested directory in the Installation Guide but any directory may have been used. Your system administrator -- or whoever installed Allegro CL -- should be able to provide this information.)
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 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. However, the text of the on-line Common Lisp Manual pages are Copyright (C) Franz Inc.
This Copyright message applies to the clman pages:
All files are Copyright (C) 1988-1998 by Franz Inc. Users may copy these files to computers for their own use. These files may not be distributed in printed form without the express prior written approval of Franz Inc. These files may not be included as part of any other software package without the express prior written approval of Franz Inc. All other rights reserved.
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 copyright notice above.
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".
Changes from version 2.0.21.16 (shipped with Allegro CL 4.3.2 on Windows 95/NT) to 2.0.21.16.15:
Changes from version 2.0.20 (shipped with Allegro CL 4.3.2 on Windows 95/NT) to 2.0.21.16:
Changes from version 2.0.19 (shipped with Allegro CL 4.3 and 4.3.1) to 2.0.20 (shipped with Allegro CL 4.3.2), all to support using eli on Windows:
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.
`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 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). The exact forms depend on where Allegro CL was installed on your system (since starting with Allegro CL 4.3, the Emacs-Lisp interface code is not merged into the standard Emacs library). Assuming that Allegro CL was installed into /usr/acl50. Here is the correct form to place in .emacs:
(load "/usr/acl50/eli/fi-site-init")
Note: replace /usr/acl50 with the correct directory if that is not where Allegro CL was installed. (/usr/acl50 is the suggested directory in the Installation Guide but any directory may have been used. Your system administrator -- or whoever installed Allegro CL -- should be able to provide this information.
These forms cause the interface to 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 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.
M-x load-file RET /usr/acl50/eli/fi-site-init
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 home/misc/dot-emacs. The home/ directory is read off the distribution tape (and it typically the Lisp library directory). Make use of this code if you wish by placing it in your .emacs file in your home directory (home/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). 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 files needed by the Emacs-Lisp interface reside in the fi subdirectory of one of the Emacs Lisp library directories. If you evaluate the Emacs variable load-path, a list of directories will be printed. The fi directory should be a subdirectory of the first directory in the list whose last element is /lisp/. Check to see if that directory does have an fi subdirectory. If it does not, the Emacs-Lisp interface was not installed correctly. See the Installation Guide for information on how to install the interface. If the fi subdirectory is there, perhaps it is not accessible on the machine where Emacs is running (usually because of a problem with NFS).
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) 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.
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. You cannot start Common Lisp in an Emacs shell and then initiate the interface. Most of the Emacs-Lisp interface will not work with a Lisp image started in an Emacs shell.
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 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 5.0 [SPARC; R1] (7/15/98 00:00) Copyright (C) 1985-1998, 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 `5.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 an 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 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 is dies) with the Allegro CL function excl:start-emacs-lisp-interface.
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 |
|---|---|
| RET | fi:inferior-lisp-newline |
| C-c C-\ | fi:subprocess-quit |
| C-c C-d | fi:subprocess-send-eof (fi:remote-lisp-send-eof when Lisp is remote) |
| C-c C-c | fi:subprocess-interrupt |
| C-c = | fi:lisp-sync-current-working-directory |
| C-c C-w | fi:subprocess-backward-kill-word |
| C-c C-v | fi:subprocess-show-output |
| C-c C-u | fi:subprocess-kill-input |
| C-c C-o | fi:subprocess-send-flush |
| C-c RET | fi:subprocess-input-region |
| C-c C-k | fi:subprocess-kill-output |
| C-c C-a | fi:subprocess-beginning-of-line |
Table 2: 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 |
|---|---|
| DEL | backward-delete-char-untabify |
| TAB | fi:lisp-indent-line |
| C-c ] | fi:super-paren |
| C-c C-e | fi:end-of-defun |
| C-c ; | fi:comment-region |
| C-c ^ | fi:center-defun |
| C-c % | fi:extract-list |
| C-c C-y | fi:pop-input |
| C-c C-s | fi:re-search-forward-input |
| C-c C-r | fi:re-search-backward-input |
| C-c C-p | fi:pop-input |
| C-c C-n | fi:push-input |
| C-c C-l | fi:list-input-ring |
| C-x RET | fi:inferior-lisp-input-list |
| ESC C-q | fi:indent-sexp |
| ESC RET | fi:inferior-lisp-input-sexp |
Table 3: 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 ? | fi:lisp-apropos |
| C-c s | fi:scan-stack |
| C-c . | fi:lisp-find-definition |
| C-c 4 . | fi:lisp-find-definition-other-window |
| C-c , | fi:lisp-find-next-definition |
| C-c SPC | fi:lisp-delete-pop-up-window |
| C-c w | fi:lisp-macroexpand-recursively |
| C-c t | fi:toggle-trace-definition |
| C-c m | fi:lisp-macroexpand |
| C-c f | fi:lisp-function-documentation |
| C-c d | fi:describe-symbol |
| C-c c | fi:list-who-calls |
| C-c a | fi:lisp-arglist |
| C-c TAB | fi:lisp-complete-symbol |
Table 4: 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 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-w | delete the last word (from "stty werase") |
| C-u | delete the current input (from "stty kill") |
| C-o | flush output (from "stty flush") |
| C-d | send EOF to Common Lisp |
| C-a | goto the beginning of the line, ignore the Common Lisp prompt |
Table 5: Superkeys
C-v, 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 top-level:*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 top-level:*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.
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 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.
| fi:common-lisp | [Emacs command] |
| Arguments: &optional buffer-name directory executable-image-name image-args host image-file | |
Create a Common Lisp subprocess and put it in the buffer named by BUFFER-NAME, with default-directory of DIRECTORY, using EXECUTABLE-IMAGE-NAME and IMAGE-ARGS as the binary image pathname and command line arguments, doing the appropriate magic to execute the process on HOST. Lastly, for machines that use image files, IMAGE-FILE is the Common Lisp image to execute. This is separate from the executable. The first time this function is called and when given a prefix argument, all the above quantities are read from the minibuffer, with defaults coming from the variables: 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 and the values read are saved in these variables for later use as defaults, except that the directory argument does not side-effect the variable fi:common-lisp-directory. After the first time or when no prefix argument is given, the defaults are used and no information is read from the minibuffer. For backward compatibility, BUFFER-NAME can be a number, when called programmatically, which means look for, and use if found, numbered buffers of the form "*common-lisp*>N>" for N > 2. If BUFFER-NAME > 0, then find the first "free" buffer name and start a subprocess in that buffer. Each Emacs may have at most one Emacs-Lisp connection. If a connection already exists when fi:common-lisp is called, then the *common-lisp* buffer will be made the current buffer, and all arguments will be ignored.
Below is an example .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. (This is eli/examples/emacs.el.)
;; A sample ~/.emacs file.
;;
;; $Id: emacs.el,v 1.6.20.1 1998/07/16 16:47:45 layer Exp $
(defvar *eli-directory*)
(setq *eli-directory* (expand-file-name "~/cl-ultra/src/eli/"))
(when (and (not (string-match "xemacs" emacs-version))
(= emacs-major-version 20)
(>= emacs-minor-version 2))
(setq load-path (cons *eli-directory* load-path)))
(load (format "%sfi-site-init" *eli-directory*))
(setq fi:common-lisp-image-name "/usr/local/cl-5.0")
(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))
;; Set up a keybinding for `run-common-lisp', two possible ways:
(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:open-lisp-listener | [Emacs command] |
| Arguments: &optional buffer-number buffer-name setup-function | |
Open a connection to an existing Common Lisp process, started with the function fi:common-lisp, and create a Lisp Listener (a top-level interaction). The Common Lisp can be either local or remote. The name of the buffer is "*lisp-listener*" with an optional suffix of ">N>", for prefix arguments > 1. If a negative prefix argument is given, then the first "free" buffer name is found and used. When called from a program, the buffer name is the second optional argument.
| fi:toggle-to-lisp | [Emacs command] |
| Arguments: nil | |
On each invocation, switch back and forth between the Lisp subprocess buffer and the source buffer from which this function was invoked.
| fi:define-global-lisp-mode-bindings | [Emacs variable] |
| Initial value: t | |
If non-nil, define Lisp mode bindings on the \e and \C-x keys.
| fi:common-lisp-buffer-name | [Emacs variable] |
| Initial value: "*common-lisp*" | |
Default buffer name used by fi:common-lisp. This variable is set by fi:common-lisp when a new buffer name is used.
| fi:common-lisp-directory | [Emacs variable] |
| Initial value: nil | |
Default directory in which the process started by fi:common-lisp uses.
| fi:common-lisp-image-name | [Emacs variable] |
| Initial value: "lisp" | |
Default Common Lisp executable image used by fi:common-lisp. The value is a string that names the executable image fi:common-lisp invokes.
| fi:common-lisp-image-file | [Emacs variable] |
| Initial value: nil | |
Default Common Lisp heap image used by fi:common-lisp. If this variable is nil, and the corresponding argument to fi:common-lisp is not given, then a default heap image is loaded.
| fi:common-lisp-image-arguments | [Emacs variable] |
| Initial value: nil | |
Default Common Lisp image arguments when invoked from `fi:common-lisp', which must be a list of strings. Each element of the list is one command line argument.
| fi:common-lisp-host | [Emacs variable] |
| Initial value: "localhost" | |
The host on which fi:common-lisp starts the Common Lisp subprocess. The default is the host on which emacs is running.
| fi:common-lisp-prompt-pattern | [Emacs variable] |
| Initial value: "^\\(\\[[0-9]+i?c?\\] \\|\\[step\\] \\)?\\(>[-A-Za-z]* ?[0-9]*?>\\|[-A-Za-z0-9]+([0-9]+):\\) " | |
The regular expression which matches the Common Lisp prompt. Anything from beginning of line up to the end of what this pattern matches is deemed to be a prompt.
| fi:common-lisp-subprocess-timeout | [Emacs variable] |
| Initial value: 30 | |
This variable only has an effect on Windows. The value is the timeout, in seconds, that Emacs will wait for Lisp to startup, when no connection can be made in fi:common-lisp.
| fi:common-lisp-subprocess-wait-forever | [Emacs variable] |
| Initial value: nil | |
This variable only has an effect on Windows. If the value is non-nil, then wait forever for the Lisp to startup. Use with caution. The keyboard-quit function will interrupt the waiting, however.
| fi:connect-to-windows | [Emacs variable] |
| Initial value: (windows-nt ms-windows ms-dos win386) | |
If non-nil, then connect to Lisp running on a Windows machine. Since we connect in a fundamentally different way, the default value of this is non-nil only on Windows.
| fi:start-lisp-interface-arguments | [Emacs variable] |
| Initial value: (lambda (use-background-streams &optional lisp-image-name) (let ((args (list "-e" (format "(excl:start-emacs-lisp-interface %s)" use-background-streams)))) (when lisp-image-name (when (string-match "^~" lisp-image-name) (setq lisp-image-name (expand-file-name lisp-image-name))) (setq args (append (list "-I" lisp-image-name) args))) args)) | |
This value of this variable determines whether or not the emacs-lisp interface is started automatically when fi:common-lisp is used to run Common Lisp images. If non-nil, then a the value of this variable should be a function of one argument that returns command line argument sufficient to start the emacs-lisp interface. The argument is a boolean that determines whether or not background streams are used (see fi:use-background-streams).
| fi:use-background-streams | [Emacs variable] |
| Initial value: t | |
If non-nil, then the default function bound to fi:start-lisp-interface-arguments will cause background streams to be initialized in ACL (see the function excl:use-background-streams). Roughly speaking, background streams cause processes that do output, but which are not associated with any particular stream, to do it in a unique listener in an emacs buffer. This allows MP:PROCESS-RUN-FUNCTION in the Lisp environment to be more useful.
| fi:start-lisp-interface-hook | [Emacs variable] |
| Initial value: (fi::auto-ensure-lep-connection fi:show-run-status) | |
A function or a list of functions to call when we get the rendezvous info from Lisp in the Lisp subprocess buffer. This is used to automatically startup the Emacs-Lisp hidden communication via a socket. fi:start-lisp-interface-arguments initiates the connection with Lisp from the Emacs side, Lisp then starts up the daemon which listens for connections and prints a string to the subprocess buffer (which is not displayed by the process filter for the Common Lisp subprocess), at which time the hooks are run.
| fi:reset-lep-connection | [Emacs command] |
| Arguments: nil | |
Reset the Lisp-editor protocol connection.
| fi:in-package-regexp | [Emacs variable] |
| Initial value: nil | |
If non-nil, the regular expression that describes the IN-PACKAGE form, for purposes of tracking package changes in a subprocess Lisp buffer. The value of this is taken from fi:default-in-package-regexp in Lisp subprocess buffers, but is nil elsewhere.
| fi:default-in-package-regexp | [Emacs variable] |
| Initial value: "(in-package\\>\\|:pa\\>\\|:pac\\>\\|:pack\\>\\|:packa\\>\\|:packag\\>\\|:package\\>" | |
The regular expression matching the Lisp expression to change the current package. The two things this must match are the IN-PACKAGE macro form and all the possible instances of the :package top-level command. If nil, no automatic package tracking will be done.
| fi:inferior-common-lisp-mode | [Emacs command] |
| Arguments: &optional mode-hook &rest mode-hook-args | |
Major mode for interacting with Common Lisp subprocesses. The keymap for this mode is bound to fi:inferior-common-lisp-mode-map: key binding --- ------- C-c Prefix Command TAB fi:lisp-indent-line RET fi:inferior-lisp-newline C-x Prefix Command ESC Prefix Command ; fi:lisp-semicolon DEL backward-delete-char-untabify down-mouse-3 fi:inferior-common-lisp-mode-popup-menu C-c C-a fi:subprocess-beginning-of-line C-c C-c fi:interrupt-listener C-c C-d fi:remote-lisp-send-eof C-c C-e fi:end-of-defun C-c TAB fi:lisp-complete-symbol C-c C-k fi:subprocess-kill-output C-c C-l fi:list-input-ring C-c RET fi:subprocess-input-region 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-q fi:indent-sexp C-c C-r fi:re-search-backward-input C-c C-s fi:re-search-forward-input C-c C-t fi:trace-definer 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 C-y fi:pop-input C-c C-\ fi:subprocess-quit C-c SPC fi:lisp-delete-pop-up-window C-c % fi:extract-list C-c , fi:lisp-find-next-definition C-c - fi:log-functional-change C-c . fi:lisp-find-definition C-c 4 Prefix Command C-c ; fi:comment-region C-c = fi:lisp-sync-current-working-directory C-c ? fi:lisp-apropos C-c A fi:lisp-arglist C-c C fi:list-who-calls C-c D fi:describe-symbol C-c F fi:lisp-function-documentation C-c M fi:lisp-macroexpand C-c T fi:toggle-trace-definition C-c W fi:lisp-macroexpand-recursively C-c ] fi:super-paren C-c a fi:lisp-arglist C-c c fi:list-who-calls C-c d fi:describe-symbol C-c f fi:lisp-function-documentation C-c k fi:kill-definition C-c l fi:toggle-to-lisp C-c m fi:lisp-macroexpand C-c s fi:scan-stack C-c t fi:toggle-trace-definition C-c w fi:lisp-macroexpand-recursively C-x RET fi:inferior-lisp-input-list ESC TAB fi:lisp-complete-symbol ESC RET fi:inferior-lisp-input-sexp ESC C-q fi:indent-sexp ESC A fi:lisp-arglist ESC C fi:list-who-calls ESC D fi:describe-symbol ESC F fi:lisp-function-documentation ESC M fi:lisp-macroexpand ESC T fi:toggle-trace-definition ESC W fi:lisp-macroexpand-recursively C-c 4 . fi:lisp-find-definition-other-window Entry to this mode runs the following hooks: fi:lisp-mode-hook fi:subprocess-mode-hook fi:inferior-common-lisp-mode-hook in the above order. When calling from a program, arguments are MODE-HOOK and MODE-HOOK-ARGS, the former is applied to the latter just after killing all local variables but before doing any other mode setup.
| fi:inferior-lisp-input-list | [Emacs command] |
| Arguments: &optional arg | |
Send the list before the point to the Lisp subprocess. With prefix arg, ARG, send that many lists.
| fi:inferior-lisp-input-sexp | [Emacs command] |
| Arguments: &optional arg | |
Send the s-expression after the point to the Lisp subprocess. With prefix arg, ARG, send that many s-expressions.
| fi:inferior-lisp-newline | [Emacs command] |
| Arguments: nil | |
When at the end of the buffer, insert a newline into a Lisp subprocess buffer, and if a complete form has been entered, send the input to the Lisp subprocess. This allows partially complete, multi-line expressions to be edited before Lisp sees them. If not at the end of the buffer, this function does its best to find a complete form around the point, copy it to the end of the buffer, and send it to the Lisp subprocess.
| fi:lisp-sync-current-working-directory | [Emacs command] |
| Arguments: nil | |
Sychronize the current working directory in Emacs and Lisp, by making Lisp conform to the value of default-directory.
| fi:list-input-ring | [Emacs command] |
| Arguments: arg &optional reflect | |
Display contents of input ring. With argument ARG, start at command number ARG. The list is displayed in reverse order if called from a program and the optional second parameter is non-nil.
| fi:pop-input | [Emacs command] |
| Arguments: &optional arg | |
Yank previous text from input ring, and cycle through input ring with each successive invocation. With argument ARG, do it that many times.
| fi:push-input | [Emacs command] |
| Arguments: &optional arg | |
Yank next text from input ring, and cycle through input ring in reverse order with each successive invocation. With argument ARG, do it that many times.
| fi:re-search-backward-input | [Emacs command] |
| Arguments: arg regexp | |
Search backward in the input ring for an occurance of text that matches REGEXP and yank it. With argument, find the ARG match.
| fi:re-search-forward-input | [Emacs command] |
| Arguments: arg regexp | |
Search forward in the input ring for an occurance of text that matches REGEXP and yank it. With argument, find the ARG match.
| fi:remote-lisp-send-eof | [Emacs command] |
| Arguments: nil | |
Simulate sending an EOF to a Lisp subprocess that was started on a remote machine (with respect to the machine on which emacs is running). The remote process was most likely started with `rsh', and sending an EOF to a remote process started in this way closes down the pipe. The fake EOF is done by doing a debugger:debug-pop on the "Initial Lisp Listener" process via the backdoor.
| fi:subprocess-backward-kill-word | [Emacs command] |
| Arguments: arg | |
Kill previous word in current subprocess input line. This function takes care not to delete past the beginning of the the current input. With argument ARG, kill that many words.
| fi:subprocess-beginning-of-line | [Emacs command] |
| Arguments: arg | |
Moves point to beginning of line, just like (beginning-of-line arg), except that if the pattern at the beginning of the line matches the current subprocess prompt pattern, this function skips over it. With argument ARG non nil or 1, move forward ARG - 1 lines first.
| fi:subprocess-input-region | [Emacs command] |
| Arguments: start end | |
Send the region defined by the point and mark to the Lisp subprocess. When called from a program give START and END buffer positions.
| fi:subprocess-interrupt | [Emacs command] |
| Arguments: nil | |
Send a kill (SIGINT) signal to the current subprocess.
| fi:subprocess-kill | [Emacs command] |
| Arguments: nil | |
Send a kill (SIGKILL) signal to the current subprocess.
| fi:subprocess-kill-input | [Emacs command] |
| Arguments: nil | |
Kill all input since the last output by the current subprocess.
| fi:subprocess-kill-output | [Emacs command] |
| Arguments: nil | |
Kill all output from the subprocess since the last input. This is a convenient way to delete the output from the last command.
| fi:subprocess-quit | [Emacs command] |
| Arguments: nil | |
Send a quit (SIGQUIT) signal to the current subprocess.
| fi:subprocess-send-eof | [Emacs command] |
| Arguments: nil | |
Send an EOF (end of file) to the current subprocess.
| fi:subprocess-send-flush | [Emacs command] |
| Arguments: nil | |
Send the `flush output' character (^O) to current subprocess.
| fi:subprocess-show-output | [Emacs command] |
| Arguments: nil | |
Display the start of this batch of shell output at top of window. Also move the point there.
| fi:subprocess-suspend | [Emacs command] |
| Arguments: nil | |
Suspend the current subprocess.
| fi:lisp-listener-mode | [Emacs command] |
| Arguments: &optional mode-hook | |
Major mode for interacting with Common Lisp over a socket. The keymap for this mode is bound to fi:lisp-listener-mode-map: key binding --- ------- C-c Prefix Command TAB fi:lisp-indent-line RET fi:inferior-lisp-newline C-x Prefix Command ESC Prefix Command ; fi:lisp-semicolon DEL backward-delete-char-untabify C-c C-a fi:subprocess-beginning-of-line C-c C-c fi:interrupt-listener C-c C-d fi:tcp-lisp-listener-send-eof C-c C-e fi:end-of-defun C-c TAB fi:lisp-complete-symbol C-c C-k fi:subprocess-kill-output C-c C-l fi:list-input-ring C-c RET fi:subprocess-input-region 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-q fi:indent-sexp C-c C-r fi:re-search-backward-input C-c C-s fi:re-search-forward-input C-c C-t fi:trace-definer 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 C-y fi:pop-input C-c C-\ fi:tcp-lisp-listener-kill-process C-c SPC fi:lisp-delete-pop-up-window C-c % fi:extract-list C-c , fi:lisp-find-next-definition C-c - fi:log-functional-change C-c . fi:lisp-find-definition C-c 4 Prefix Command C-c ; fi:comment-region C-c = fi:lisp-sync-current-working-directory C-c ? fi:lisp-apropos C-c A fi:lisp-arglist C-c C fi:list-who-calls C-c D fi:describe-symbol C-c F fi:lisp-function-documentation C-c M fi:lisp-macroexpand C-c T fi:toggle-trace-definition C-c W fi:lisp-macroexpand-recursively C-c ] fi:super-paren C-c a fi:lisp-arglist C-c c fi:list-who-calls C-c d fi:describe-symbol C-c f fi:lisp-function-documentation C-c k fi:kill-definition C-c l fi:toggle-to-lisp C-c m fi:lisp-macroexpand C-c s fi:scan-stack C-c t fi:toggle-trace-definition C-c w fi:lisp-macroexpand-recursively C-x RET fi:inferior-lisp-input-list ESC TAB fi:lisp-complete-symbol ESC RET fi:inferior-lisp-input-sexp ESC C-q fi:indent-sexp ESC A fi:lisp-arglist ESC C fi:list-who-calls ESC D fi:describe-symbol ESC F fi:lisp-function-documentation ESC M fi:lisp-macroexpand ESC T fi:toggle-trace-definition ESC W fi:lisp-macroexpand-recursively C-c 4 . fi:lisp-find-definition-other-window Entry to this mode runs the following hooks: fi:lisp-mode-hook fi:subprocess-mode-hook fi:lisp-listener-mode-hook in the above order. When calling from a program, argument is MODE-HOOK, which is funcall'd just after killing all local variables but before doing any other mode setup.
| fi:interrupt-listener | [Emacs command] |
| Arguments: select | |
Interrupt a Lisp listener (send a SIGINT). Without a prefix argument, interrupt the Lisp process tied to the buffer in which this function is invoked. With a prefix argument, the listener in which this is invoked asks which Lisp process to interrupt and does a lisp:break on that process.
| fi:tcp-lisp-listener-kill-process | [Emacs command] |
| Arguments: nil | |
Simulate sending a SIGQUIT to the Lisp Listener pseudo-process, meaning kill the Common Lisp thread associated with the Lisp Listener buffer. It is not a real process because it is a network connection to the Common Lisp UNIX process, and since there is no tty control there is no character which is interpreted as `quit'. The fake `quit' is simulated by doing a mp:process-kill on the Common Lisp process tied to the Lisp Listener buffer via the backdoor.
| fi:tcp-lisp-listener-send-eof | [Emacs command] |
| Arguments: nil | |
Simulate sending an EOF on the Lisp Listener pseudo-process. It is not a real process because it is a network connection to the Common Lisp UNIX process, and EOF has no meaning (out-of-band data is not handled in either Emacs or Common Lisp, at this time). The fake EOF is simulated by doing a debugger:debug-pop on the Common Lisp process tied to the Lisp Listener buffer via the backdoor.
| fi:emacs-to-lisp-transaction-directory | [Emacs variable] |
| Initial value: "c:/tmp" | |
The directory in which files for Emacs/Lisp communication are stored. When using Lisp and Emacs on different machines, this directory must be accessible on both machine with the same pathname (via the wonders of NFS).
| fi:default-input-ring-max | [Emacs variable] |
| Initial value: 50 | |
The default maximum length to which an input ring is allowed to grow.
| fi:display-buffer-function | [Emacs variable] |
| Initial value: fi::switch-to-buffer-new-screen | |
If non-nil, then the value should be a function taking one argument, a buffer, which is used to display a buffer when a subprocess is created.
| fi:new-screen-for-common-lisp-buffer | [Emacs variable] |
| Initial value: nil | |
If non-nil, then starting Common Lisp will cause emacs to create a new screen for the *common-lisp* buffer, if this version of emacs is capable of creating separate screens. If you redefine fi:display-buffer-function this variable will be ignored.
| fi:eval-in-lisp | [Emacs function] |
| Arguments: string &rest args | |
Apply (Emacs Lisp) format to STRING and ARGS and sychronously evaluate the result in the Common Lisp to which we are connected.
| fi:eval-in-lisp-asynchronous | [Emacs function] |
| Arguments: string &rest args | |
Apply (Emacs Lisp) format to STRING and ARGS and asychronously evaluate the result in the Common Lisp to which we are connected.
| fi:filename-frobber-hook | [Emacs variable] |
| Initial value: fi::discombobulate-automounter-lint | |
If non-nil, then name of a function which transforms filenames received from Lisp. This exists solely for the purpose of removing /tmp_mnt/net from the beginning of filenames that are on automounted filesystems.
| fi:lisp-evalserver-number-reads | [Emacs variable] |
| Initial value: 200 | |
The number of times the Lisp eval server tries to read from the lisp-evalserver process before giving up. Without this feature Emacs would hang if Lisp got into an infinite loop while printing. If the size of the values returned to Emacs is large, then the value of this variable should be increased.
| fi:shell-cd-regexp | [Emacs variable] |
| Initial value: ":?cd" | |
The regular expression matching the C shell `cd' command and the Common Lisp :cd top-level command. If nil, no tracking of directory changes will be done.
| fi:shell-popd-regexp | [Emacs variable] |
| Initial value: ":?popd" | |
The regular expression matching the C shell `popd' command and the Common Lisp :popd top-level command. If nil, no tracking of directory changes will be done.
| fi:shell-pushd-regexp | [Emacs variable] |
| Initial value: ":?pushd" | |
The regular expression matching the C shell `pushd' command and the Common Lisp :pushd top-level command. If nil, no tracking of directory changes will be done.
| fi:subprocess-continuously-show-output-in-visible-buffer | [Emacs variable] |
| Initial value: t | |
If t, output from a subprocess to a visible buffer is continuously shown. If a subprocess buffer is visible and the window point is beyond the process output marker, output to that buffer from its associated process will be continuously visible. If the window point is before the process output marker, the window is not updated. This is a buffer-local symbol.
| fi:subprocess-enable-superkeys | [Emacs variable] |
| Initial value: nil | |
If t, certain keys become `superkeys' in subprocess buffers--this should be set before starting any subprocesses. The superkeys are C-a, C-d, C-o,C-u, C-w, C-z, and C-\, which will behave as they would in the current local keymap when typed at the end of a subprocess buffer. If typed elsewhere, these keys have their normal global binding. This is a buffer-local symbol. Use setq-default to set the default value for this symbol.
| fi:subprocess-env-vars | [Emacs variable] |
| Initial value: (("EMACS" . "t") ("TERM" . "emacs") ("DISPLAY" or (getenv "DISPLAY") (format "%s:0.0" (system-name))) ("TERMCAP" format "emacs:co#%d:tc=unknown:" (frame-width))) | |
An alist containing the environment variables to pass to newly created subprocesses.
| fi:superkey-shadow-universal-argument | [Emacs variable] |
| Initial value: t | |
If non-nil, then make C-u a superkey in subprocess modes, otherwise leave it alone.
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.
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. For some of the special forms and macros new to Common Lisp (due to the ANSI X3J13 committee), the indentation is not as standardized as it is for older forms. 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 | [Emacs variable] |
| Initial value: (40 t nil 0) | |
Specification list for indentations of semicolon comments. The nth element of the list specifies the indentation for a comment beginning with n semicolons (e.g. the first element of the list is the indentation for comments beginning with one semicolon). Each element of the list may be one of `t' (indent comment just like an s-expression), `nil' (don't change the indentation of the comment, i.e. leave the semicolon where it is), a non- negative integer (specifying the absolute column to which the comment is to be indented), or a negative integer (specifying a negative offset for the comment relative to the current column). 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.
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 readable.
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.htm for information on creating and using named readtables. |
Fields in the file mode line are separated by semicolons. The following example illustrate 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 is 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 | [Emacs variable] |
| Initial value: "user" | |
The name of the package to use as the default package, if there is no package specification in the mode line. See fi:parse-mode-line-and-package for more information.
| fi:package | [Emacs variable] |
| Initial value: nil | |
A buffer-local variable whose value is automatically set for editing modes and will be nil or a string which names a package in the Lisp world--ie, in a Lisp subprocess running as an inferior of Emacs in some buffer. It is used when expressions are sent from an Emacs buffer to a Lisp process so that the symbols are read into the correct Lisp package.
| fi:readtable | [Emacs variable] |
| Initial value: nil | |
A buffer-local variable whose value is automatically set for editing modes and will be nil or a string which names a readtable in the Lisp world--ie, in a Lisp subprocess running as an inferior of Emacs in some buffer. It is used when expressions are sent from an Emacs buffer to a Lisp process so that the expressions are read using the correct 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-list
Take 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:comment-region
Comment the region between the point and the mark. With a non-nil prefix argument, uncomment the region.
fi:super-paren
Close the current top-level form by inserting as many parenthesis as are necessary.
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
--- -------
C-c C-r fi:lisp-eval-or-compile-region
C-c C-s fi:lisp-eval-or-compile-last-sexp
C-c C-b fi:lisp-eval-or-compile-current-buffer
ESC C-x fi:lisp-eval-or-compile-defun
The above group of functions cause the
region, last s-expression, the entire buffer
or the current top-level form to be
evaluated in the Common Lisp environment.
With a prefix argument, the source is
compiled.
C-c m fi:lisp-macroexpand
C-c w fi:lisp-macroexpand-recursively
The above two functions cause the form at the point
to be macroexpanded, recursively so with the second
function.
C-c t fi:toggle-trace-definition Toggle tracing a function in the Common Lisp environment. If it is currently being traced, then tracing will be turned off, or if is not being traced, then tracing will be turned on for this one function. With a prefix argument, entry to this function will cause entry into the debugger (trace on break).
C-c ? fi:lisp-apropos
C-c f fi:lisp-function-documentation
C-c d fi:describe-symbol
C-c c fi:list-who-calls
C-c a fi:lisp-arglist
The above group of functions read a function name
from the minibuffer, using the symbol at the point,
if there is one, as the default answer, and execute
`apropos', find the documentation on the function,
describe the function, find the callers of the
function, or the arglist for the function, in the
Common Lisp environment. The information is printed
in the minibuffer if it will fix, otherwise a buffer
is popped up that displays the information.
C-c TAB fi:lisp-complete-symbol Dynamically complete the symbol at the point in the Common 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 substring before the hyphen to be matched at the beginning of words in target symbols.
C-c . fi:lisp-find-definition
C-c 4 . fi:lisp-find-definition-other-window
C-c , fi:lisp-find-next-definition
The above group of functions are used for finding
definitions of objects defined in the Common Lisp
environment. See the documents
source_file_recording.htm
xref.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 | [Emacs command] |
| Arguments: &optional mode-hook | |
Major mode for editing Lisp code to run in Common Lisp. The keymap for this mode is bound to fi:common-lisp-mode-map: key binding --- ------- C-c Prefix Command TAB fi:lisp-indent-line RET fi:lisp-mode-newline C-x Prefix Command ESC Prefix Command ; fi:lisp-semicolon DEL backward-delete-char-untabify down-mouse-3 fi:common-lisp-mode-popup-menu C-c C-b fi:lisp-eval-or-compile-current-buffer C-c C-e fi:end-of-defun C-c TAB fi:lisp-complete-symbol C-c C-q fi:indent-sexp C-c C-r fi:lisp-eval-or-compile-region C-c C-s fi:lisp-eval-or-compile-last-sexp C-c C-t fi:trace-definer C-c C-x fi:lisp-eval-or-compile-defun C-c SPC fi:lisp-delete-pop-up-window C-c % fi:extract-list C-c , fi:lisp-find-next-definition C-c - fi:log-functional-change C-c . fi:lisp-find-definition C-c 4 Prefix Command C-c ; fi:comment-region C-c ? fi:lisp-apropos C-c A fi:lisp-arglist C-c C fi:list-who-calls C-c D fi:describe-symbol C-c F fi:lisp-function-documentation C-c M fi:lisp-macroexpand C-c T fi:toggle-trace-definition C-c W fi:lisp-macroexpand-recursively C-c ] fi:super-paren C-c ^ fi:center-defun C-c a fi:lisp-arglist C-c c fi:list-who-calls C-c d fi:describe-symbol C-c f fi:lisp-function-documentation C-c k fi:kill-definition C-c l fi:toggle-to-lisp C-c m fi:lisp-macroexpand C-c t fi:toggle-trace-definition C-c w fi:lisp-macroexpand-recursively ESC TAB fi:lisp-complete-symbol ESC C-q fi:indent-sexp ESC C-x fi:lisp-eval-or-compile-defun ESC A fi:lisp-arglist ESC C fi:list-who-calls ESC D fi:describe-symbol ESC F fi:lisp-function-documentation ESC M fi:lisp-macroexpand ESC T fi:toggle-trace-definition ESC W fi:lisp-macroexpand-recursively C-c 4 . fi:lisp-find-definition-other-window Entry to this mode runs the following hooks: fi:lisp-mode-hook fi:common-lisp-mode-hook in the above order. When calling from a program, argument is MODE-HOOK, which is funcall'd just after killing all local variables but before doing any other mode setup.
| fi:center-defun | [Emacs command] |
| Arguments: nil | |
Put the first line of the current definition on the first line of the window, leaving the point unchanged.
| fi:comment-region | [Emacs command] |
| Arguments: &optional start end uncomment | |
Comment all lines in the current region. With prefix arg, uncomment the region (it should have been commented with this function). When calling from a program, arguments are START and END, both buffer positions, and UNCOMMENT.
| fi:uncomment-region | [Emacs command] |
| Arguments: start end | |
Uncomment all lines in the current region (it should have been commented with the function fi:comment-region). When calling from a program, arguments are START and END.
| fi:end-of-defun | [Emacs command] |
| Arguments: nil | |
Put the point at the end of the current top-level form.
| fi:extract-list | [Emacs command] |
| Arguments: arg | |
Take the list after the point and remove the surrounding list. With argument ARG do it that many times.
| fi:indent-sexp | [Emacs command] |
| Arguments: nil | |
Indent each line of the list starting just after point.
| fi:lisp-apropos | [Emacs command] |
| Arguments: string &optional regexp | |
In the Common Lisp environment evaluate lisp:apropos on STRING. With prefix arg REGEXP, STRING is a regular expression for which matches are sought. fi:package is used to determine from which Common Lisp package the operation is done. In a subprocess buffer, the package is tracked automatically. In source buffer, the package is parsed at file visit time.
| fi:lisp-arglist | [Emacs command] |
| Arguments: string | |
Dynamically determine, in the Common Lisp environment, the arglist for STRING. fi:package is used to determine from which Common Lisp package the operation is done. In a subprocess buffer, the package is tracked automatically. In source buffer, the package is parsed at file visit time.
| fi:lisp-complete-symbol | [Emacs command] |
| Arguments: nil | |
Perform completion on the Common Lisp symbol preceding the point. That symbol is compared to symbols that exist in the Common Lisp environment. If the symbol starts just after an open-parenthesis, then only symbols (in the Common Lisp) with function definitions are considered. Otherwise all symbols are considered. fi:package is used to determine from which Common Lisp package the operation is done. In a subprocess buffer, the package is tracked automatically. In source buffer, the package is parsed at file visit time. 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 substring before the hyphen to be matched at the beginning of words in target symbols.
| fi:describe-symbol | [Emacs command] |
| Arguments: fspec | |