File:  [CSRG BSD Unix] / 43BSDReno / contrib / emacs-18.55 / dist-1.3 / fi / spec.out
Revision 1.1: download - view: text, annotated - select for diffs
Tue Apr 24 16:12:57 2018 UTC (8 years, 1 month ago) by root
CVS tags: MAIN, HEAD
Initial revision

	      Franz Inc. GNU Emacs/Common Lisp Interface
			     Release 1.3

This document is a specification of the Franz Inc. GNU Emacs interface
to Common Lisp, which is written entirely in GNU Emacs Lisp (for GNU
Emacs version 18.50).

0. Concepts and Terminology

   In Emacs, each buffer has a `mode.'  A mode is a collection of key
and variable `bindings' which are specialized to a certain task.  When
the cursor is in a `buffer' and you depress a key, its action is
determined by the binding found in the `keymap' associated with that
buffer (the buffer-local keymap).  If there is no binding in the
buffer-local keymap, then the binding is sought on the `global' keymap.
Thus, a mode is usually implemented by creating a buffer-local keymap
and adding bindings to do specific tasks.  The result is that certain
keys act differently in the buffer but most keys act just as they do
in all the other buffers.  Usually the mode of a buffer is displayed
in parentheses at the bottom of the screen (in what is called the
`mode line').

   Two terms used interchangeably in this document are `subprocess' and
`inferior process'.  They both refer to the interaction between Emacs
and running program, and their names come from the fact that UNIX
processes are part of a hierarchical structure--each process has a
parent and some processes have children.  Here, Lisp is run as a child
of Emacs, or a subordinate process under Emacs.

   Most machines available today have a `network' interface.  There
are several `protocols' in use today, of which `TCP/IP' (Transmission
Control Protocol) is one.  TCP/IP is most commonly used for
communication between machines using `ethernet'--ethernet is the
hardware and TCP/IP is the software.  TCP/IP is available on Berkeley
UNIX and some other UNIX systems, and is a powerful tool for making
resources from a large number of machines easily available to all
users on the network.  The X window system, for example, uses TCP/IP
to communicate between clients and server.

   In order for Emacs and Lisp to communicate, Lisp must accept
messages sent to a certain address and Emacs must know that address.
There are two types of addressing available: internet and UNIX domain.
An internet address is a machine address and a port number.  A UNIX
domain address is a file name.  The advantage of an internet address
is that it can be accessed from any machine on the network because the
address contains the machine number.  The disadvantage is that only
one process (a Lisp process in our case) on a given machine can listen
for messages on a given internet address.  Thus, if you wanted to use
the Emacs to Lisp interface on a machine with many users, only one
user at a time could use it.  A UNIX domain address can only be used
from programs running on the same machine.  However the flexibility of
using file names in UNIX domain addresses allows the Emacs to Lisp
interface to choose unique addresses for each user running on a
machine.  The file name convention we use is this: when user `smith'
starts up Lisp, the UNIX domain address `~smith/.excl_to_emacs' is used
by Lisp.  When `smith' directs Emacs to connect to Lisp, it knows it
was started by smith and thus talks to address `~smith/.excl_to_emacs'.
Thus multiple users on a given machine can run the Emacs to Lisp
interface.

   The Emacs/Lisp interface in this document can use both of these
methods of communication, but the preferred method uses UNIX domain
sockets, because more than one person on a machine may use the
Lisp/Emacs interface.

1. Introduction

   The purpose of this package is to enhance the Lisp environment.  To
this end, GNU Emacs and Lisp have been tightly coupled, and in the
case of Allegro CL 3.0 the interface uses TCP/IP UNIX or internet
domain sockets.  This interface can be broken down into three modes:

	* Common Lisp,
	* Inferior Common Lisp, and
	* TCP Common Lisp.

The first is for editing Lisp programs, the second for starting up a
Lisp subprocess under Emacs, and the third for TCP/IP communication
between Emacs and Lisp.

   While editing Lisp source code, there are commands that make it
easy to send expressions to, and receive information from, a Lisp
process.  For example: a function can be sent to Lisp from a source
buffer, a form in a source buffer can be macroexpanded, and
source for functions defined by loading files into Lisp may be located
automatically.

   For many of the bindings set up in the editing modes to be useful,
there must be a Lisp to which Emacs can communicate.  In this area the
interface can be broken down into three parts: an enhanced mode for
running an inferior Lisp process in an Emacs buffer, a new mode that
creates an Emacs buffer onto an existing Lisp process via a TCP/IP
socket, and mechanisms to query the Lisp environment for information
which can be used in the Emacs environment (also using TCP/IP
sockets).

   Running an inferior Lisp in an Emacs buffer is not new--Emacs
supports this `off the shelf.'  This feature allows users to interact
directly with Lisp while editing Lisp source code.  Although the
existing inferior Lisp mode has been enhanced and a new mode added to
support socket connections to Lisp, the most significant contribution of
this package is in offering tighter coupling of the Lisp and Emacs
environments and in providing better subprocess management tools.

   By taking advantage of Lisp multiprocessing, an Emacs buffer can be
opened onto a Lisp not started as a subprocess of Emacs.  This
connection uses TCP/IP sockets (UNIX or internet domain), which in turn
means that Emacs can talk to a Lisp running on any machine on the
network.  Sockets and multiprocessing also mean that one can establish
more than one connection between Lisp and Emacs.

   These socket connections to Lisp are the key to the integration of
the two environments.  Emacs uses a `back door' connection to exchange
information with a Lisp process.  Users can obtain information about
Lisp function argument lists and symbol documentation, macroexpand Lisp
forms, and locate source definitions of Lisp symbols (which are recorded
by Lisp when a symbol is defined, usually by loading a file).  All these
features are accessible with a few key-strokes.

   Aside from the Lisp interface proper, this package provides useful
features for subprocess manipulation, including an input ring for
handy retrieval of previously-typed input, filename completion,
special handling of certain subprocess-specific keys (e.g., ^C or ^D),
and continuously showing output from a subprocess in a visible buffer.

2. Editing Lisp

   This package modifies `auto-mode-alist' so that the major modes
defined in this package are invoked when certain types of source files
are edited.  The list of filename extensions given by the value of
`fi:common-lisp-file-types' cause `fi:common-lisp-mode' to be invoked
whenever a file with one of these types is visited.  The important
actions done by Common Lisp mode are (in order):

	1. set up local variables specific to the mode;
	2. check for package information;
	3. set up keymaps; and
	4. call hooks.

The above functions are enhancements to the standard available GNU
Emacs Lisp mode.

   The major mode function for Common Lisp is called
`fi:common-lisp-mode', and this function can be interactively called
to put a buffer in Common Lisp mode.

fi:common-lisp-file-types...........................................[variable]
   Value: (".cl" ".lisp" ".lsp")
   A list of the files which are automatically put in fi:common-lisp-mode.
This variable should be set before this package is loaded.



2.1 Bindings

   The key bindings for Common Lisp mode are set up only once, the
first time the mode is entered, and are taken from the variable
`fi:common-lisp-mode-map'.  Users wanting to change the bindings could
explicitly set this variable or augment the map from within the hooks
for the mode.

   The initial local bindings for Common Lisp mode are:

fi:common-lisp-mode-map...............................................[keymap]
   Major mode map used when editing Common Lisp source.

C-c             Prefix Command
RET             fi:lisp-reindent-newline-indent
DEL             backward-delete-char-untabify
TAB             lisp-indent-line
C-x             Prefix Command
ESC             Prefix Command

C-c C-r         fi:lisp-eval-region
C-c C-s         fi:lisp-eval-last-sexp
C-c C-b         fi:lisp-eval-current-buffer

ESC C-x         fi:lisp-eval-defun
ESC W           fi:lisp-walk
ESC M           fi:lisp-macroexpand
ESC F           fi:lisp-function-documentation
ESC D           fi:lisp-describe
ESC C           fi:lisp-who-calls
ESC A           fi:lisp-arglist
ESC TAB         fi:lisp-complete-symbol
ESC ,           fi:lisp-tags-loop-continue
ESC .           fi:lisp-find-tag
ESC C-q         indent-sexp




2.2 Variables

   All local variables are killed when Common Lisp mode is
entered--this is a convention to insure that there are no name
conflicts with user variables.

   To correctly deal with the Common Lisp package system, Emacs must
know the package for each file, so that it may use this when sending
expressions from a buffer to Lisp.  There is a buffer-local variable
which contains the name of the package:

fi:package..........................................................[variable]
   Value: "user"
   A buffer-local variable whose value should either 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.



There are three ways to automatically set this variable (the first and
third items here are standard GNU Emacs features):

  1. If the first line in the file contains text surrounded by -*-,
     the `package' field of this line is parsed for the package name.
     For example,

		;; -*- mode: common-lisp; package: excl -*-

     would put the file in package `excl'.

  2. If the above attempt fails, then the buffer is searched for an
     `in-package' form, which is parsed for the package name.

  3. Lastly, the values obtained in one of the first two locations can
     be over-written by manually setting fi:package in the local
     variables list.  For example, the following at the end of the
     file will override any value given previously given to
     fi:package:

	^L
	;; Local Variables:
	;; eval: (setq fi:package "excl")
	;; End:

     Note that the normal method for setting a variable will not work,
     because `fi:package' contains a `:' and this confuses GNU
     Emacs, hence the use of `eval'.

If Emacs cannot determine the package, then it is assumed to be
"user" (the initial Common Lisp package).

2.3 Functions

   The following functions are either bound to keys in Common Lisp
mode or are available as extended commands:

fi:lisp-reindent-newline-indent.....................................[function]
   Invoke with: RET in Common Lisp mode.
   Indent the current line, insert a newline and indent to the proper
column.


fi:lisp-eval-region.................................................[function]
   Invoke with: C-c C-r in Common Lisp mode.
   Send the text in the region to the Lisp subprocess associated with this
buffer, one expression at a time if there is more than one complete
expression.  If a Lisp subprocess has not been started, then one is
started.  With a prefix argument, the source sent to the subprocess is
compiled.


fi:lisp-eval-last-sexp..............................................[function]
   Invoke with: C-c C-s in Common Lisp mode.
   Send the sexp before the point to the Lisp subprocess associated with
this buffer.  If a Lisp subprocess has not been started, then one is
started.  With a prefix argument, the source sent to the subprocess is
compiled.


fi:lisp-eval-current-buffer.........................................[function]
   Invoke with: C-c C-b in Common Lisp mode.
   Send the entire buffer to the Lisp subprocess associated with this
buffer.  If a Lisp subprocess has not been started, then one is started.
With a prefix argument, the source sent to the subprocess is compiled.


fi:lisp-eval-defun..................................................[function]
   Invoke with: ESC C-x in Common Lisp mode.
   Send the current top-level (or nearest previous) form to the Lisp
subprocess associated with this buffer.  A `top-level' form is one that
starts in column 1.  If a Lisp subprocess has not been started, then one is
started.  With a prefix argument, the source sent to the subprocess is
compiled.


fi:remove-all-temporary-lisp-transaction-files......................[function]
   This function will clean up all the files created for Lisp/Emacs
communication.  See the variable fi:emacs-to-lisp-transaction-directory for
the location of the files.



   The following functions are bound to keys in Common Lisp mode, and
require the TCP/IP communication channel to Lisp:

fi:lisp-find-tag....................................................[function]
   Invoke with: ESC . in Common Lisp mode.
   Find the Common Lisp source for a symbol, using the characters around
the point as the default tag.


fi:lisp-tags-loop-continue..........................................[function]
   Invoke with: ESC , in Common Lisp mode.
   Find the next occurrence of the tag last used by fi:lisp-find-tag.


fi:lisp-arglist.....................................................[function]
   Invoke with: ESC A in Common Lisp mode.
   Print the arglist (using excl:arglist) for a symbol, which is read from
the minibuffer.  The word around the point is used as the default.


fi:lisp-describe....................................................[function]
   Invoke with: ESC D in Common Lisp mode.
   Describe a symbol, which is read from the minibuffer.  The word around
the point is used as the default.


fi:lisp-function-documentation......................................[function]
   Invoke with: ESC F in Common Lisp mode.
   Print the function documentation for a symbol, which is read from the
minibuffer.  The word around the point is used as the default.


fi:lisp-macroexpand.................................................[function]
   Invoke with: ESC M in Common Lisp mode.
   Print the macroexpansion of the form at the point.


fi:lisp-walk........................................................[function]
   Invoke with: ESC W in Common Lisp mode.
   Print the full macroexpansion the form at the point.
With a prefix argument, macroexpand the code as the compiler would.


fi:lisp-who-calls...................................................[function]
   Invoke with: ESC C in Common Lisp mode.
   Print all the callers of a function.  The default symbol name is taken
from the sexp around the point.


fi:lisp-complete-symbol.............................................[function]
   Invoke with: ESC TAB in 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, to which there
is a TCP/IP connection (see fi:eval-in-lisp).  If the symbol starts just
after an open-parenthesis, then only symbols (in the Common Lisp) with
function defintions are considered.  Otherwise all symbols are considered.



fi:set-associated-sublisp...........................................[function]
   When evaluated in a Lisp source buffer causes further `eval'
commands (those which send expressions from Emacs to Lisp) to use
BUFFER-NAME as the buffer which contains a Lisp subprocess.  If evaluated
when not in a Lisp source buffer, then the process type is read from the
minibuffer ("common-lisp" or "franz-lisp").  The buffer name is
interactively read and must be the name of an existing buffer.  New buffers
with the same mode as the current buffer will also use BUFFER-NAME for
future `eval' commands.



2.3 Hooks

   The hooks run for Common Lisp mode are fi:lisp-mode-hook and
fi:common-lisp-mode-hook.  The form of the hook function is determined
by `run-hooks', which is used to process the hooks.  Hooks are run
last during mode initialization.  For example, the following hook
enables auto-fill in Common Lisp mode:

    (setq fi:lisp-mode-hook
      '(lambda ()
	(define-key (current-local-map) "\t" 'lisp-indent-line)
	(setq fill-column 75)
	(auto-fill-mode 1)))

3. Running Lisp

   What follows is a discussion of the bindings, variables and
functions allowing the user to interact with and manipulate a Lisp run
as an inferior to Emacs.  A discussion on how to start up and use the
interface is discussed in the next section.


3.1 Bindings

   The initial local bindings for Inferior Common Lisp mode are:

fi:inferior-common-lisp-mode-map......................................[keymap]
   The inferior-common-lisp major-mode keymap.

DEL             backward-delete-char-untabify
TAB             lisp-indent-line
C-x             Prefix Command
ESC             Prefix Command
C-c             Prefix Command
RET             fi:inferior-lisp-newline

C-c C-\         fi:subprocess-quit
C-c C-d         fi:subprocess-send-eof
C-c C-c         fi:subprocess-interrupt
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-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-o         fi:subprocess-send-flush
C-c C-n         fi:push-input
C-c RET         fi:subprocess-input-region
C-c C-l         fi:list-input-ring
C-c C-k         fi:subprocess-kill-output
C-c C-a         fi:subprocess-beginning-of-line

C-x RET         fi:inferior-lisp-input-list

ESC W           fi:lisp-walk
ESC M           fi:lisp-macroexpand
ESC F           fi:lisp-function-documentation
ESC D           fi:lisp-describe
ESC C           fi:lisp-who-calls
ESC A           fi:lisp-arglist
ESC TAB         fi:lisp-complete-symbol
ESC ,           fi:lisp-tags-loop-continue
ESC .           fi:lisp-find-tag
ESC RET         fi:inferior-lisp-input-sexp
ESC C-q         indent-sexp




and for the TCP Common Lisp mode:

fi:tcp-common-lisp-mode-map...........................................[keymap]
   The tcp-lisp major-mode keymap.

DEL             backward-delete-char-untabify
TAB             lisp-indent-line
C-x             Prefix Command
ESC             Prefix Command
C-c             Prefix Command
RET             fi:inferior-lisp-newline

C-c C-\         fi:tcp-lisp-kill-process
C-c C-d         fi:tcp-lisp-send-eof
C-c C-c         fi:tcp-lisp-interrupt-process
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-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-o         fi:subprocess-send-flush
C-c C-n         fi:push-input
C-c RET         fi:subprocess-input-region
C-c C-l         fi:list-input-ring
C-c C-k         fi:subprocess-kill-output
C-c C-a         fi:subprocess-beginning-of-line

C-x RET         fi:inferior-lisp-input-list

ESC W           fi:lisp-walk
ESC M           fi:lisp-macroexpand
ESC F           fi:lisp-function-documentation
ESC D           fi:lisp-describe
ESC C           fi:lisp-who-calls
ESC A           fi:lisp-arglist
ESC TAB         fi:lisp-complete-symbol
ESC ,           fi:lisp-tags-loop-continue
ESC .           fi:lisp-find-tag
ESC RET         fi:inferior-lisp-input-sexp
ESC C-q         indent-sexp




   Superkeys are keys that are handled specially at the end of a
buffer.  At the end of a buffer it has a buffer-specific meaning, but
anywhere else in the buffer it has the normal global meaning (obtained
by looking the key up in the global keymap).  This way, ^D can send an
EOF to the Lisp process at the end of a buffer but invoke delete-char
("delete character") anywhere else.
 
   The values of `fi:inferior-common-lisp-mode-super-key-map' and
`fi:tcp-common-lisp-mode-super-key-map' are used as superkey maps for
Inferior Common Lisp and TCP Common Lisp modes.
   
   Superkeys are turned off by default.

3.2 Variables

   The name of the Common Lisp image to activate for an inferior Lisp
is taken from the following variables:

fi:common-lisp-image-name...........................................[variable]
   Value: "cl"
   *Default Common Lisp image to invoke from `fi:common-lisp'.  If the
value is a string then it names the image file or image path that
`fi:common-lisp' 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.



   After the image name as been determined and the process has been
started, a file in the user's home directory called .emacs_<IMAGE>,
where <IMAGE> is the image name, is fed to the newly created process.
This could be used to customize a initialization file on the name of
the Lisp binary.

   The command-line arguments passed to the activated image are taken
from the following variables:

fi:common-lisp-image-arguments......................................[variable]
   Value: nil
   *Default Common Lisp image arguments when invoked from `fi:common-lisp',
which must be a list of strings.



   The prompt pattern for the inferior Lisp is taken from a variable
with the name `fi:<IMAGE>-prompt-pattern' or from the following:

fi:common-lisp-prompt-pattern.......................................[variable]
   Value: "^\\(\\[[0-9]+c?\\] \\|\\[step\\] \\)?<[-A-Za-z]* ?[0-9]*?> "
   *The regular expression which matches the Common Lisp prompt, used in
Inferior Common Lisp mode.  Anything from beginning of line up to the end
of what this pattern matches is deemed to be a prompt.


fi:common-lisp-package-regexp.......................................[variable]
   Value: "(in-package\\>\\|:\\<pa\\>\\|:\\<pac\\>\\|:\\<pack\\>\\|:\\<packa\\>\\|:\\<packag\\>\\|:\\<package\\>"
   *The regular expression matching the Common Lisp expression(s) to change
packages.  If nil, no automatic package tracking will be done.



   The following variables are used in TCP Common Lisp mode:

fi:unix-domain......................................................[variable]
   Value: t
   *If non-nil, then `fi:unix-domain-socket' specifies the name of the
socket file.  It is recommended that this interface be used, and not
internet ports, because when internet ports are used only one process on a
machine may use this interface (it is a global resource).  When using UNIX
domain sockets, communication is done through a socket file in the user's
home directory.  But, if you really want to use internet ports, here are
the steps to take:

1. Set this variable to nil.
2. Add the following line to /etc/services:
	excl		6789/tcp
3. Make sure `fi:local-host-name' is in /etc/hosts and points to the local
or loopback host.
4. On the Common Lisp side, put the following in you .clinit.cl file:
	(setq ipc:*inet-port* 6789) 	; the number from /etc/services
	(setq ipc:*unix-domain* nil)

The problem with this, is that people can then use `telnet' to get a
listener on your lisp!


fi:unix-domain-socket...............................................[variable]
   Value: "~/.excl_to_emacs"
   *The name of the socket file that lisp and emacs use to communicate.
This is used when fi:unix-domain is non-nil.


fi:excl-service-name................................................[variable]
   Value: "excl"
   *The service name from /etc/services (`tcp' type).  This is only used
when fi:unix-domain is nil.


fi:local-host-name..................................................[variable]
   Value: "localhost"
   *On 4.2 BSD the name of 127.1--usually localhost or loopback.
This is only used when fi:unix-domain is nil.


fi:source-info-not-found-hook.......................................[variable]
   Value: find-tag
   *The value of this variable is funcalled when source information is not
present in Lisp for a symbol.  The function is given one argument, the name
for which source is desired (a string).  The null string means use the word
at the point as the search word.  This allows the GNU Emacs tags facility
to be used when the information is not present in Lisp.



plus the following miscellaneous variables:

fi:echo-evals-from-buffer-in-listener-p.............................[variable]
   Value: nil
   *If non-NIL, forms evalutated directly from a lisp buffer by the
fi:lisp-eval-* functions will be echoed by the lisp listener.


fi:emacs-to-lisp-transaction-directory..............................[variable]
   Value: "/tmp"
   *The directory in which files for Emacs/Lisp communication are stored.
When using Lisp and Emacs on different machines, this directory should be
accessible on both machine with the same pathname (via the wonders of NFS).


fi:subprocess-enable-superkeys......................................[variable]
   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:pop-to-sublisp-buffer-after-lisp-eval............................[variable]
   Value: t
   *If non-nil, then after sending expressions to a Lisp process do pop to
the buffer which contains the Lisp.


fi:display-buffer-function..........................................[variable]
   Value: switch-to-buffer
   *If non-nil, then it is used as the function which is funcall'd with one
argument, a buffer, to display a subprocess buffer when it is created (ie,
from `fi:common-lisp').


fi:lisp-evalserver-timeout..........................................[variable]
   Value: 5
   The time which fi:eval-in-lisp will wait before timing out and
signalling an error.  Without a timeout Emacs would potentially be locked
out if Lisp did not `return' a result.


fi:lisp-evalserver-number-reads.....................................[variable]
   Value: 20
   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.



   The following are miscellaneous subprocess variables:

fi:default-input-ring-max...........................................[variable]
   Value: 50
   *The default maximum length to which an input ring is allowed to grow.


fi:shell-token-pattern..............................................[variable]
   Value: "[ 	
()<>&|;=]"
   *The regular expression used by file name completion to mark path name
boundaries.


fi:subprocess-continuously-show-output-in-visible-buffer............[variable]
   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.



   The following three variables are used to track the shell commands
which change the current working directory.  For Common Lisp, the
aliases in Appendix A together with these variables will allow Common
Lisp to emulate the shell commands and for Emacs to track them:

fi:shell-cd-regexp..................................................[variable]
   Value: ":?cd"
   *The regular expression matching the C shell `cd' command.  If nil,
no automatic directory changes will be made.


fi:shell-popd-regexp................................................[variable]
   Value: ":?popd"
   *The regular expression matching the C shell `popd' command.  If nil, no
automatic directory changes will be made.


fi:shell-pushd-regexp...............................................[variable]
   Value: ":?pushd"
   *The regular expression matching the C shell `pushd' command.  If nil,
no automatic directory changes will be made.



3.3 Functions

fi:common-lisp......................................................[function]
   Start a Common Lisp subprocess in a buffer whose name is determined
from the optional prefix argument BUFFER-NUMBER.  Common Lisp buffer names
start with `*common-lisp' and end with `*', with an optional `-N' in
between.  If BUFFER-NUMBER is not given it defaults to 1.  If BUFFER-NUMBER
is >= 0, then the buffer is named `*common-lisp-<BUFFER-NUMBER>*'.  If
BUFFER-NUMBER is < 0, then the first available buffer name is chosen.

The image file and image arguments are taken from the variables
`fi:common-lisp-image-name' and `fi:common-lisp-image-arguments'.

See fi:explicit-common-lisp.


fi:explicit-common-lisp.............................................[function]
   The same as fi:common-lisp, except that the image and image arguments
are read from the minibuffer.


fi:remote-common-lisp...............................................[function]
   Start a Common Lisp subprocess in a buffer whose name is determined
from the optional prefix argument BUFFER-NUMBER, where the Common Lisp
image is run on another machine.  Common Lisp buffer names start with
`*common-lisp' and end with `*', with an optional `-N' in between.  If
BUFFER-NUMBER is not given it defaults to 1.  If BUFFER-NUMBER is >= 0,
then the buffer is named `*common-lisp-<BUFFER-NUMBER>*'.  If BUFFER-NUMBER
is < 0, then the first available buffer name is chosen.

The host on which the image is run is read from the minibuffer.

The image file and image arguments are taken from the variables
`fi:common-lisp-image-name' and `fi:common-lisp-image-arguments'.

See fi:explicit-remote-common-lisp.


fi:explicit-remote-common-lisp......................................[function]
   The same as fi:remote-common-lisp, except that the image and image
arguments are read from the minibuffer.


fi:tcp-common-lisp..................................................[function]
   In a buffer whose name is determined from the optional prefix argument
BUFFER-NAME, connect to a Common Lisp using either a UNIX domain socket
file or internet port number.  Common Lisp buffer names start with
`*common-lisp' and end with `*', with an optional `-N' in between.  If
BUFFER-NUMBER is not given it defaults to 1.  If BUFFER-NUMBER is >= 0,then
the buffer is named `*common-lisp-<BUFFER-NUMBER>*'.  If BUFFER-NUMBER is <
0, then the first available buffer name is chosen.

See `fi:unix-domain' and `fi:explicit-tcp-common-lisp'.


fi:explicit-tcp-common-lisp.........................................[function]
   The same as fi:tcp-common-lisp, except that the host name a port number
are read from the minibuffer.  Use a port number of 0 for UNIX domain
sockets.



fi:inferior-lisp-newline............................................[function]
   Invoke with: RET in Inferior Common Lisp mode.
   Bound to RET in an inferior Lisp buffer.  At the end of the buffer it
inserts a newline and performs automatic indentation.  Whole expressions
are sent to Lisp (not each piece after each newline is typed).  This allows
previously typed lines to be edited before Lisp is sent the input.  Typed
anywhere else in the buffer, this functions causes the input previously
typed (around the point) to be copied to the end of the subprocess buffer
and send to Lisp.


fi:inferior-lisp-input-sexp.........................................[function]
   Invoke with: ESC RET in Inferior Common Lisp mode.
   Send the sexp on which the point resides to the Lisp subprocess.  With a
numeric prefix argument, send that many sexps.


fi:inferior-lisp-input-list.........................................[function]
   Invoke with: C-x RET in Inferior Common Lisp mode.
   Send the list before the point to the Lisp subprocess.  With a numeric
prefix argument, send that many lists.


fi:subprocess-input-region..........................................[function]
   Invoke with: C-c RET in Inferior Common Lisp mode.
   Send the region defined by the point and mark to the Lisp subprocess.


fi:subprocess-kill-input............................................[function]
   Invoke with: C-c C-u in Inferior Common Lisp mode.
   Kill all input since the last output by the subprocess.


fi:subprocess-beginning-of-line.....................................[function]
   Invoke with: C-c C-a in Inferior Common Lisp mode.
   Moves point to beginning of line, just like (beginning-of-line),
except that if the pattern at the beginning of the line matches the
current subprocess prompt pattern, this function skips over it.


fi:subprocess-backward-kill-word....................................[function]
   Invoke with: C-c C-w in Inferior Common Lisp mode.
   Kill previous word in current subprocess input line.  This function
takes care not to delete past most recent subprocess output.


fi:subprocess-kill-output...........................................[function]
   Invoke with: C-c C-k in Inferior Common Lisp mode.
   Kill all output from the subprocess since the last input.


fi:subprocess-quit..................................................[function]
   Invoke with: C-c C-\ in Inferior Common Lisp mode.
   Send a quit signal to the subprocess.


fi:subprocess-send-flush............................................[function]
   Invoke with: C-c C-o in Inferior Common Lisp mode.
   Send the `flush output' character (^O) to subprocess.


fi:subprocess-show-output...........................................[function]
   Invoke with: C-c C-v in Inferior Common Lisp mode.
   Display the start of this batch of shell output at top of window.
Also move the point there.


fi:subprocess-suspend...............................................[function]
   Suspend, with a SIGSTOP, the current subprocess.



   The following three functions are used in fi:inferior-lisp-mode to
interrupt, kill or input an end-of-file to the Lisp process:

fi:subprocess-interrupt.............................................[function]
   Invoke with: C-c C-c in Inferior Common Lisp mode.
   Interrupt the current subprocess.


fi:subprocess-kill..................................................[function]
   Send a `kill' (SIGKILL) signal to the current subprocess.


fi:subprocess-send-eof..............................................[function]
   Invoke with: C-c C-d in Inferior Common Lisp mode.
   Send an end of file to the subprocess.



   The following three functions are used in fi:tcp-common-lisp-mode to
interrupt, kill and input an end-of-file to the Lisp process at the
other end of the TCP/IP socket:

fi:tcp-lisp-interrupt-process.......................................[function]
   Invoke with: C-c C-c in TCP Common Lisp mode.
   Interrupt the tcp-lisp process via a mp:process-interrupt spoken to the
backdoor Common Lisp listener.


fi:tcp-lisp-kill-process............................................[function]
   Invoke with: C-c C-\ in TCP Common Lisp mode.
   Kill a tcp-lisp process via a mp:process-kill spoken to the backdoor
Common Lisp listener.


fi:tcp-lisp-send-eof................................................[function]
   Invoke with: C-c C-d in TCP Common Lisp mode.
   Simulate an EOF on the tcp-lisp process via a db:debug-pop spoken to the
backdoor Common Lisp listener.



   All input typed to a subprocess buffer is saved in a ring.  The
following functions retrieve input and manipulate the ring:

fi:pop-input........................................................[function]
   Invoke with: C-c C-p in Inferior Common Lisp mode.
   Yank previous text from input ring.  Cycle through input ring with each
successive invocation.


fi:push-input.......................................................[function]
   Invoke with: C-c C-n in Inferior Common Lisp mode.
   Yank next text from input ring.  Cycle through input ring in reverse
order with each successive invocation.


fi:list-input-ring..................................................[function]
   Invoke with: C-c C-l in Inferior Common Lisp mode.
   Display contents of input ring, starting at arg.  The list is displayed
in reverse order if called from a program and the optional second parameter
is non-nil.


fi:re-search-backward-input.........................................[function]
   Invoke with: C-c C-r in Inferior Common Lisp mode.
   Search in input ring for text that contains regexp and yank.


fi:re-search-forward-input..........................................[function]
   Invoke with: C-c C-s in Inferior Common Lisp mode.
   Search in input ring for text that contains regexp and yank.



plus the following miscellaneous function:

fi:eval-in-lisp.....................................................[function]
   Apply format (in Emacs) to STRING and ARGS and evaluate the result
in the Common Lisp to which we are connected.  If a lisp-eval-server has
not been started, then this function starts it.



3.4 Hooks

   The hooks run at the end of Inferior Common Lisp mode
initialization are:

	fi:lisp-mode-hook
	fi:subprocess-mode-hook
	fi:inferior-common-lisp-mode-hook

and for TCP Common Lisp mode are:

	fi:lisp-mode-hook
	fi:subprocess-mode-hook
	fi:tcp-common-lisp-mode-hook

4. Starting the Interface

   The two parts of the (full) interface which require user setup are:

	* running Lisp as an inferior of Emacs, with a "Lisp
	  listener daemon" listening for connections from Emacs
	* a set of Emacs bindings that query Lisp for information
	
In this sections the setup of these features will be discussed.

4.1 Setup

   (After the installation procedure has been followed (see the file
INSTALL in the main distribution directory) the interface will be in a
subdirectory of the `lisp' directory.  Typically the location is
/usr/local/lib/emacs, which is the pathname used throughout the rest
of this document.)

   The Lisp part of the interface consists of a Lisp process called
the "Lisp listener daemon" which lies dormant until Emacs tries to
communicate with it.  When Emacs "connects" an interactive top level
is started (called a "read-eval-print" loop) to which Emacs can send
expressions for evaluation and from which Emacs receives the results
of evaluation (see fi:eval-in-lisp).  The preferred method to start
this daemon is to put the following in your .login file:

	setenv EMACSLIBRARY /usr/local/lib/emacs

and to put the following in your .clinit.cl file in your home directory:

	(defparameter *emacs-library*
	  (let ((emacs-lib (si:getenv "EMACSLIBRARY")))
	    (if emacs-lib (format nil "~a/lisp/fi/" emacs-lib))))

	(and *emacs-library*
	     (find "+ipc" (system:command-line-arguments) :test #'string=)
	     (load (merge-pathnames "clinit.cl" *emacs-library*))
	     (load-and-start-ipc-package))

and to put the following in your .emacs file in your home directory:

	(load "fi/site-init.el")

	(setq fi:common-lisp-image-arguments '("+ipc"))

	(setq fi:unix-domain-socket
	  (format "/tmp/%s_emacs_to_acl" (user-login-name)))

Now consider the following typed to Emacs:

	M-x fi:common-lisp RET

This will cause a Common Lisp (the default image name is `cl') to be
started in a buffer called `*common-lisp*', as an inferior process of
Emacs.  This Common Lisp will be passed a command line argument of
`+ipc', which will cause Common Lisp to load and start the Lisp
listener daemon.  Emacs and Common Lisp will communicate through a
UNIX domain socket (a file) in /tmp called `USER_emacs_to_acl', where
USER is the currently-logged-in-user's name.  All of the bindings and
functions described above are now available.


4.2 Examples

   After fi:common-lisp has started a Common Lisp and all the above
modifications to .emacs and .clinit.cl have been made, the following
Emacs command will open a second buffer onto the same Lisp.  This
listener is a separate Common Lisp process (as opposed to a separate
Operating System process) and the entire Common Lisp environment
available in the first listener is available in this one:

	M-x fi:tcp-common-lisp RET

To run a second Common Lisp and get a completely fresh Common Lisp:

	C-u 2 M-x fi:common-lisp RET

The former uses one Common Lisp for multiple purposes (compiling a
program in one buffer while typing forms to another), while the latter
starts two separate Common Lisp processes, and thus uses twice the
memory and swap space.


4.2.1 Remote Common Lisps using TCP/IP

   It is possible, with the functions and bindings in this interface,
to run an Emacs and Common Lisp on two different machines.  For
example, to run Emacs on a machine called `snooze' and Common Lisp on
one called `akbar', where both machines are accessible on the network,
~/.emacs on `snooze' would contain:

	(setq fi:unix-domain nil)
	(setq fi:local-host-name "akbar")	; the remote host name

and ~/.clinit.cl on `akbar' would contain the forms given in section
4.1 with the call to load-and-start-ipc-package replaced with:

	(load-and-start-ipc-package :unix-domain nil)

Then, make sure the value of ipc::*inet-port* in ipc.cl and
fi:excl-service-name in tcplisp.el (all in the lisp/fi directory)
match what is in /etc/services.  For the interface as distributed, put
the following line in /etc/services:

	excl		6789/tcp

on both `akbar' and `snooze'.

Then, on `akbar', possibly in a shell buffer remotely logged into
`akbar', startup Common Lisp with the +ipc argument:

	akbar% cl +ipc

(If you get the error "bind: Address already in use" then the port
number you chose is already being used by another program.  In this
case, use something other than 6789 (in the default case) or the one
currently being used.)  Then, on `snooze' do:

	M-x fi:tcp-common-lisp RET

which will open a connection to the Lisp on `akbar' from `snooze'.


4.2.2 Remote Common Lisps using `rsh'

   It is also possible to run Common Lisp on another machine using
`rsh'.  For example, typing the following to Emacs will start a Lisp
process on host `akbar' without using the TCP/IP connection between
Common Lisp and Emacs:

	M-x fi:remote-common-lisp RET akbar RET

NOTE: fi:remote-common-lisp uses fi:common-lisp-image-name to
determine which image to activate.  If the image name is incorrect for
the remote machine, then use fi:explicit-remote-common-lisp.

			      Appendix A
			    Sample .emacs

;;				-[Fri Nov 18 18:53:13 1988 by layer]-
;; Sample .emacs file
;;
;; $Header: /var/lib/cvsd/repos/CSRG/43BSDReno/contrib/emacs-18.55/dist-1.3/fi/spec.out,v 1.1 2018/04/24 16:12:57 root Exp $

(load "fi/site-init.el")

;; use a socket file in /tmp since can't communicate via files on NFS
;; mounted file systems
;;
(setq fi:unix-domain-socket
  (format "/tmp/%s_emacs_to_acl" (user-login-name)))

;; turn on superkeys in subprocess modes
;;
(setq-default fi:subprocess-enable-superkeys t)

;; the following causes fi:common-lisp to give the inferior Common
;; Lisp, by default, a command line argument of `+ipc':
;;
(setq fi:common-lisp-image-arguments '("+ipc"))

;; the following causes fi:common-lisp to invoke the image `acl', but
;; to ask for an image name when given a prefix argument:
;;
(setq fi:common-lisp-image-name
  '(lambda ()
    (let ((image "acl"))
      (if current-prefix-arg
	  (setq image
	    (read-file-name (format "cl image (default: %s): " image)
			    default-directory image nil)))
      (setq mode-line-buffer-identification
	(format "%s (%s)" (buffer-name) (file-name-nondirectory image)))
      image)))

;; This redefines `kill-emacs' so that transaction files in /tmp are
;; removed emacs is killed:
;;
(fset 'old-kill-emacs (symbol-function 'kill-emacs))
(defun kill-emacs (&optional arg)
  (interactive "P")
  (fi:remove-all-temporary-lisp-transaction-files)
  (old-kill-emacs arg))

			      Appendix B
			  Sample .clinit.cl

;;				-[Fri Nov 18 19:00:37 1988 by layer]-
;; Sample .clinit.cl file
;;
;; $Header: /var/lib/cvsd/repos/CSRG/43BSDReno/contrib/emacs-18.55/dist-1.3/fi/spec.out,v 1.1 2018/04/24 16:12:57 root Exp $

(format t "; Loading home clinit...~%")

(defparameter *emacs-library*
  (let ((emacs-lib (si:getenv "EMACSLIBRARY")))
    (if emacs-lib (format nil "~a/lisp/fi/" emacs-lib))))

(and *emacs-library*
     (find "+ipc" (system:command-line-arguments) :test #'string=)
     (load (merge-pathnames "clinit.cl" *emacs-library*))
     (load-and-start-ipc-package :unix-domain nil))

;; The following emulates the C shell cd, pushd, popd, pwd, and dirs,
;; and allows Emacs to track directory changes:

(defvar *directory-stack*
  (list (namestring
	 (setq *default-pathname-defaults* (current-directory)))))

(tpl:alias ("pushd" :string) (&optional dir)
  (if* (string= "" dir)
     then (let ((old-top (pop *directory-stack*))
		(new-top (pop *directory-stack*)))
	    (push old-top *directory-stack*)
	    (push (chdir new-top) *directory-stack*))
     else (push (chdir dir) *directory-stack*))
  (format t "~a~%" *directory-stack*))

(tpl:alias "popd" ()
  (if (> (length *directory-stack*) 1)
      (pop *directory-stack*)
    (format t "nothing to pop into~%"))
  (chdir (car *directory-stack*))
  (format t "~a~%" *directory-stack*))

(tpl:alias "dirs" ()
  (format t "~a~%" *directory-stack*))

(tpl:alias ("cd" :string) (dir)
  (setf (car *directory-stack*)
    (apply #'chdir
	   (if (string= "" dir) nil (list dir))))
  (format t "~a~%" *directory-stack*))

(tpl:alias "pwd" ()
  (format t "process cwd = ~a~%*default-pathname-defaults* = ~a~%"
	  (namestring (current-directory))
	  (namestring (truename *default-pathname-defaults*))))

			      Appendix C
			Sample X11 interaction

;;				-[Fri Nov 18 20:21:56 1988 by layer]-
;; Sample X11 bindings for .emacs file
;;
;; $Header: /var/lib/cvsd/repos/CSRG/43BSDReno/contrib/emacs-18.55/dist-1.3/fi/spec.out,v 1.1 2018/04/24 16:12:57 root Exp $

(require 'x-mouse)

(defun x-lisp-find-tag (arg)
  (x-mouse-set-point arg)
  (cond ((eq major-mode 'fi:common-lisp-mode) (fi:lisp-find-tag))
	(t (find-tag-other-window (find-tag-default)))))

(defun x-lisp-eval-defun (arg)
  (x-mouse-set-point arg)
  (cond ((memq major-mode '(fi:common-lisp-mode fi:franz-lisp-mode
			    fi:lisp-mode))
	 (fi:lisp-eval-defun nil))
	((eq major-mode 'fi:emacs-lisp-mode) (eval-defun))))

(defun x-lisp-arglist (arg)
  (x-mouse-set-point arg)
  (cond ((eq major-mode 'fi:common-lisp-mode) (fi:lisp-arglist))
	(t (describe-function (intern (find-tag-default))))))

(define-key mouse-map x-button-left-up 'x-lisp-find-tag)
(define-key mouse-map x-button-middle-up 'x-lisp-eval-defun)
(define-key mouse-map x-button-right-up 'x-lisp-arglist)

;; we ignore mouse button-down events, because if we put something
;; on it the `up' event will cause the minibuffer output to disappear
(define-key mouse-map x-button-left 'x-mouse-ignore)
(define-key mouse-map x-button-middle 'x-mouse-ignore)
(define-key mouse-map x-button-right 'x-mouse-ignore)
(define-key mouse-map x-button-c-left 'x-mouse-ignore)

			      Appendix D
			  Franz Lisp Support

D.1 Introduction

   Franz Lisp is handled very similar to Common Lisp, the only
difference being that Franz Lisp does not support TCP/IP socket
communication.  In all other ways, the features, function and variable
names mirror those of the corresponding Common Lisp functions and
variables.

D.2 Editing Franz Lisp

   As with Common Lisp, editing a Franz Lisp source file (.l
extension) causes fi:franz-lisp-mode to be invoked.  The order of
setup in the mode follows that of fi:common-lisp-mode.

   Package system set-up also occurs in the same way as in
fi:common-lisp-mode.

   Franz Lisp does not support the commands depending on TCP/IP.

D.2.1 Bindings

fi:franz-lisp-mode-map................................................[keymap]
   Major mode map used when editing Franz Lisp source.

C-c             Prefix Command
RET             fi:lisp-reindent-newline-indent
DEL             backward-delete-char-untabify
TAB             lisp-indent-line
C-x             Prefix Command
ESC             Prefix Command

C-c C-r         fi:lisp-eval-region
C-c C-s         fi:lisp-eval-last-sexp
C-c C-b         fi:lisp-eval-current-buffer

ESC C-x         fi:lisp-eval-defun
ESC C-q         indent-sexp




D.2.2 Variables

   The buffer-local variable fi:package is set up as in
fi:common-lisp-mode.

D.2.3 Functions

   The functions in the keymaps are a subset of those in Common Lisp
mode--refer to the main document for a description of those commands.

D.2.4 Hooks

   The hooks run are fi:lisp-mode-hook and fi:franz-lisp-mode-hook,
and are done last in the mode initialization.

D.3 Running Franz Lisp

   As with Common Lisp, there are two entry points for running an
inferior Franz Lisp. `M-x fi:franz-lisp' and `M-x fi:explicit-franz-lisp'
create Franz Lisp processes.  The default name of the Franz Lisp image
is `lisp'.

D.3.1 Bindings

fi:inferior-franz-lisp-mode-map.......................................[keymap]
   The inferior-franz-lisp major-mode keymap.

DEL             backward-delete-char-untabify
TAB             lisp-indent-line
C-x             Prefix Command
ESC             Prefix Command
C-c             Prefix Command
RET             fi:inferior-lisp-newline

C-c C-\         fi:subprocess-quit
C-c C-d         fi:subprocess-send-eof
C-c C-c         fi:subprocess-interrupt
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-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-o         fi:subprocess-send-flush
C-c C-n         fi:push-input
C-c RET         fi:subprocess-input-region
C-c C-l         fi:list-input-ring
C-c C-k         fi:subprocess-kill-output
C-c C-a         fi:subprocess-beginning-of-line

C-x RET         fi:inferior-lisp-input-list

ESC RET         fi:inferior-lisp-input-sexp
ESC C-q         indent-sexp




D.3.2 Variables

fi:franz-lisp-image-name............................................[variable]
   Value: "lisp"
   *Default Franz Lisp image to invoke from `fi:franz-lisp'.  If the value
is a string then it names the image file or image path that
`fi:common-lisp' 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:franz-lisp-image-arguments.......................................[variable]
   Value: nil
   *Default Franz Lisp image arguments when invoked from `fi:franz-lisp'.


fi:franz-lisp-prompt-pattern........................................[variable]
   Value: "^[-=]> +\\|^c{[0-9]+} +"
   *The regular expression which matches the Franz Lisp prompt, used in
Inferior Franz Lisp mode.  Anything from beginning of line up to the end
of what this pattern matches is deemed to be a prompt.



D.3.3 Functions

fi:franz-lisp.......................................................[function]
   Start a Franz Lisp subprocess in a buffer whose name is determined
from the optional prefix argument BUFFER-NUMBER.  Franz Lisp buffer names
start with `*franz-lisp' and end with `*', with an optional `-N' in
between.  If BUFFER-NUMBER is not given it defaults to 1.  If BUFFER-NUMBER
is >= 0, then the buffer is named `*franz-lisp-<BUFFER-NUMBER>*'.  If
BUFFER-NUMBER is < 0, then the first available buffer name is chosen.

The image file and image arguments are taken from the variables
`fi:franz-lisp-image-name' and `fi:franz-lisp-image-arguments'.

See fi:explicit-franz-lisp.


fi:explicit-franz-lisp..............................................[function]
   The same as fi:franz-lisp, except that the image and image arguments
are read from the minibuffer.



D.3.3 Hooks

   The following hooks are run when starting up an inferior Franz
Lisp:

	fi:lisp-mode-hook
	fi:subprocess-mode-hook
	fi:inferior-franz-lisp-mode-hook

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.