The Emacs-Lisp Interface
ELI Version 2.0.21.16.2
$Revision: 1.1.2.4 $
Table of Contents
1. Introduction to the
Emacs-Lisp interface
2. Starting the Emacs-Lisp interface
2.1. Troubleshooting the
Emacs-Lisp interface
3. Running Common Lisp
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
6. Shell modes
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:
- Introduction to the Emacs-Lisp interface, the section you are now reading. This section
presents an overview of the Emacs-Lisp interface and describes the organization of the
whole document.
- Starting the Emacs-Lisp interface. This section discusses starting up the primary
mechanism for Emacs-Lisp interaction. A troubleshooting guide suggests what may be wrong
if things do not work as expected.
- Running Common Lisp. This section describes how Common Lisp can be started as a
subprocess of Emacs.
- Editing Common Lisp Programs. This section discusses the facilities for editing of Lisp
programs.
- Writing and Debugging Common Lisp Programs. This section discusses the finer points of
debugging programs written in Lisp. In this section, many of the features associated with
Lisp machines are discussed in detail.
- Shell modes. This section discusses other useful modes for creating shells, rlogins,
telnets, etc. It is here for completeness and because many of the features in the Lisp
subprocess modes are also available in these subprocess modes.
- Advanced miscellaneous features. This section discusses when Emacs Lisp hooks are
called.
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 |
- A description of how to invoke the command (commands are also called interactive
functions) followed by a description. Commands often have preassigned key bindings that
will invoke them while functions do not have preassigned key bindings. In the
documentation string, arguments appear in Courier-Italic and are described in the order in
which they appear in the formal arglist.
- The key binding that invokes a command may have a prefix argument. The GNU Emacs Lisp
Manual defines a prefix argument as follows: [...] a number before the
command itself. (Don't confuse prefix arguments with prefix keys.) The prefix
argument is represented by a value that is always available (though it may be
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 |
- A description of how to call the function followed by a description. Functions do not
have preassigned key bindings while commands do have preassigned key bindings. The user
may assign key bindings to functions. In the description, arguments appear in
Courier-Italic and are described in the order in which they appear in the formal arglist.
user-option-name |
[Emacs user option] |
Initial value: value |
- The initial value of the user option followed by a description. Note that user options
are user-settable and variables are set by the system and should only be examined but not
set by users. The Emacs function describe-variable will return the documentation string of
a user-option or variable. User-options are identified with a * appearing at the beginning
of the documentation string. Note that descriptions in this document are not the same as
the documentation strings (displayed by describe-variable), hence the * will not appear at
the beginning of descriptions in this document.
variable-name |
[Emacs variable] |
Initial value: value |
- The initial value of the variable followed by a description. Note that user options are
user-settable and variables are set by the system and should only be examined but not set
by users.
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.
XEmacs users only:
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.
- C-u may not behave in an expected manner. If a C-u is typed at the end of certain types
of buffers, then the functionality invoked will be different from the standard Emacs
functionality. This is because C-u can be bound as a superkey (see the information under
the heading Superkeys in section 3.1). In Emacs C-u is the universal-argument. In a Unix
shell C-u is often the kill character. The Emacs-Lisp Interface provides either
functionality depending on where in the buffer C-u is typed. If you are at the end of a
buffer and are getting the kill behavior when you want the prefix behavior, move up one
line (with C-p) and try again.
- The Emacs-Lisp interface keeps track of the current package of common-lisp-mode buffers.
If the Emacs-Lisp interface fails to correctly determine the current package, then the
interface may fail in mysterious ways. The most common failure occurs when the Emacs-Lisp
interface attempts to query the Common Lisp environment. If you experience strange
failures you may want to verify that the Emacs-Lisp interface has the correct package by
doing the following:
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.20 (shipped with Allegro CL 4.3.2 on Windows 95/NT) to
2.0.21.16.2:
- fi:common-lisp does not side-effect fi:common-lisp-directory.
- New variable, fi:common-lisp-image-file, is used by fi:common-lisp to default the image-file
argument (when calling from a program) and question (when calling interactively).
- fi:common-lisp-image-name can no longer be a cons, the cdr being the Lisp image file. See fi:common-lisp-image-file above.
- The clman facility is no longer distributed. It was out of date. It will be
replaced in the near future with an HTML version.
- Allegro CL if* macro now available in Emacs Lisp.
- Building on UNIX: type make in the eli/ directory. The number of
warnings during the compile has been reduced to 1.
- Bug fix: make sure the case mode of Lisp and Emacs never get out of sync.
- Lisp mode bindings: the C-c<upper case character>
bindings are now available as C-c<lower case character>,
too.
- New Lisp mode binding: C-cC-t is bound to fi:trace-definer.
- New variable, fi:auto-fill, controls whether or not
auto-fill minor mode is used in Lisp editing modes. The default value is nil.
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:
- The fi:common-lisp function takes an additional optional
argument, when called from a program, the Lisp image file to use. The image-file argument is the sixth optional argument to fi:common-lisp. When called interactively, fi:common-lisp now asks for the name of the Lisp image file.
This question is fourth of five questions.
- fi:common-lisp-image-name can now be a cons, the car being the Lisp executable and the cdr
being the Lisp image file.
- On Windows, the host argument to fi:common-lisp always
defaults to "localhost". There is
currently no support for remotely running Lisp.
- Build procedure on Windows is to just load fi-site-init.
The necessary files will be automatically compiled before loading. If you
want this behavior on UNIX, set fi:compile-at-load-time to
t in your ~/.emacs.
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
Note about running Common Lisp on a different machine than Emacs
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.
- Start up Emacs with the -q option: <shell prompt>% emacs -q This will start up
Emacs without reading your .emacs file.
- Load the Emacs-Lisp interface by hand: M-x load-file RET /usr/acl50/eli/fi-site-init
- Start up a Common Lisp image with the -qq option: M-x fi:common-lisp Answer the
question: Image arguments (separate by spaces): with -qq This will start up Common Lisp
without reading any .clinit.cl files.
- Try the Emacs-Lisp interface command that tests the interface: M-x
fi:verify-emacs-support. See 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.
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.
General subprocess interaction
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
Editing
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
Lisp environment query
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.
Superkeys
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.
Input rings
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.
Tracking directory changes
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.
Tracking package changes
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.
Lisp Listeners
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 |
- Invoke with M-x fi:common-lisp.
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*" 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 |
- Invoke with M-x fi:open-lisp-listener.
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 "", 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 |
fi:define-global-lisp-mode-bindings |
[Emacs variable] |
Initial value: t |
fi:common-lisp-buffer-name |
[Emacs variable] |
Initial value: "*common-lisp*" |
fi:common-lisp-directory |
[Emacs variable] |
Initial value: nil |
fi:common-lisp-image-name |
[Emacs variable] |
Initial value: "lisp" |
fi:common-lisp-image-file |
[Emacs variable] |
Initial value: nil |
fi:common-lisp-image-arguments |
[Emacs variable] |
Initial value: nil |
fi:common-lisp-host |
[Emacs variable] |
Initial value: nil |
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]+):\\) " |
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: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 |
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\\>" |
fi:inferior-common-lisp-mode |
[Emacs command] |
Arguments: &optional mode-hook &rest mode-hook-args |
- Invoke with M-x fi:inferior-common-lisp-mode.
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
C-\ .. C-^ fi:self-insert-command
SPC .. : fi:self-insert-command
; fi:lisp-semicolon
< .. ~ fi:self-insert-command
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 |
fi:inferior-lisp-input-sexp |
[Emacs command] |
Arguments: &optional arg |
fi:inferior-lisp-newline |
[Emacs command] |
Arguments: nil |
- Invoke with RET in fi:inferior-common-lisp-mode.
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 |
fi:list-input-ring |
[Emacs command] |
Arguments: arg &optional reflect |
fi:pop-input |
[Emacs command] |
Arguments: &optional arg |
fi:push-input |
[Emacs command] |
Arguments: &optional arg |
fi:re-search-backward-input |
[Emacs command] |
Arguments: arg regexp |
fi:re-search-forward-input |
[Emacs command] |
Arguments: arg regexp |
fi:remote-lisp-send-eof |
[Emacs command] |
Arguments: nil |
- Invoke with C-c C-d in fi:inferior-common-lisp-mode.
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 |
fi:subprocess-beginning-of-line |
[Emacs command] |
Arguments: arg |
- Invoke with C-c C-a in fi:inferior-common-lisp-mode.
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 |
fi:subprocess-interrupt |
[Emacs command] |
Arguments: nil |
fi:subprocess-kill |
[Emacs command] |
Arguments: nil |
fi:subprocess-kill-input |
[Emacs command] |
Arguments: nil |
fi:subprocess-kill-output |
[Emacs command] |
Arguments: nil |
fi:subprocess-quit |
[Emacs command] |
Arguments: nil |
fi:subprocess-send-eof |
[Emacs command] |
Arguments: nil |
fi:subprocess-send-flush |
[Emacs command] |
Arguments: nil |
fi:subprocess-show-output |
[Emacs command] |
Arguments: nil |
fi:subprocess-suspend |
[Emacs command] |
Arguments: nil |
fi:lisp-listener-mode |
[Emacs command] |
Arguments: &optional mode-hook |
- Invoke with M-x fi:lisp-listener-mode.
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 |
- Invoke with C-c C-c in fi:lisp-listener-mode.
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 |
- Invoke with C-c C-\ in fi:lisp-listener-mode.
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 |
- Invoke with C-c C-d in fi:lisp-listener-mode.
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: "/tmp" |
fi:default-input-ring-max |
[Emacs variable] |
Initial value: 50 |
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 |
fi:eval-in-lisp-asynchronous |
[Emacs function] |
Arguments: string &rest args |
fi:filename-frobber-hook |
[Emacs variable] |
Initial value: fi::discombobulate-automounter-lint |
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" |
fi:shell-popd-regexp |
[Emacs variable] |
Initial value: ":?popd" |
fi:shell-pushd-regexp |
[Emacs variable] |
Initial value: ":?pushd" |
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:" (screen-width))) |
fi:superkey-shadow-universal-argument |
[Emacs variable] |
Initial value: t |
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:
- a positive number n, which means indent to the nth column,
- a negative number, which means indent a negative number of columns relative to the
current column,
- t, which means indent as an s-expression at the same column surrounding s-expressions
are indented to, or
- nil, which means leave the comment where it is.
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 in-package macro form is parsed when a file is visited, and the argument to
in-package is used as the package for that buffer.
- The file mode line (unfortunately named, since the name conflicts with the display mode
line) also communicates information about the file to Emacs.
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" |
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 |
- Invoke with M-x fi:common-lisp-mode.
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 |
fi:comment-region |
[Emacs command] |
Arguments: &optional start end uncomment |
- Invoke with C-c ; in fi:common-lisp-mode.
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 |
fi:end-of-defun |
[Emacs command] |
Arguments: nil |
fi:extract-list |
[Emacs command] |
Arguments: arg |
fi:indent-sexp |
[Emacs command] |
Arguments: nil |
fi:lisp-apropos |
[Emacs command] |
Arguments: string &optional regexp |
- Invoke with C-c ? in fi:common-lisp-mode.
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 |
- Invoke with C-c A in fi:common-lisp-mode.
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 |
- Invoke with C-c TAB in fi:common-lisp-mode.
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 |
- Invoke with C-c D in fi:common-lisp-mode.
Dynamically, in the Common Lisp environment, describe the symbol named
by FSPEC.
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-evals-always-compile |
[Emacs variable] |
Initial value: t |
This variable controls whether or not the fi:lisp-eval-or-compile-*
functions will compile or evaluate their forms. If non-nil, then
compilation is the default, otherwise evaluation is the default.
The non-default functionality can be selected by using a prefix argument.
fi:lisp-eval-current-buffer |
[Emacs command] |
Arguments: nil |
fi:lisp-eval-or-compile-current-buffer |
[Emacs command] |
Arguments: compilep |
fi:lisp-eval-defun |
[Emacs command] |
Arguments: nil |
fi:lisp-compile-current-buffer |
[Emacs command] |
Arguments: nil |
fi:lisp-compile-defun |
[Emacs command] |
Arguments: nil |
fi:lisp-eval-or-compile-defun |
[Emacs command] |
Arguments: compilep |
fi:lisp-eval-last-sexp |
[Emacs command] |
Arguments: nil |
fi:lisp-compile-last-sexp |
[Emacs command] |
Arguments: nil |
fi:lisp-eval-or-compile-last-sexp |
[Emacs command] |
Arguments: compilep |
fi:lisp-eval-region |
[Emacs command] |
Arguments: nil |
fi:lisp-compile-region |
[Emacs command] |
Arguments: nil |
fi:lisp-eval-or-compile-region |
[Emacs command] |
Arguments: compilep |
fi:lisp-find-definition |
[Emacs command] |
Arguments: tag &optional next |
- Invoke with C-c . in fi:common-lisp-mode.
Find TAG using information in the Common Lisp environment, in the current
window. With prefix arg NEXT, find the next occurance of the last tag.
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-find-definition-other-window |
[Emacs command] |
Arguments: tag &optional next |
- Invoke with C-c 4 . in fi:common-lisp-mode.
Find TAG in the other window using information in the Common Lisp
environment, in the current window. With prefix arg NEXT, find the next
occurance of the last tag. 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-find-next-definition |
[Emacs command] |
Arguments: nil |
- Invoke with C-c , in fi:common-lisp-mode.
Continue last tags search, started by fi:lisp-find-definition.
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-function-documentation |
[Emacs command] |
Arguments: symbol |
- Invoke with C-c F in fi:common-lisp-mode.
Dynamically, in the Common Lisp environment, determine the function
documentation for SYMBOL.
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-indent-line |
[Emacs command] |
Arguments: &optional whole-exp |
fi:lisp-macroexpand |
[Emacs command] |
Arguments: nil |
- Invoke with C-c M in fi:common-lisp-mode.
Print the macroexpansion of the form at the point.
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-macroexpand-recursively |
[Emacs command] |
Arguments: arg |
- Invoke with C-c W in fi:common-lisp-mode.
Print the full, recursive macroexpansion the form at the point.
With prefix arg, recursively macroexpand the code as the compiler
would. (The compiler simulation is approximate only and does not
preserve the precise semantics of the form.) 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-mode-auto-indent |
[Emacs variable] |
Initial value: t |
If non-nil, then the command bound to \r, fi:lisp-mode-newline, will
indent, newline and indent. It does this by funcalling the value bound to
indent-line-function.
fi:lisp-mode-newline |
[Emacs command] |
Arguments: nil |
fi:log-functional-change |
[Emacs command] |
Arguments: nil |
fi:super-paren |
[Emacs command] |
Arguments: nil |
fi:trace-definition |
[Emacs command] |
Arguments: break |
fi:toggle-trace-definition |
[Emacs command] |
Arguments: string |
- Invoke with C-c T in fi:common-lisp-mode.
Dynamically toggle, in the Common Lisp environment, tracing for STRING.
If tracing is turned on, then it will be turned off for STRING. If it is
turned off, then it will be turned on for STRING. With a prefix arg, cause
the debugger to be invoked, via a call to BREAK, when the function is called.
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:definition-mode |
[Emacs command] |
Arguments: nil |
- Invoke with M-x fi:definition-mode.
A major mode for viewing definitions of objects defined in the Common
Lisp environment. The definitions are put in a buffer called
*definitions*, and each line contains the name and type of the definition.
The type is one of:
:operator for functions, methods, generic functions
and macros,
:type for classes (types),
:setf-method for setf methods, or
:variable for constants and variables.
Definition mode is used by other tools, such as the changed-definition
commands, fi:list-who-calls as well as fi:list-buffer-definitions.
The keymap for this mode is bound to fi:definition-mode-map:
key binding
--- -------
C-_ fi:definition-mode-undo
. fi:definition-mode-goto-definition
n fi:definition-mode-goto-next
p fi:definition-mode-goto-previous
q fi:definition-mode-quit
t fi:definition-mode-toggle-trace
Entry to this mode runs the fi:definition-mode-hook.
fi:inverse-definition-mode |
[Emacs command] |
Arguments: nil |
- Invoke with M-x fi:inverse-definition-mode.
A major mode for viewing inverse definitions of objects defined in the
Common Lisp environment. The definitions are put in a buffer called
*inverse-definitions*, and each line contains the name and type of the
definition. As definition-mode shows definitions and provides bindings to
go to the source of the definitions, inverse-definition-mode shows
definitions and provides ways to find the users of the definitions.
The type is one of:
:operator for functions, methods, generic functions
and macros,
:type for classes (types),
:setf-method for setf methods, or
:variable for constants and variables.
Inverse definition mode is used by other tools, such as
fi:list-undefined-functions.
The keymap for this mode is bound to fi:inverse-definition-mode-map:
Uses keymap "fi:inverse-definition-mode-map", which is not currently defined.
Entry to this mode runs the fi:inverse-definition-mode-hook.
fi:maintain-definition-stack |
[Emacs variable] |
Initial value: t |
If non-nil, then maintain a stack of definitions found by various
source code finding functions (fi:lisp-find-definition,
fi:edit-generic-function-methods, etc). When you find a definition for
a name and there are multiple definitions, fi:lisp-find-next-definition is
used to step through the list of definitions. If, in the middle of
stepping through some definitions, another find definition command is
executed, then the previous definitions are pushed onto a stack and can one
can resume finding these definitions after the current ones are
exhausted.
fi:compare-source-files |
[Emacs command] |
Arguments: new-file old-file |
- Invoke with M-x fi:compare-source-files.
Compare two files, NEW-FILE and OLD-FILE, listing the definitions in the
in NEW-FILE which have been added, deleted or changed with respect to
OLD-FILE.
fi:list-buffer-definitions |
[Emacs command] |
Arguments: nil |
fi:list-undefined-functions |
[Emacs command] |
Arguments: nil |
- Invoke with M-x fi:list-undefined-functions.
Using the cross referencing database in the Lisp environment and
inverse-definition mode, find and display all the functions which are
called but not defined. See the documentation for
fi:inverse-definition-mode for more information on finding the callers of
the undefined functions. See the Allegro CL variable
EXCL:*RECORD-XREF-INFO*.
fi:list-unused-functions |
[Emacs command] |
Arguments: nil |
- Invoke with M-x fi:list-unused-functions.
Using the cross referencing database in the Lisp environment and
definition mode, find and display all the functions which are
defined but not called. See the documentation for fi:definition-mode for
more information on finding the definitions of the unused functions. See
the Allegro CL variable EXCL:*RECORD-XREF-INFO*.
fi:definition-mode-goto-definition |
[Emacs command] |
Arguments: nil |
fi:definition-mode-goto-next |
[Emacs command] |
Arguments: nil |
fi:definition-mode-goto-previous |
[Emacs command] |
Arguments: nil |
fi:definition-mode-quit |
[Emacs command] |
Arguments: nil |
fi:definition-mode-undo |
[Emacs command] |
Arguments: nil |
fi:definition-mode-toggle-trace |
[Emacs command] |
Arguments: nil |
fi:inverse-definition-mode-quit |
[Emacs command] |
Arguments: nil |
fi:inverse-definition-who-calls |
[Emacs command] |
Arguments: nil |
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:
- commands which query the Common Lisp environment for information
- commands to change the state of the Common Lisp environment
- a mode for debugging Common Lisp processes from within Emacs
- additional lisp listeners for debugging multiprocessing applications
- programming aids
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.
fi:auto-fill |
[Emacs variable] |
Initial value: nil |
fi:check-unbalanced-parentheses-when-saving |
[Emacs variable] |
Initial value: t |
If non-nil, for the Lisp editing modes (Common Lisp, Emacs Lisp, and
Franz Lisp) check for unbalanced parentheses before writing the file.
If the value is T, then ask whether or not the file should be written ``as
is'' if there are too many or few parens--answering no leaves the point at
the place of error. If the value is 'warn, then a warning is issued and
the file is written.
fi:common-lisp-file-types |
[Emacs variable] |
Initial value: (".cl" ".lisp" ".lsp") |
fi:compile-file |
[Emacs command] |
Arguments: file |
fi:echo-evals-from-buffer-in-listener-p |
[Emacs variable] |
Initial value: nil |
If non-nil, functions which eval a region, form, or an entire buffer will
echo evaluated forms and results directly in the initial Lisp listener buffer.
If nil, the results of evalation will be printed in the minibuffer if they
fit, or otherwise in a popup buffer.
fi:fill-paragraph |
[Emacs command] |
Arguments: arg |
fi:find-tag-lock |
[Emacs variable] |
Initial value: t |
fi:find-unbalanced-parenthesis |
[Emacs command] |
Arguments: nil |
fi:indent-code-rigidly |
[Emacs command] |
Arguments: start end arg &optional nochange-regexp |
- Invoke with M-x fi:indent-code-rigidly.
Indent all lines of code, starting in the region, sideways by ARG columns.
Does not affect lines starting inside comments or strings, assuming that
the start of the region is not inside them. Called from a program, takes
args START, END, COLUMNS and NOCHANGE-REGEXP. The last is a regexp which,
if matched at the beginning of a line, means don't indent that line.
fi:indent-methods-case-sensitive |
[Emacs variable] |
Initial value: t |
If non-nil, the code that is being edited is for a case-sensitive dialect
of Lisp. This variable is buffer-local. If a Lisp is case-insensitive,
indentation specifications should be placed on the Emacs Lisp symbol that
corresponds to the lowercase name of the function, macro, or special
form.
fi:kill-definition |
[Emacs command] |
Arguments: do-kill |
- Invoke with M-x fi:kill-definition.
Insert a form to kill, or undefine, the definition that starts at the
point. The undefining form is inserted after the form to undefine.
With prefix arg DO-KILL, then actually undefine the form in the Common Lisp
environment instead of inserted the undefining form. 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-do-indentation |
[Emacs variable] |
Initial value: t |
fi:lisp-electric-semicolon |
[Emacs variable] |
Initial value: nil |
fi:load-file |
[Emacs command] |
Arguments: file |
fi:parse-mode-line-and-package |
[Emacs command] |
Arguments: nil |
- Invoke with M-x fi:parse-mode-line-and-package.
Determine the current package in which the buffer is defined.
The buffer's IN-PACKAGE form and the -*- mode line are parsed for this
information. This function is automatically called when a Common Lisp
source file is visited, but may be executed explicitly to re-parse the
package.
When using Allegro CL 4.2 or later, the ``Readtable: '' can be used to name
the readtable used for evaluations given to Lisp from emacs.
fi:pop-to-sublisp-buffer-after-lisp-eval |
[Emacs variable] |
Initial value: nil |
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 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 excl:*record-source-file-info*
and excl:*load-source-file-info*
are non-nil.
Retrieving information from the Common Lisp environment
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
Table 10: 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 (We mention these functions briefly. Their full
descriptions are later):
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 names *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.
Emacs functions and variables for retrieving CL environment information
fi:lisp-delete-pop-up-window |
[Emacs command] |
Arguments: nil |
fi:pop-up-temp-window-behavior |
[Emacs variable] |
Initial value: (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. The value is a cons of the style and a
boolean of whether or not the minibuffer should be used for displaying the
result. The possible values for the CAR of the cons are the symbols
SPLIT, OTHER, and REPLACE. 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, spliting the screen if there is only one window. REPLACE causes
the current window to be replaced with the help buffer. The reason for
specifying a CDR of nil is so that a window is always used--messages
printed in the minibuffer can easily be erased.
fi:list-who-calls |
[Emacs command] |
Arguments: &optional fspec |
- Invoke with C-c C in fi:common-lisp-mode.
List all the callers of FSPEC. `List' means to show them in a buffer in
definition mode. The source for each definition can be easily found via
key bindings in definition mode. The default FSPEC is taken from the text
surrounding the point. 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:list-who-is-called-by |
[Emacs command] |
Arguments: fspec |
- Invoke with M-x fi:list-who-is-called-by.
List all the functions called by FSPEC. `List' means to show them in a
buffer in definition mode. The source for each definition can be easily
found via key bindings in definition mode. The default FSPEC is taken from
the text surrounding the point. 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:edit-who-calls |
[Emacs command] |
Arguments: fspec |
fi:edit-who-is-called-by |
[Emacs command] |
Arguments: fspec |
fi:list-generic-function-methods |
[Emacs command] |
Arguments: &optional fspec |
- Invoke with M-x fi:list-generic-function-methods.
List all the generic function methods of FSPEC. `List' means to show
them in a buffer in definition mode. The source for each definition can be
easily found via key bindings in definition mode. The default FSPEC is
taken from the text surrounding the point. 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:edit-generic-function-methods |
[Emacs command] |
Arguments: fspec |
fi:describe-class |
[Emacs command] |
Arguments: fspec |
- Invoke with M-x fi:describe-class.
Dynamically, in the Common Lisp environment, describe the class named by
FSPEC.
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:describe-function |
[Emacs command] |
Arguments: fspec |
- Invoke with M-x fi:describe-function.
Dynamically, in the Common Lisp environment, describe the function named
by FSPEC.
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.
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.
Emacs functions and variables that interact with Allegro Composer
fi:inspect-class |
[Emacs command] |
Arguments: something |
fi:inspect-function |
[Emacs command] |
Arguments: something |
fi:inspect-value |
[Emacs command] |
Arguments: something |
fi:show-calls-to |
[Emacs command] |
Arguments: function |
fi:show-calls-from |
[Emacs command] |
Arguments: function |
fi:show-subclasses |
[Emacs command] |
Arguments: class |
fi:show-superclasses |
[Emacs command] |
Arguments: class |
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 11: 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, defined just below. The value of since
causes the above functions to operate on the changes:
- since = 1: since the file was first read by Emacs.
- since = 2: since the current buffer was last saved (by Emacs).
- since = 3: that have not yet been compiled or evaluated by Emacs.
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 |
[Emacs variable] |
Initial value: last-compile-or-eval |
The value of this variable is used as the default SINCE
argument to the changed-definition commands. The value must be one of the
symbols file-first-read, buffer-save or last-compile-or-eval, which
correspond to SINCE arguments of 1, 2 and 3. The meaning of each of the
values are:
file-first-read - the changes since the file was first read by emacs are
used,
buffer-save - the changes since the last buffer save are used, and
last-compile-or-eval - the changes since the last compile or eval changed
definition command was issued.
Functions and variables that modify the state of the Lisp environment
All of these functions act on definitions which have changed since:
- a file was first read by Emacs (since = 1)
- a buffer was last saved (since = 2)
- a buffer was last compiled or evaluated (since = 3).
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 |
[Emacs command] |
Arguments: since |
fi:list-changed-definitions |
[Emacs command] |
Arguments: since |
fi:eval-buffer-changed-definitions |
[Emacs command] |
Arguments: since |
fi:eval-changed-definitions |
[Emacs command] |
Arguments: since |
fi:compile-buffer-changed-definitions |
[Emacs command] |
Arguments: since |
fi:compile-changed-definitions |
[Emacs command] |
Arguments: since |
fi:copy-buffer-changed-definitions |
[Emacs command] |
Arguments: since |
fi:copy-changed-definitions |
[Emacs command] |
Arguments: 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:
motion in the stack: d goto to the next frame, making it `current'
u goto to the previous frame, making it `current'
. make frame on the line with the point `current'
The `current' frame is signified by the "->" indicator. All the
commands below operate on the current frame, the one with the "->" beside it. |
exiting commands: r return a value, read from the minibuffer and
evaluated in the Common Lisp environment
R restart execution, with a prefix argument with
a new functions and arguments
C-cC-c continue from the current error, which must be
continuable, and the default restart is chosen
(equivalent to ":continue 0")
C-cC-p Abandon this error and pop out to the top
level read-eval-print loop or a previous
debugger loop (equivalent to ":pop")
C-cC-r Abandon all debugger loops and reset to the
top level (equivalent to ":reset")
q quit scan stack mode
All of the "exiting" type commands leave scan stack mode and restore the
window configuration to what is was when this mode was entered. |
print auxiliary information: D disassemble the function associated with
a frame and position the buffer with the
return pc highlighted
l retrieve the local, or lexical, variables
associated with a frame. Local variable
information is dependent of the value of the
compiler switch compiler:save-local-names-switch
p pprint the function and actual arguments of a frame
All the above commands display their output in a buffer named *CL-temp*. |
miscellaneous: e edit the definition of the function associated
with a frame
h toggle the visibility of the help text, which
if visible, is at the beginning of the buffer
a toggle between hiding certain stack frames,
which are normally not useful in debugging,
and show all stack frames
g revert stack the stack from the Common Lisp
process from which the current stack was taken
|
Emacs functions for scanning the Common Lisp stack
fi:scan-stack |
[Emacs command] |
Arguments: &optional all |
- Invoke with M-x fi:scan-stack.
Debug a Common Lisp process, which is read, with completion, from the
minibuffer. The "Initial Lisp Listener" is the default process. The
debugging occurs on a stack scan, created by :zoom on the Common Lisp
process. With argument ALL, do a ":zoom :all t".
fi:scan-stack-mode |
[Emacs function] |
Arguments: &optional from-buffer process-name |
fi:scan-stack-mode-display-help |
[Emacs variable] |
Initial value: t |
fi:ss-continue |
[Emacs command] |
Arguments: nil |
fi:ss-disassemble |
[Emacs command] |
Arguments: nil |
fi:ss-edit |
[Emacs command] |
Arguments: nil |
fi:ss-hide-help-text |
[Emacs command] |
Arguments: nil |
fi:ss-locals |
[Emacs command] |
Arguments: nil |
fi:ss-next-frame |
[Emacs command] |
Arguments: nil |
- Invoke with M-x fi:ss-next-frame.
Go to the next frame.
fi:ss-pop |
[Emacs command] |
Arguments: nil |
fi:ss-pprint |
[Emacs command] |
Arguments: nil |
fi:ss-previous-frame |
[Emacs command] |
Arguments: nil |
fi:ss-quit |
[Emacs command] |
Arguments: nil |
fi:ss-reset |
[Emacs command] |
Arguments: nil |
fi:ss-restart |
[Emacs command] |
Arguments: new-form |
- Invoke with R in fi:scan-stack-mode.
Do a :restart on the process being debugged. This causes the process
being debugged to restart the execution of the function associated with the
current frame. With argument NEW-FORM, a form to evaluate to obtain the
function and arguments to be restarted is read from the minibuffer and
evaluated in the Common Lisp environment. The default function and
arguments are the ones in the current frame. The debugger buffer is
buried and the window configuration as it was before this mode was entered
is restored.
fi:ss-return |
[Emacs command] |
Arguments: nil |
- Invoke with r in fi:scan-stack-mode.
Do a :return on the process being debugged. This causes the process
being debugged to return a value from the current frame, as if the error
never occured. The form to evaluate to obtain the return value for the
current frame is read from the minibuffer and evaluated in the Common Lisp
environment. The debugger buffer is buried and the window configuration as
it was before this mode was entered is restored.
fi:ss-revert-stack |
[Emacs command] |
Arguments: nil |
fi:ss-toggle-all |
[Emacs command] |
Arguments: nil |
fi:ss-unhide-help-text |
[Emacs command] |
Arguments: nil |
Debugging with gdb
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 |
[Emacs command] |
Arguments: nil |
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:
:processes list all the Common Lisp processes and their state
:arrest stop a Common Lisp process
:focus make a process the focus of future stack
commands, such :zoom
:unarrest reverse the effect of arrest and focusing on a
process, allowing it to continue, if possible
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:
- the subprocess input ring helps to minimize typing during a debugging session.
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 commands fi:list-input-ring, fi:pop-input,
fi:push-input, fi:re-search-backward-input and fi:re-search-forward-input in Section 3.3
Functions and variables for Interacting with a CL subprocess.
- fi:list-buffer-definitions provides an easy method of scanning or visiting all the
definitions in a buffer. The result is a buffer in definition mode which gives a one-line
description of each definition. See fi:definition-mode for more information.
Finally, we end our discussion on debugging by mentioning a function which will allow
Franz Inc. to be sent a bug report with all the right information:
fi:bug-report |
[Emacs command] |
Arguments: nil |
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:
- support for rlogin, su, and telnet, including secure password entry for su and telnet
modes.
- command completion. See fi:shell-command-completion.
- file name completion. See fi:shell-file-name-completion. Note that
fi:shell-do-completion will do either command or filename completion.
- better tracking of directory changes (handles +N arguments to pushd and popd).
- input ring for yanking and searching for previously typed input. The subprocess input
ring helps to minimize typing. Previously typed input can be yanked to the prompt at the
end of a shell subprocess buffer. It can then be edited before sending it to the shell.
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 commands fi:list-input-ring,
fi:pop-input, fi:push-input, fi:re-search-backward-input and fi:re-search-forward-input.
- superkeys for convenience of typing `shell' specific characters at the end of a
subprocess buffer. There is a set of process-related functions that are needed in shell
mode buffers. Superkey key bindings have a special meaning at the end of the buffer, but
have their global meaning when typed anywhere else in the buffer. The superkey facility is
controlled by fi:subprocess-enable-superkeys. fi:superkey-shadow-universal-argument
controls how C-u behaves.
- An initial input string is sent automatically upon starting a remote shell. Sending a
string allows one to set the tty correctly. Symptoms of an incorrect tty setting include
spurious ^M characters and extra echoing of input. See fi:su-initial-input,
fi:telnet-initial-input and fi:rlogin-initial-input.
shell mode
fi:shell |
[Emacs command] |
Arguments: &optional buffer-number |
- Invoke with M-x fi:shell.
Start a shell in a buffer whose name is determined from the optional
prefix argument BUFFER-NUMBER. Shell buffer names start with `*shell*'
and end with an optional "". If BUFFER-NUMBER is not given it defaults
to 1. If BUFFER-NUMBER is 1, then the trailing "<1>" is omited. If
BUFFER-NUMBER is < 0, then the first available buffer name is chosen (a
buffer with no process attached to it.
The shell image file and image arguments are taken from the variables
`fi:shell-image-name' and `fi:shell-image-arguments'.
fi:shell-command-completion |
[Emacs command] |
Arguments: nil |
fi:shell-do-completion |
[Emacs command] |
Arguments: nil |
fi:shell-file-name-completion |
[Emacs command] |
Arguments: nil |
fi:shell-image-arguments |
[Emacs variable] |
Initial value: ("-i") |
fi:shell-image-name |
[Emacs variable] |
Initial value: "csh" |
Default Shell image to invoke from (fi:shell). If the value
is a string then it names the image file or image path that
`fi:shell' invokes. Otherwise, the value of this variable is given
to funcall, the result of which should yield a string which is the image
name or path.
fi:shell-mode |
[Emacs command] |
Arguments: &optional mode-hook |
- Invoke with M-x fi:shell-mode.
Major mode for interacting with an inferior shell.
The keymap for this mode is bound to fi:shell-mode-map:
key binding
--- -------
C-c Prefix Command
RET fi:subprocess-send-input
C-c C-a fi:subprocess-beginning-of-line
C-c C-c fi:subprocess-interrupt
C-c C-d fi:subprocess-send-eof
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-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 C-y fi:pop-input
C-c C-z fi:subprocess-suspend
C-c C-\ fi:subprocess-quit
C-c = fi:shell-sync-current-working-directory
Entry to this mode runs the following hooks:
fi:subprocess-mode-hook
fi:shell-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:shell-mode-bang |
[Emacs command] |
Arguments: &optional arg |
- Invoke with M-x fi:shell-mode-bang.
Expand !$ in shell mode.
fi:shell-mode-use-history |
[Emacs variable] |
Initial value: nil |
fi:shell-prompt-pattern |
[Emacs variable] |
Initial value: "^[-_.a-zA-Z0-9]*[#$%>] *" |
fi:shell-sync-current-working-directory |
[Emacs command] |
Arguments: nil |
fi:shell-token-pattern |
[Emacs variable] |
Initial value: "[ \n()<>&|;=]" |
su mode
fi:su |
[Emacs command] |
Arguments: &optional buffer-number |
- Invoke with M-x fi:su.
Start an su in a buffer whose name is determined from the optional
prefix argument BUFFER-NUMBER. Su buffer names start with `*su*'
and end with an optional "". If BUFFER-NUMBER is not given it defaults
to 1. If BUFFER-NUMBER is 1, then the trailing "<1>" is omited. If
BUFFER-NUMBER is < 0, then the first available buffer name is chosen (a
buffer with no process attached to it.
fi:su-initial-input |
[Emacs variable] |
Initial value: "stty -echo nl tabs\n" |
fi:su-mode |
[Emacs command] |
Arguments: &optional mode-hook |
- Invoke with M-x fi:su-mode.
Major mode for interacting with an inferior su.
The keymap for this mode is bound to fi:su-mode-map:
key binding
--- -------
C-c Prefix Command
RET fi:subprocess-send-input
C-c C-a fi:subprocess-beginning-of-line
C-c C-c fi:subprocess-interrupt
C-c C-d fi:subprocess-send-eof
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-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 C-y fi:pop-input
C-c C-z fi:subprocess-suspend
C-c C-\ fi:subprocess-quit
C-c = fi:shell-sync-current-working-directory
Entry to this mode runs the following hooks:
fi:subprocess-mode-hook
fi:su-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:su-prompt-pattern |
[Emacs variable] |
Initial value: "^[-_.a-zA-Z0-9]*[#$%>] *" |
fi:remote-root-login |
[Emacs command] |
Arguments: &optional buffer-number host |
- Invoke with M-x fi:remote-root-login.
Start a remote root rlogin in a buffer whose name is determined from the
optional prefix argument BUFFER-NUMBER and the HOST. Remote root Rlogin
buffer names start with `*root-HOST*' and end with an optional "". If
BUFFER-NUMBER is not given it defaults to 1. If BUFFER-NUMBER is 1, then
the trailing "<1>" is omited. If BUFFER-NUMBER is < 0, then the first
available buffer name is chosen (a buffer with no process attached to it.
The host name is read from the minibuffer.
fi:remote-su-mode |
[Emacs command] |
Arguments: &optional mode-hook |
- Invoke with M-x fi:remote-su-mode.
Major mode for interacting with an remote inferior su.
The keymap for this mode is bound to fi:remote-su-mode-map:
key binding
--- -------
C-c Prefix Command
RET fi:subprocess-send-input
C-c C-a fi:subprocess-beginning-of-line
C-c C-c fi:rlogin-send-interrupt
C-c C-d fi:rlogin-send-eof
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-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 C-y fi:pop-input
C-c C-z fi:rlogin-send-stop
C-c C-\ fi:rlogin-send-quit
C-c = fi:shell-sync-current-working-directory
Entry to this mode runs the following hooks:
fi:subprocess-mode-hook
fi:rlogin-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.
telnet mode
fi:telnet |
[Emacs command] |
Arguments: &optional buffer-number host |
- Invoke with M-x fi:telnet.
Start an telnet in a buffer whose name is determined from the optional
prefix argument BUFFER-NUMBER and the HOST. Telnet buffer names start with
`*HOST*' and end with an optional "". If BUFFER-NUMBER is not given
it defaults to 1. If BUFFER-NUMBER is 1, then the trailing "<1>" is
omited. If BUFFER-NUMBER is < 0, then the first available buffer name is
chosen (a buffer with no process attached to it).
The host name is read from the minibuffer.
The telnet image file and image arguments are taken from the variables
`fi:telnet-image-name' and `fi:telnet-image-arguments'.
fi:telnet-mode |
[Emacs command] |
Arguments: &optional mode-hook |
- Invoke with M-x fi:telnet-mode.
Major mode for interacting with an inferior telnet.
The keymap for this mode is bound to fi:telnet-mode-map:
key binding
--- -------
C-c Prefix Command
RET fi:subprocess-send-input
C-c C-a fi:subprocess-beginning-of-line
C-c C-c fi:rlogin-send-interrupt
C-c C-d fi:rlogin-send-eof
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-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 C-y fi:pop-input
C-c C-z fi:rlogin-send-stop
C-c C-\ fi:rlogin-send-quit
C-c = fi:shell-sync-current-working-directory
C-c m fi:telnet-start-garbage-filter
Entry to this mode runs the following hooks:
fi:subprocess-mode-hook
fi:telnet-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:telnet-image-arguments |
[Emacs variable] |
Initial value: nil |
fi:telnet-image-name |
[Emacs variable] |
Initial value: "telnet" |
Default telnet image to invoke from FI:TELNET. If the value
is a string then it names the image file or image path that
FI:TELNET invokes. Otherwise, the value of this variable is given
to funcall, the result of which should yield a string which is the image
name or path.
fi:telnet-initial-input |
[Emacs variable] |
Initial value: "stty -echo nl\n" |
fi:telnet-prompt-pattern |
[Emacs variable] |
Initial value: "^[-_.a-zA-Z0-9]*[#$%>] *" |
fi:telnet-start-garbage-filter |
[Emacs command] |
Arguments: nil |
rlogin mode
fi:rlogin |
[Emacs command] |
Arguments: &optional buffer-number host user |
- Invoke with M-x fi:rlogin.
Start an rlogin in a buffer whose name is determined from the optional
prefix argument BUFFER-NUMBER and the HOST. Rlogin buffer names start with
`*HOST*' and end with an optional "". If BUFFER-NUMBER is not given
it defaults to 1. If BUFFER-NUMBER is 1, then the trailing "<1>" is
omited. If BUFFER-NUMBER is < 0, then the first available buffer name is
chosen (a buffer with no process attached to it.
The host name is read from the minibuffer.
The rlogin image file and image arguments are taken from the variables
`fi:rlogin-image-name' and `fi:rlogin-image-arguments'.
fi:rlogin-mode |
[Emacs command] |
Arguments: &optional mode-hook |
- Invoke with M-x fi:rlogin-mode.
Major mode for interacting with an inferior rlogin.
The keymap for this mode is bound to fi:rlogin-mode-map:
key binding
--- -------
C-c Prefix Command
RET fi:subprocess-send-input
C-c C-a fi:subprocess-beginning-of-line
C-c C-c fi:rlogin-send-interrupt
C-c C-d fi:rlogin-send-eof
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-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 C-y fi:pop-input
C-c C-z fi:rlogin-send-stop
C-c C-\ fi:rlogin-send-quit
C-c = fi:shell-sync-current-working-directory
Entry to this mode runs the following hooks:
fi:subprocess-mode-hook
fi:rlogin-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:rlogin-image-arguments |
[Emacs variable] |
Initial value: nil |
fi:rlogin-image-name |
[Emacs variable] |
Initial value: "rlogin" |
Default remote-login image to invoke from (fi:rlogin). If the value
is a string then it names the image file or image path that
`fi:rlogin' invokes. Otherwise, the value of this variable is given
to funcall, the result of which should yield a string which is the image
name or path.
fi:rlogin-initial-input |
[Emacs variable] |
Initial value: "stty -echo nl\n" |
fi:rlogin-prompt-pattern |
[Emacs variable] |
Initial value: "^[-_.a-zA-Z0-9]*[#$%>] *" |
fi:rlogin-send-eof |
[Emacs command] |
Arguments: nil |
fi:rlogin-send-interrupt |
[Emacs command] |
Arguments: nil |
fi:rlogin-send-quit |
[Emacs command] |
Arguments: nil |
fi:rlogin-send-stop |
[Emacs command] |
Arguments: nil |
This section and its subsections discuss advanced features of the Emacs-Lisp interface.
fi:define-emacs-lisp-mode |
[Emacs variable] |
Initial value: t |
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 install_lisp in a relatively
standard fashion. install_lisp is the program that installs Allegro CL. By `a relatively
standard fashion', we mean that the restart_function= command line argument to
install_lisp was not specified.
Problems starting the Emacs-Lisp interface can arise, however, when starting images:
- created with excl:dumplisp called with a restart function specified as the value of the
:restart-function keyword argument;
- created with excl:dumplisp called with a non-nil value specified for the
:ignore-command-line-arguments keyword argument;
- created by install_lisp with a value specified for the restart_function= command line
argument to install_lisp.
Note that cases (2) and (3) are really the same. install_lisp creates its image with
excl:dumplisp. install_lisp calls excl:dumplisp with :ignore-command-line-arguments nil in
all situations except when restart_function= is specified on the command line, in which
case :ignore-command-line-arguments is specified to be t.
Those cases cause problems because of how the Emacs-Lisp interface is started, as we
describe next.
How Emacs and Lisp rendezvous
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:
- fi:common-lisp invokes a Common Lisp subprocess with the arguments ``-e
(excl:start-emacs-lisp-interface t)'' followed by whatever other command-line arguments
there are.
- the buffer in which Common Lisp is run, *common-lisp* by default, has an Emacs Lisp
filter that looks for strings of the form ^A<...>^A, that is something surrounded by
^A's.
- when Common Lisp starts up, it evaluates the argument following the -e (actually it
reads from the command line argument string and then evaluates).
- excl:start-emacs-lisp-interface prints the information Emacs needs to rendezvous with
Lisp to *terminal-io*. This information is given to the Emacs Lisp process filter, in the
form ^A<...>^A.
- the process filter sees the ^A<...>^A and extracts the following information from
what appears in <...>:
- The internet port number
- the password (not yours -- generated by Lisp)
- the case mode of Common Lisp
- the host on which Common Lisp is running
- the ipc version
- the above information is used to setup the interface and establish a connection between
Lisp and Emacs.
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.
The problem with an image created with excl:dumplisp with a restart function is a bit
more subtle but essentially the same. Command line arguments are processed after the
restart function returns. However restart functions are (often) designed not to return
(they provide the interface to an application, e.g.) Therefore, specifying a restart
function prevents command line arguments from being processed.
Starting the interface directly with excl:start-emacs-lisp-interface
If, because command-line arguments are ignored or there is a restart function, 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:start-emacs-lisp-interface. We
remind you again that the image must have been started with fi:common-lisp for this to
work.
Usually Common Lisp allows input editing of expressions as they are typed in.
Borrowing a term from Unix, we call this the cooked mode. A Common Lisp program may need
to read characters as they are typed in, without newlines. We call this raw mode. Usually,
the Emacs-Lisp interface expects Common Lisp to be in cooked mode. To use the Emacs-Lisp
interface with a Common Lisp that is in raw mode, we provide the Lisp function
excl:get-terminal-characteristics and Emacs Lisp variables and functions.
Security and raw mode
To use a remote Common Lisp in raw mode with a local Emacs-Lisp interface, one must use
the Unix on command. The on command requires that the rexd daemon be turned on in
/etc/inetd.conf. The rexd daemon is a known potential security hole.
Note that it is possible to use a local Common Lisp in raw mode and a local Emacs-Lisp
interface without using on. That situation does not pose a security problem.
An example use:
(defun raw-read-char (&optional (stream *standard-input*) &rest args)
;; If this function is loaded into a Common Lisp started
;; under Emacs and via M-x fi:common-lisp, then the
;; before method on SET-TERMINAL-CHARACTERISTICS will set
;; commands to Emacs that will change the values of
;; fi:raw-mode and fi:raw-mode-echo appropriately. This
;; means that the READ-CHAR below will read one character
;; and *not* require a terminating newline character for
;; READ-CHAR to return, as is normally needed when not in
;; RAW or CBREAK mode (see ioctl(2) in the UNIX manual).
(excl:set-terminal-characteristics stream :input-processing :cbreak)
;; We use HANDLER-CASE instead of UNWIND-PROTECT here
;; because being in CBREAK mode and going into the debugger
;; would not be very friendly.
(prog1
(handler-case
(apply #'read-char stream args)
(error (c)
(format *terminal-io*
"error doing read-char from ~s: ~a"
stream c)))
(excl:set-terminal-characteristics stream :input-processing
:cooked)))
The following two variables deal with raw mode. The first tells you if you are in raw
mode. The second controls the echo behavior in raw mode.
fi:raw-mode |
[Emacs variable] |
Initial value: nil |
If non-nil, then the inferior lisp process gets characters as they are
typed, not when a complete expressions has been entered. This means that
no input editing of expressions can occur. The intention of this feature
is that it be used by programs written in Common Lisp that need to read
characters without newlines after them. See the example in the Allegro
User Guide for more information.
fi:raw-mode-echo |
[Emacs variable] |
Initial value: t |