Slime, Swank, and Corman Lisp v3.01+
April 4, 2008
How to Run Corman Lisp with XEmacs/SLIME
I have more-or-less successfully got Corman Common Lisp running with XEmacs/SLIME. I will describe how…
In order to get things running I’ve made a number of changes to Swank and Corman Lisp. If the cookbook below doesn’t work for you I have probably forgotten to document one of the changes, so if you’ll let me know I’ll try to track it down.
Versions
This report applies to:
-
xemacs (version 21.4.21)
-
slime (version 2.0 changelog dated 2006-04-20)
-
corman common lisp (version 3.01)
-
Windows XP and Vista.
Procedure
Download and install XEmacs and Corman Common Lisp.
Modify XEmacs
Run XEmacs and make the following modifications to your init file by either editing it directly (if you know where XEmacs looks for it) or by using /Options/Edit Init File from the XEmacs menu bar:
(add-to-list ‘load-path “/Program Files/XEmacs/xemacs-packages/lisp/slime-2.0″)
(require ’slime)
(slime-setup :autodoc t)
Of course, if you have installed XEmacs in a non-default location, you must modify the load path accordingly.
Modify Corman Common Lisp
You need patched versions of the following Corman Lisp distribution files: clos.lisp, xp.lisp, and trace.lisp. These are available from Corman Lisp. When the version of Corman Lisp subsequent to v3.01 is available you will be able simply to use the normal files from the distribution and will not need to acquire patched files from Corman Lisp. In the meantime, you should add the patched files into your Corman Lisp image.
You must modify the Sys/sockets.lisp file and the Sys/winsock.lisp files from the Corman Lisp distribution as suggested here by ungil on 19 Sep 2006. With apologies, I am copying ungil’s changes verbatim here:
| $ diff -b sockets.lisp 469c469 < (winsock::listen (socket-descriptor s) SOMAXCONN)))) — > (listen (socket-descriptor s) SOMAXCONN))))$ diff -b winsock.lisp 14,15d13 < (shadow ‘(cl:listen)) < |
I have integrated these changes into my Corman Lisp image. They do not seem to have broken anything, but I cannot be sure. If you want to be on the safe side, do not add the sockets.lisp and winsock.lisp changes into your lisp image, just modify the relevant functions after initializing your lisp.
You must modify the Modules/gray-streams.lisp file so that it defines stream-terpri. Add the following code to the file
| (defmethod stream-terpri ((stream fundamental-character-output-stream)) (if (stream-start-line-p stream) nil (progn (stream-write-char stream #\newline) t))) |
If you prefer, you can download the modified file from here, and simply copy it over the old one in the Modules directory. The modified file contains a number of additional stub function definitions that should be transparent to any code currently using gray-streams.lisp.
You need to make a few additional, special changes to Corman Lisp for Slime compatibility. I have collected these in a separate file called slime-compatibility.lisp here. The file slime-compatibility makes the following modifications:
-
Fix the definition of #’user-homedir-pathname;
-
Redefine #’pprint so that it sets *print-pretty* nil;
-
Redefine #’cl:machine-instance, #’cl:machine-type, #’cl:machine-version;
-
Add a feature to *features*;
When you start Corman Lisp, you will need to reload sockets.lisp, winsock.lisp, gray-streams.lisp, and slime-compatibility.lisp so that the new definitions are visible to the system. Alternatively, you can create a new lisp image using the function #’compile-cormanlisp-image. (Consult the documentation.)
You must load all these changes into Corman Lisp before loading swank.
Modify Swank
You must make a number of modifications to the code distributed with XEmacs.
In the slime distribution file [XEmacs]/xemacs-packages/lisp/slime-2.0/swank.lisp you need to comment out a series of assertions. Open the file and search for ‘test-print-arglist’. Then comment out the progn as follows:
#-cormanlisp(progn
(assert (test-print-arglist ‘(function cons) “(function cons)“))
(assert (test-print-arglist ‘(quote cons) “(quote cons)“))
(assert (test-print-arglist ‘(&key (function #’+)) “(&key (function #’+))“))
(assert (test-print-arglist ‘(&whole x y z) “(y z)“))
(assert (test-print-arglist ‘(x &aux y z) “(x)“))
(assert (test-print-arglist ‘(x &environment env y) “(x y)“)))
;; Expected failure:
;; (assert (test-print-arglist ‘(&key ((function f))) “(&key ((function f)))”))
I have also redefined #’swank::swank-debugger-hook so that you can disable the debugger by controlling the value of *maybe-disable-debugger*. In addition to being convenient, it avoids some instabilities involved with the Corman Lisp Debugger. Here is the relevant section of swank.lisp:
#+cormanlisp
(defvar *maybe-avoid-debugger* t
“do not enter debugger if it is possible simply to abort the request”)
#+cormanlisp
(defun swank-debugger-hook (condition hook)
(declare (ignore hook))
(cond ((and *maybe-avoid-debugger* (find-restart ‘abort-request))
(send-to-emacs `(:write-string ,(format nil “~A” condition)))
(invoke-restart ‘abort-request))
(*emacs-connection*
(debug-in-emacs condition))
((default-connection)
(with-connection ((default-connection))
(debug-in-emacs condition)))))
#-cormanlisp
(defun swank-debugger-hook (condition hook)
“Debugger function for binding *DEBUGGER-HOOK*.
Sends a message to Emacs declaring that the debugger has been entered,
then waits to handle further requests from Emacs. Eventually returns
after Emacs causes a restart to be invoked.”
(declare (ignore hook))
(cond (*emacs-connection*
(debug-in-emacs condition))
((default-connection)
(with-connection ((default-connection))
(debug-in-emacs condition)))))
In the slime distribution file [XEmacs]/xemacs-packages/lisp/slime-2.0/swank-corman.lisp you need to modify the definition of #’arglist as follows:
| (defimplementation arglist (name) (handler-case (cond ((and (symbolp name) (macro-function name)) (let* ((function (symbol-function name)) (macro-list (ccl::macro-lambda-list function))) (if macro-list macro-list :not-available))) (t (when (symbolp name) (setq name (symbol-function name))) (if (eq (class-of name) cl::the-class-standard-gf) (generic-function-lambda-list name) (ccl:function-lambda-list name)))) (error () :not-available))) |
Appropriate swank-corman.lisp and swank.lisp files are available as a .zip file for download here. After the next release of Corman Common Lisp (whatever version comes after 3.01), I will see about getting the changes added to the official XEmacs distribution so the standard distribution will simply work out of the box.
Run Slime and Corman Lisp
-
Start Swank on the corman lisp side via the following steps:
-
Start [Corman Lisp]/CormanLisp.exe;
-
(load “Sys/winsock.lisp”)
-
(load “Sys/sockets.lisp”)
-
(load “Modules/gray-streams.lisp”)
-
(load “swank-compatibility.lisp”) ; from wherever you saved swank-compatibility.lisp
- Change directory to the slime distribution. For example (setf (cormanlisp:current-directory) “C:\\Program Files\\XEmacs\\xemacs-packages\\lisp\\slime-2.0\\“)
-
(load “swank-loader.lisp”) ; this will take some time
- (swank::create-server)
-
-
Assuming everything works, you should see a notice that Swank started at port: 4005.
-
Start xemacs.
-
Initiate slime via
-
Alt-x slime-connect<return>
-
Host: 127.0.0.1<return>
-
Port: 4005<return>
-
-
Assuming everything works, you should see a “Connected” notice.
If you prefer to keep the full debugging capabilities, setq swank::*maybe-avoid-debugger* t.
What Works; What Doesn’t
;;; As of
;;; 04 Apr 2008 -
;;; Functionality Description Yes/No/Kinda
;;; ===============================================
;;; C-M-x, etc. basic editing and eval Y
;;; arglist display K
;;; C-c C-c, etc compilation Y
;;; loading files Y
;;; C-c C-d d, &c describe/hyperspec Y
;;; debugger K
;;; C-c I inspector Y
;;; profiling N
;;; stepper N
;;; comm styles (:spawn etc.) N
;;; C-c C-w c, &c cross referencing N
;;; M-. edit definition Y
;;; M-TAB complete symbol Y
;;; C-c C-s complete form K
Notes:
The debugger is mostly ok. It is possible to crash it if you are ungentle. I personally find the lisp-style of debugger overkill in most instances, so it is nice to be able to disable it unless needed. If you want to disable it, at the slime repl setq swank::*maybe-avoid-debugger* t. If you want to re-enable it, setq swank::*maybe-avoid-debugger* nil.
Corman Lisp doesn’t currently feature a stepper.
The arglist display works for all user-defined functions and some built-in functions. Inexplicably, a large fraction of the built-in functions haven’t saved their arglists, so, for example, you can’t get arglist information on #’defun.
RSS
[...] updated version of this post is available here: http://brainrack.wordpress.com/2008/04/04/slime-swank-and-corman-lisp-v301/. The update describes how to get SLIME working with [...]