Reinstate old -f option as an alias for -o for installed base uses.
[bpt/emacs.git] / lisp / progmodes / inf-lisp.el
CommitLineData
926d5019 1;;; inf-lisp.el --- an inferior-lisp mode
5336e829 2;;; Copyright (C) 1988 Free Software Foundation, Inc.
3a801d0c 3
07168830 4;; Author: Olin Shivers <shivers@cs.cmu.edu>
e9571d2a 5;; Keywords: processes, lisp
07168830 6
926d5019
JB
7;;; This file is part of GNU Emacs.
8
9;;; GNU Emacs is free software; you can redistribute it and/or modify
10;;; it under the terms of the GNU General Public License as published by
11;;; the Free Software Foundation; either version 2, or (at your option)
12;;; any later version.
13
14;;; GNU Emacs is distributed in the hope that it will be useful,
15;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;;; GNU General Public License for more details.
18
19;;; You should have received a copy of the GNU General Public License
20;;; along with GNU Emacs; see the file COPYING. If not, write to
21;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2f790b20 22
07168830
ER
23;;; Commentary:
24
2f790b20 25;;; Hacked from tea.el by Olin Shivers (shivers@cs.cmu.edu). 8/88
2f790b20 26
926d5019
JB
27;;; This file defines a a lisp-in-a-buffer package (inferior-lisp
28;;; mode) built on top of comint mode. This version is more
29;;; featureful, robust, and uniform than the Emacs 18 version. The
30;;; key bindings are also more compatible with the bindings of Hemlock
31;;; and Zwei (the Lisp Machine emacs).
2f790b20
JB
32
33;;; Since this mode is built on top of the general command-interpreter-in-
34;;; a-buffer mode (comint mode), it shares a common base functionality,
35;;; and a common set of bindings, with all modes derived from comint mode.
36;;; This makes these modes easier to use.
37
38;;; For documentation on the functionality provided by comint mode, and
39;;; the hooks available for customising it, see the file comint.el.
926d5019 40;;; For further information on inferior-lisp mode, see the comments below.
2f790b20
JB
41
42;;; Needs fixin:
43;;; The load-file/compile-file default mechanism could be smarter -- it
44;;; doesn't know about the relationship between filename extensions and
45;;; whether the file is source or executable. If you compile foo.lisp
46;;; with compile-file, then the next load-file should use foo.bin for
47;;; the default, not foo.lisp. This is tricky to do right, particularly
48;;; because the extension for executable files varies so much (.o, .bin,
49;;; .lbin, .mo, .vo, .ao, ...).
50;;;
926d5019 51;;; It would be nice if inferior-lisp (and inferior scheme, T, ...) modes
2f790b20
JB
52;;; had a verbose minor mode wherein sending or compiling defuns, etc.
53;;; would be reflected in the transcript with suitable comments, e.g.
54;;; ";;; redefining fact". Several ways to do this. Which is right?
55;;;
56;;; When sending text from a source file to a subprocess, the process-mark can
57;;; move off the window, so you can lose sight of the process interactions.
58;;; Maybe I should ensure the process mark is in the window when I send
59;;; text to the process? Switch selectable?
60
2f790b20
JB
61;; YOUR .EMACS FILE
62;;=============================================================================
63;; Some suggestions for your .emacs file.
64;;
926d5019 65;; ; If inferior-lisp lives in some non-standard directory, you must tell emacs
2f790b20
JB
66;; ; where to get it. This may or may not be necessary.
67;; (setq load-path (cons (expand-file-name "~jones/lib/emacs") load-path))
68;;
926d5019
JB
69;; ; Autoload inferior-lisp from file inf-lisp.el
70;; (autoload 'inferior-lisp "inferior-lisp"
2f790b20
JB
71;; "Run an inferior Lisp process."
72;; t)
73;;
926d5019
JB
74;; ; Define C-c t to run my favorite command in inferior-lisp mode:
75;; (setq inferior-lisp-load-hook
2f790b20 76;; '((lambda ()
926d5019 77;; (define-key inferior-lisp-mode-map "\C-ct" 'favorite-cmd))))
2f790b20
JB
78
79\f
80;;; Brief Command Documentation:
81;;;============================================================================
926d5019
JB
82;;; Comint Mode Commands: (common to inferior-lisp and all
83;;; comint-derived modes)
2f790b20
JB
84;;;
85;;; m-p comint-previous-input Cycle backwards in input history
86;;; m-n comint-next-input Cycle forwards
87;;; m-c-r comint-previous-input-matching Search backwards in input history
88;;; return comint-send-input
89;;; c-a comint-bol Beginning of line; skip prompt.
90;;; c-d comint-delchar-or-maybe-eof Delete char unless at end of buff.
91;;; c-c c-u comint-kill-input ^u
92;;; c-c c-w backward-kill-word ^w
93;;; c-c c-c comint-interrupt-subjob ^c
94;;; c-c c-z comint-stop-subjob ^z
95;;; c-c c-\ comint-quit-subjob ^\
96;;; c-c c-o comint-kill-output Delete last batch of process output
97;;; c-c c-r comint-show-output Show last batch of process output
98;;; send-invisible Read line w/o echo & send to proc
99;;; comint-continue-subjob Useful if you accidentally suspend
100;;; top-level job.
101;;; comint-mode-hook is the comint mode hook.
102
926d5019 103;;; Inferior Lisp Mode Commands:
2f790b20
JB
104;;; c-m-x lisp-send-defun This binding is a gnu convention.
105;;; c-c c-l lisp-load-file Prompt for file name; tell Lisp to load it.
106;;; c-c c-k lisp-compile-file Prompt for file name; tell Lisp to kompile it.
107;;; Filename completion is available, of course.
108;;;
109;;; Additionally, these commands are added to the key bindings of Lisp mode:
110;;; c-m-x lisp-eval-defun This binding is a gnu convention.
111;;; c-c c-e lisp-eval-defun Send the current defun to Lisp process.
112;;; c-x c-e lisp-eval-last-sexp Send the previous sexp to Lisp process.
2f790b20 113;;; c-c c-r lisp-eval-region Send the current region to Lisp process.
2f790b20 114;;; c-c c-c lisp-compile-defun Compile the current defun in Lisp process.
2f790b20
JB
115;;; c-c c-z switch-to-lisp Switch to the Lisp process buffer.
116;;; c-c c-l lisp-load-file (See above. In a Lisp file buffer, default
117;;; c-c c-k lisp-compile-file is to load/compile the current file.)
118;;; c-c c-d lisp-describe-sym Query Lisp for a symbol's description.
119;;; c-c c-a lisp-show-arglist Query Lisp for function's arglist.
120;;; c-c c-f lisp-show-function-documentation Query Lisp for a function's doc.
121;;; c-c c-v lisp-show-variable-documentation Query Lisp for a variable's doc.
122
926d5019 123;;; inferior-lisp Fires up the Lisp process.
2f790b20 124;;; lisp-compile-region Compile all forms in the current region.
2f790b20 125;;;
926d5019
JB
126;;; Inferior Lisp Mode Variables:
127;;; inferior-lisp-filter-regexp Match this => don't get saved on input hist
2f790b20
JB
128;;; inferior-lisp-program Name of Lisp program run-lisp executes
129;;; inferior-lisp-load-command Customises lisp-load-file
926d5019 130;;; inferior-lisp-mode-hook
2f790b20
JB
131;;; inferior-lisp-prompt Initialises comint-prompt-regexp.
132;;; Backwards compatibility.
133;;; lisp-source-modes Anything loaded into a buffer that's in
134;;; one of these modes is considered Lisp
135;;; source by lisp-load/compile-file.
136
137;;; Read the rest of this file for more information.
07168830
ER
138
139;;; Code:
140
141(require 'comint)
0c280127
JB
142(require 'lisp-mode)
143
2f790b20 144\f
7e1dae73 145;;;###autoload
926d5019 146(defvar inferior-lisp-filter-regexp "\\`\\s *\\(:\\(\\w\\|\\s_\\)\\)?\\s *\\'"
2f790b20 147 "*What not to save on inferior Lisp's input history
926d5019 148Input matching this regexp is not saved on the input history in inferior-lisp
2f790b20
JB
149mode. Default is whitespace followed by 0 or 1 single-letter :keyword
150(as in :a, :c, etc.)")
151
926d5019
JB
152(defvar inferior-lisp-mode-map nil)
153(cond ((not inferior-lisp-mode-map)
154 (setq inferior-lisp-mode-map
2f790b20 155 (full-copy-sparse-keymap comint-mode-map))
926d5019
JB
156 (setq inferior-lisp-mode-map
157 (nconc inferior-lisp-mode-map shared-lisp-mode-map))
158 (define-key inferior-lisp-mode-map "\C-x\C-e" 'lisp-eval-last-sexp)
159 (define-key inferior-lisp-mode-map "\C-c\C-l" 'lisp-load-file)
160 (define-key inferior-lisp-mode-map "\C-c\C-k" 'lisp-compile-file)
161 (define-key inferior-lisp-mode-map "\C-c\C-a" 'lisp-show-arglist)
162 (define-key inferior-lisp-mode-map "\C-c\C-d" 'lisp-describe-sym)
163 (define-key inferior-lisp-mode-map "\C-c\C-f"
164 'lisp-show-function-documentation)
165 (define-key inferior-lisp-mode-map "\C-c\C-v"
166 'lisp-show-variable-documentation)))
2f790b20
JB
167
168;;; These commands augment Lisp mode, so you can process Lisp code in
169;;; the source files.
170(define-key lisp-mode-map "\M-\C-x" 'lisp-eval-defun) ; Gnu convention
171(define-key lisp-mode-map "\C-x\C-e" 'lisp-eval-last-sexp) ; Gnu convention
172(define-key lisp-mode-map "\C-c\C-e" 'lisp-eval-defun)
2f790b20 173(define-key lisp-mode-map "\C-c\C-r" 'lisp-eval-region)
2f790b20 174(define-key lisp-mode-map "\C-c\C-c" 'lisp-compile-defun)
2f790b20
JB
175(define-key lisp-mode-map "\C-c\C-z" 'switch-to-lisp)
176(define-key lisp-mode-map "\C-c\C-l" 'lisp-load-file)
177(define-key lisp-mode-map "\C-c\C-k" 'lisp-compile-file) ; "kompile" file
178(define-key lisp-mode-map "\C-c\C-a" 'lisp-show-arglist)
179(define-key lisp-mode-map "\C-c\C-d" 'lisp-describe-sym)
180(define-key lisp-mode-map "\C-c\C-f" 'lisp-show-function-documentation)
181(define-key lisp-mode-map "\C-c\C-v" 'lisp-show-variable-documentation)
182
183
daa37602
JB
184;;; This function exists for backwards compatibility.
185;;; Previous versions of this package bound commands to C-c <letter>
186;;; bindings, which is not allowed by the gnumacs standard.
187
926d5019
JB
188(defun inferior-lisp-install-letter-bindings ()
189 "This function binds many inferior-lisp commands to C-c <letter> bindings,
daa37602
JB
190where they are more accessible. C-c <letter> bindings are reserved for the
191user, so these bindings are non-standard. If you want them, you should
926d5019
JB
192have this function called by the inferior-lisp-load-hook:
193 (setq inferior-lisp-load-hook '(inferior-lisp-install-letter-bindings))
daa37602 194You can modify this function to install just the bindings you want."
926d5019 195
daa37602
JB
196 (define-key lisp-mode-map "\C-ce" 'lisp-eval-defun-and-go)
197 (define-key lisp-mode-map "\C-cr" 'lisp-eval-region-and-go)
198 (define-key lisp-mode-map "\C-cc" 'lisp-compile-defun-and-go)
199 (define-key lisp-mode-map "\C-cz" 'switch-to-lisp)
200 (define-key lisp-mode-map "\C-cl" 'lisp-load-file)
201 (define-key lisp-mode-map "\C-ck" 'lisp-compile-file)
202 (define-key lisp-mode-map "\C-ca" 'lisp-show-arglist)
203 (define-key lisp-mode-map "\C-cd" 'lisp-describe-sym)
204 (define-key lisp-mode-map "\C-cf" 'lisp-show-function-documentation)
205 (define-key lisp-mode-map "\C-cv" 'lisp-show-variable-documentation)
926d5019
JB
206
207 (define-key inferior-lisp-mode-map "\C-cl" 'lisp-load-file)
208 (define-key inferior-lisp-mode-map "\C-ck" 'lisp-compile-file)
209 (define-key inferior-lisp-mode-map "\C-ca" 'lisp-show-arglist)
210 (define-key inferior-lisp-mode-map "\C-cd" 'lisp-describe-sym)
211 (define-key inferior-lisp-mode-map "\C-cf" 'lisp-show-function-documentation)
212 (define-key inferior-lisp-mode-map "\C-cv"
213 'lisp-show-variable-documentation))
daa37602
JB
214
215
7e1dae73 216;;;###autoload
2f790b20 217(defvar inferior-lisp-program "lisp"
926d5019 218 "*Program name for invoking an inferior Lisp with `inferior-lisp'.")
2f790b20 219
7e1dae73 220;;;###autoload
2f790b20
JB
221(defvar inferior-lisp-load-command "(load \"%s\")\n"
222 "*Format-string for building a Lisp expression to load a file.
223This format string should use %s to substitute a file name
224and should result in a Lisp expression that will command the inferior Lisp
225to load that file. The default works acceptably on most Lisps.
226The string \"(progn (load \\\"%s\\\" :verbose nil :print t) (values))\\\n\"
227produces cosmetically superior output for this application,
228but it works only in Common Lisp.")
229
7e1dae73 230;;;###autoload
2f790b20
JB
231(defvar inferior-lisp-prompt "^[^> ]*>+:? *"
232 "Regexp to recognise prompts in the inferior Lisp.
233Defaults to \"^[^> ]*>+:? *\", which works pretty good for Lucid, kcl,
234and franz. This variable is used to initialise comint-prompt-regexp in the
926d5019 235inferior-lisp buffer.
2f790b20
JB
236
237More precise choices:
238Lucid Common Lisp: \"^\\(>\\|\\(->\\)+\\) *\"
239franz: \"^\\(->\\|<[0-9]*>:\\) *\"
240kcl: \"^>+ *\"
241
242This is a fine thing to set in your .emacs file.")
243
7e1dae73 244;;;###autoload
926d5019
JB
245(defvar inferior-lisp-mode-hook '()
246 "*Hook for customising inferior-lisp mode")
2f790b20 247
926d5019 248(defun inferior-lisp-mode ()
2f790b20
JB
249 "Major mode for interacting with an inferior Lisp process.
250Runs a Lisp interpreter as a subprocess of Emacs, with Lisp I/O through an
251Emacs buffer. Variable inferior-lisp-program controls which Lisp interpreter
926d5019 252is run. Variables inferior-lisp-prompt, inferior-lisp-filter-regexp and
2f790b20
JB
253inferior-lisp-load-command can customize this mode for different Lisp
254interpreters.
255
256For information on running multiple processes in multiple buffers, see
926d5019 257documentation for variable inferior-lisp-buffer.
2f790b20 258
926d5019 259\\{inferior-lisp-mode-map}
2f790b20
JB
260
261Customisation: Entry to this mode runs the hooks on comint-mode-hook and
926d5019 262inferior-lisp-mode-hook (in that order).
2f790b20
JB
263
264You can send text to the inferior Lisp process from other buffers containing
265Lisp source.
266 switch-to-lisp switches the current buffer to the Lisp process buffer.
267 lisp-eval-defun sends the current defun to the Lisp process.
268 lisp-compile-defun compiles the current defun.
269 lisp-eval-region sends the current region to the Lisp process.
270 lisp-compile-region compiles the current region.
271
daa37602
JB
272 Prefixing the lisp-eval/compile-defun/region commands with
273 a \\[universal-argument] causes a switch to the Lisp process buffer after sending
274 the text.
2f790b20
JB
275
276Commands:
277Return after the end of the process' output sends the text from the
278 end of process to point.
279Return before the end of the process' output copies the sexp ending at point
280 to the end of the process' output, and sends it.
281Delete converts tabs to spaces as it moves back.
282Tab indents for Lisp; with argument, shifts rest
283 of expression rigidly with the current line.
284C-M-q does Tab on each line starting within following expression.
285Paragraphs are separated only by blank lines. Semicolons start comments.
286If you accidentally suspend your process, use \\[comint-continue-subjob]
287to continue it."
288 (interactive)
289 (comint-mode)
290 (setq comint-prompt-regexp inferior-lisp-prompt)
926d5019
JB
291 (setq major-mode 'inferior-lisp-mode)
292 (setq mode-name "Inferior Lisp")
2f790b20 293 (setq mode-line-process '(": %s"))
926d5019
JB
294 (lisp-mode-variables t)
295 (use-local-map inferior-lisp-mode-map) ;c-c c-k for "kompile" file
2f790b20
JB
296 (setq comint-get-old-input (function lisp-get-old-input))
297 (setq comint-input-filter (function lisp-input-filter))
298 (setq comint-input-sentinel 'ignore)
926d5019 299 (run-hooks 'inferior-lisp-mode-hook))
2f790b20
JB
300
301(defun lisp-get-old-input ()
302 "Snarf the sexp ending at point"
303 (save-excursion
304 (let ((end (point)))
305 (backward-sexp)
306 (buffer-substring (point) end))))
307
308(defun lisp-input-filter (str)
926d5019
JB
309 "Don't save anything matching inferior-lisp-filter-regexp"
310 (not (string-match inferior-lisp-filter-regexp str)))
2f790b20 311
7e1dae73 312;;;###autoload
926d5019
JB
313(defun inferior-lisp (cmd)
314 "Run an inferior Lisp process, input and output via buffer *inferior-lisp*.
315If there is a process already running in *inferior-lisp*, just switch
316to that buffer.
daa37602 317With argument, allows you to edit the command line (default is value
926d5019
JB
318of inferior-lisp-program). Runs the hooks from
319inferior-lisp-mode-hook (after the comint-mode-hook is run).
2f790b20 320\(Type \\[describe-mode] in the process buffer for a list of commands.)"
daa37602
JB
321 (interactive (list (if current-prefix-arg
322 (read-string "Run lisp: " inferior-lisp-program)
926d5019
JB
323 inferior-lisp-program)))
324 (if (not (comint-check-proc "*inferior-lisp*"))
325 (let ((cmdlist (inferior-lisp-args-to-list cmd)))
326 (set-buffer (apply (function make-comint)
327 "inferior-lisp" (car cmdlist) nil (cdr cmdlist)))
328 (inferior-lisp-mode)))
329 (setq inferior-lisp-buffer "*inferior-lisp*")
330 (switch-to-buffer "*inferior-lisp*"))
331
332(fset 'run-lisp 'inferior-lisp)
2f790b20 333
daa37602
JB
334;;; Break a string up into a list of arguments.
335;;; This will break if you have an argument with whitespace, as in
336;;; string = "-ab +c -x 'you lose'".
926d5019 337(defun inferior-lisp-args-to-list (string)
daa37602
JB
338 (let ((where (string-match "[ \t]" string)))
339 (cond ((null where) (list string))
340 ((not (= where 0))
341 (cons (substring string 0 where)
926d5019
JB
342 (inferior-lisp-args-to-list (substring string (+ 1 where)
343 (length string)))))
daa37602
JB
344 (t (let ((pos (string-match "[^ \t]" string)))
345 (if (null pos)
346 nil
926d5019
JB
347 (inferior-lisp-args-to-list (substring string pos
348 (length string)))))))))
daa37602
JB
349
350(defun lisp-eval-region (start end &optional and-go)
351 "Send the current region to the inferior Lisp process.
352Prefix argument means switch-to-lisp afterwards."
353 (interactive "r\nP")
926d5019
JB
354 (comint-send-region (inferior-lisp-proc) start end)
355 (comint-send-string (inferior-lisp-proc) "\n")
daa37602 356 (if and-go (switch-to-lisp t)))
2f790b20 357
daa37602
JB
358(defun lisp-eval-defun (&optional and-go)
359 "Send the current defun to the inferior Lisp process.
360Prefix argument means switch-to-lisp afterwards."
361 (interactive "P")
2f790b20 362 (save-excursion
daa37602
JB
363 (end-of-defun)
364 (skip-chars-backward " \t\n\r\f") ; Makes allegro happy
365 (let ((end (point)))
366 (beginning-of-defun)
367 (lisp-eval-region (point) end)))
368 (if and-go (switch-to-lisp t)))
2f790b20 369
daa37602
JB
370(defun lisp-eval-last-sexp (&optional and-go)
371 "Send the previous sexp to the inferior Lisp process.
372Prefix argument means switch-to-lisp afterwards."
373 (interactive "P")
374 (lisp-eval-region (save-excursion (backward-sexp) (point)) (point) and-go))
2f790b20 375
daa37602
JB
376;;; Common Lisp COMPILE sux.
377(defun lisp-compile-region (start end &optional and-go)
378 "Compile the current region in the inferior Lisp process.
379Prefix argument means switch-to-lisp afterwards."
380 (interactive "r\nP")
926d5019
JB
381 (comint-send-string
382 (inferior-lisp-proc)
383 (format "(funcall (compile nil `(lambda () (progn 'compile %s))))\n"
384 (buffer-substring start end)))
daa37602 385 (if and-go (switch-to-lisp t)))
926d5019 386
daa37602
JB
387(defun lisp-compile-defun (&optional and-go)
388 "Compile the current defun in the inferior Lisp process.
389Prefix argument means switch-to-lisp afterwards."
390 (interactive "P")
2f790b20
JB
391 (save-excursion
392 (end-of-defun)
daa37602 393 (skip-chars-backward " \t\n\r\f") ; Makes allegro happy
2f790b20
JB
394 (let ((e (point)))
395 (beginning-of-defun)
daa37602
JB
396 (lisp-compile-region (point) e)))
397 (if and-go (switch-to-lisp t)))
2f790b20
JB
398
399(defun switch-to-lisp (eob-p)
400 "Switch to the inferior Lisp process buffer.
401With argument, positions cursor at end of buffer."
402 (interactive "P")
926d5019
JB
403 (if (get-buffer inferior-lisp-buffer)
404 (pop-to-buffer inferior-lisp-buffer)
405 (error "No current process buffer. See variable inferior-lisp-buffer."))
2f790b20
JB
406 (cond (eob-p
407 (push-mark)
408 (goto-char (point-max)))))
409
daa37602
JB
410
411;;; Now that lisp-compile/eval-defun/region takes an optional prefix arg,
412;;; these commands are redundant. But they are kept around for the user
413;;; to bind if he wishes, for backwards functionality, and because it's
414;;; easier to type C-c e than C-u C-c C-e.
415
2f790b20
JB
416(defun lisp-eval-region-and-go (start end)
417 "Send the current region to the inferior Lisp,
418and switch to the process buffer."
419 (interactive "r")
daa37602 420 (lisp-eval-region start end t))
2f790b20
JB
421
422(defun lisp-eval-defun-and-go ()
423 "Send the current defun to the inferior Lisp,
424and switch to the process buffer."
425 (interactive)
daa37602 426 (lisp-eval-defun t))
2f790b20
JB
427
428(defun lisp-compile-region-and-go (start end)
429 "Compile the current region in the inferior Lisp,
430and switch to the process buffer."
431 (interactive "r")
daa37602 432 (lisp-compile-region start end t))
2f790b20
JB
433
434(defun lisp-compile-defun-and-go ()
435 "Compile the current defun in the inferior Lisp,
436and switch to the process buffer."
437 (interactive)
daa37602 438 (lisp-compile-defun t))
2f790b20
JB
439
440;;; A version of the form in H. Shevis' soar-mode.el package. Less robust.
926d5019
JB
441;;; (defun lisp-compile-sexp (start end)
442;;; "Compile the s-expression bounded by START and END in the inferior lisp.
443;;; If the sexp isn't a DEFUN form, it is evaluated instead."
444;;; (cond ((looking-at "(defun\\s +")
445;;; (goto-char (match-end 0))
446;;; (let ((name-start (point)))
447;;; (forward-sexp 1)
448;;; (process-send-string "inferior-lisp"
449;;; (format "(compile '%s #'(lambda "
450;;; (buffer-substring name-start
451;;; (point)))))
452;;; (let ((body-start (point)))
453;;; (goto-char start) (forward-sexp 1) ; Can't use end-of-defun.
454;;; (process-send-region "inferior-lisp"
455;;; (buffer-substring body-start (point))))
456;;; (process-send-string "inferior-lisp" ")\n"))
457;;; (t (lisp-eval-region start end)))))
458;;;
459;;; (defun lisp-compile-region (start end)
460;;; "Each s-expression in the current region is compiled (if a DEFUN)
461;;; or evaluated (if not) in the inferior lisp."
462;;; (interactive "r")
463;;; (save-excursion
464;;; (goto-char start) (end-of-defun) (beginning-of-defun) ; error check
465;;; (if (< (point) start) (error "region begins in middle of defun"))
466;;; (goto-char start)
467;;; (let ((s start))
468;;; (end-of-defun)
469;;; (while (<= (point) end) ; Zip through
470;;; (lisp-compile-sexp s (point)) ; compiling up defun-sized chunks.
471;;; (setq s (point))
472;;; (end-of-defun))
473;;; (if (< s end) (lisp-compile-sexp s end)))))
474;;;
2f790b20
JB
475;;; End of HS-style code
476
477
478(defvar lisp-prev-l/c-dir/file nil
479 "Saves the (directory . file) pair used in the last lisp-load-file or
480lisp-compile-file command. Used for determining the default in the
481next one.")
482
483(defvar lisp-source-modes '(lisp-mode)
484 "*Used to determine if a buffer contains Lisp source code.
485If it's loaded into a buffer that is in one of these major modes, it's
486considered a Lisp source file by lisp-load-file and lisp-compile-file.
487Used by these commands to determine defaults.")
488
489(defun lisp-load-file (file-name)
490 "Load a Lisp file into the inferior Lisp process."
491 (interactive (comint-get-source "Load Lisp file: " lisp-prev-l/c-dir/file
492 lisp-source-modes nil)) ; NIL because LOAD
926d5019 493 ; doesn't need an exact name
2f790b20
JB
494 (comint-check-source file-name) ; Check to see if buffer needs saved.
495 (setq lisp-prev-l/c-dir/file (cons (file-name-directory file-name)
496 (file-name-nondirectory file-name)))
926d5019 497 (comint-send-string (inferior-lisp-proc)
daa37602
JB
498 (format inferior-lisp-load-command file-name))
499 (switch-to-lisp t))
2f790b20
JB
500
501
502(defun lisp-compile-file (file-name)
503 "Compile a Lisp file in the inferior Lisp process."
504 (interactive (comint-get-source "Compile Lisp file: " lisp-prev-l/c-dir/file
505 lisp-source-modes nil)) ; NIL = don't need
926d5019 506 ; suffix .lisp
2f790b20
JB
507 (comint-check-source file-name) ; Check to see if buffer needs saved.
508 (setq lisp-prev-l/c-dir/file (cons (file-name-directory file-name)
509 (file-name-nondirectory file-name)))
926d5019
JB
510 (comint-send-string (inferior-lisp-proc) (concat "(compile-file \""
511 file-name
512 "\"\)\n"))
daa37602 513 (switch-to-lisp t))
2f790b20
JB
514
515
516\f
517;;; Documentation functions: function doc, var doc, arglist, and
518;;; describe symbol.
519;;; ===========================================================================
520
521;;; Command strings
522;;; ===============
523
524(defvar lisp-function-doc-command
525 "(let ((fn '%s))
526 (format t \"Documentation for ~a:~&~a\"
527 fn (documentation fn 'function))
528 (values))\n"
529 "Command to query inferior Lisp for a function's documentation.")
530
531(defvar lisp-var-doc-command
532 "(let ((v '%s))
533 (format t \"Documentation for ~a:~&~a\"
534 v (documentation v 'variable))
535 (values))\n"
536 "Command to query inferior Lisp for a variable's documentation.")
537
538(defvar lisp-arglist-command
539 "(let ((fn '%s))
540 (format t \"Arglist for ~a: ~a\" fn (arglist fn))
541 (values))\n"
542 "Command to query inferior Lisp for a function's arglist.")
543
544(defvar lisp-describe-sym-command
545 "(describe '%s)\n"
546 "Command to query inferior Lisp for a variable's documentation.")
547
548
549;;; Ancillary functions
550;;; ===================
551
552;;; Reads a string from the user.
553(defun lisp-symprompt (prompt default)
554 (list (let* ((prompt (if default
555 (format "%s (default %s): " prompt default)
926d5019 556 (concat prompt ": ")))
2f790b20
JB
557 (ans (read-string prompt)))
558 (if (zerop (length ans)) default ans))))
559
560
561;;; Adapted from function-called-at-point in help.el.
562(defun lisp-fn-called-at-pt ()
563 "Returns the name of the function called in the current call.
564Nil if it can't find one."
565 (condition-case nil
566 (save-excursion
567 (save-restriction
568 (narrow-to-region (max (point-min) (- (point) 1000)) (point-max))
569 (backward-up-list 1)
570 (forward-char 1)
571 (let ((obj (read (current-buffer))))
572 (and (symbolp obj) obj))))
573 (error nil)))
574
575
576;;; Adapted from variable-at-point in help.el.
577(defun lisp-var-at-pt ()
578 (condition-case ()
579 (save-excursion
580 (forward-sexp -1)
581 (skip-chars-forward "'")
582 (let ((obj (read (current-buffer))))
583 (and (symbolp obj) obj)))
584 (error nil)))
585
586
587;;; Documentation functions: fn and var doc, arglist, and symbol describe.
588;;; ======================================================================
589
590(defun lisp-show-function-documentation (fn)
591 "Send a command to the inferior Lisp to give documentation for function FN.
592See variable lisp-function-doc-command."
593 (interactive (lisp-symprompt "Function doc" (lisp-fn-called-at-pt)))
926d5019
JB
594 (comint-proc-query (inferior-lisp-proc)
595 (format lisp-function-doc-command fn)))
2f790b20
JB
596
597(defun lisp-show-variable-documentation (var)
598 "Send a command to the inferior Lisp to give documentation for function FN.
599See variable lisp-var-doc-command."
600 (interactive (lisp-symprompt "Variable doc" (lisp-var-at-pt)))
926d5019 601 (comint-proc-query (inferior-lisp-proc) (format lisp-var-doc-command var)))
2f790b20
JB
602
603(defun lisp-show-arglist (fn)
604 "Sends an query to the inferior Lisp for the arglist for function FN.
605See variable lisp-arglist-command."
606 (interactive (lisp-symprompt "Arglist" (lisp-fn-called-at-pt)))
926d5019 607 (comint-proc-query (inferior-lisp-proc) (format lisp-arglist-command fn)))
2f790b20
JB
608
609(defun lisp-describe-sym (sym)
610 "Send a command to the inferior Lisp to describe symbol SYM.
611See variable lisp-describe-sym-command."
612 (interactive (lisp-symprompt "Describe" (lisp-var-at-pt)))
926d5019
JB
613 (comint-proc-query (inferior-lisp-proc)
614 (format lisp-describe-sym-command sym)))
2f790b20
JB
615
616\f
926d5019 617(defvar inferior-lisp-buffer nil "*The current inferior-lisp process buffer.
2f790b20
JB
618
619MULTIPLE PROCESS SUPPORT
620===========================================================================
926d5019
JB
621Inf-lisp.el supports, in a fairly simple fashion, running multiple
622Lisp processes. To run multiple Lisp processes, you start the first up
623with \\[inferior-lisp]. It will be in a buffer named *inferior-lisp*.
624Rename this buffer with \\[rename-buffer]. You may now start up a new
625process with another \\[inferior-lisp]. It will be in a new buffer,
626named *inferior-lisp*. You can switch between the different process
627buffers with \\[switch-to-buffer].
2f790b20
JB
628
629Commands that send text from source buffers to Lisp processes --
630like lisp-eval-defun or lisp-show-arglist -- have to choose a process
631to send to, when you have more than one Lisp process around. This
926d5019 632is determined by the global variable inferior-lisp-buffer. Suppose you
2f790b20 633have three inferior lisps running:
926d5019
JB
634 Buffer Process
635 foo inferior-lisp
636 bar inferior-lisp<2>
637 *inferior-lisp* inferior-lisp<3>
daa37602 638If you do a \\[lisp-eval-defun] command on some Lisp source code,
2f790b20
JB
639what process do you send it to?
640
926d5019 641- If you're in a process buffer (foo, bar, or *inferior-lisp*),
2f790b20
JB
642 you send it to that process.
643- If you're in some other buffer (e.g., a source file), you
926d5019
JB
644 send it to the process attached to buffer inferior-lisp-buffer.
645This process selection is performed by function inferior-lisp-proc.
2f790b20 646
926d5019
JB
647Whenever \\[inferior-lisp] fires up a new process, it resets
648inferior-lisp-buffer to be the new process's buffer. If you only run
649one process, this will do the right thing. If you run multiple
650processes, you can change inferior-lisp-buffer to another process
651buffer with \\[set-variable].
2f790b20 652
eb8c3be9 653More sophisticated approaches are, of course, possible. If you find yourself
2f790b20
JB
654needing to switch back and forth between multiple processes frequently,
655you may wish to consider ilisp.el, a larger, more sophisticated package
656for running inferior Lisp processes. The approach taken here is for a
657minimal, simple implementation. Feel free to extend it.")
658
926d5019
JB
659(defun inferior-lisp-proc ()
660 "Returns the current inferior-lisp process. See variable inferior-lisp-buffer."
2f790b20
JB
661 (let ((proc (get-buffer-process (if (eq major-mode 'inferior-lisp-mode)
662 (current-buffer)
926d5019 663 inferior-lisp-buffer))))
2f790b20 664 (or proc
926d5019 665 (error "No current process. See variable inferior-lisp-buffer"))))
2f790b20
JB
666
667
668;;; Do the user's customisation...
669;;;===============================
926d5019
JB
670(defvar inferior-lisp-load-hook nil
671 "This hook is run when inferior-lisp is loaded in.
2f790b20 672This is a good place to put keybindings.")
926d5019
JB
673
674(run-hooks 'inferior-lisp-load-hook)
2f790b20
JB
675
676;;; CHANGE LOG
677;;; ===========================================================================
926d5019
JB
678;;; 7/21/92 Jim Blandy
679;;; - Changed all uses of the cmulisp name or prefix to inferior-lisp;
680;;; this is now the official inferior lisp package. Use the global
681;;; ChangeLog from now on.
2f790b20
JB
682;;; 5/24/90 Olin
683;;; - Split cmulisp and cmushell modes into separate files.
684;;; Not only is this a good idea, it's apparently the way it'll be rel 19.
685;;; - Upgraded process sends to use comint-send-string instead of
686;;; process-send-string.
687;;; - Explicit references to process "cmulisp" have been replaced with
688;;; (cmulisp-proc). This allows better handling of multiple process bufs.
689;;; - Added process query and var/function/symbol documentation
690;;; commands. Based on code written by Douglas Roberts.
691;;; - Added lisp-eval-last-sexp, bound to C-x C-e.
692;;;
693;;; 9/20/90 Olin
694;;; Added a save-restriction to lisp-fn-called-at-pt. This bug and fix
695;;; reported by Lennart Staflin.
696;;;
697;;; 3/12/90 Olin
698;;; - lisp-load-file and lisp-compile-file no longer switch-to-lisp.
699;;; Tale suggested this.
daa37602
JB
700;;; - Reversed this decision 7/15/91. You need the visual feedback.
701;;;
702;;; 7/25/91 Olin
703;;; Changed all keybindings of the form C-c <letter>. These are
704;;; supposed to be reserved for the user to bind. This affected
705;;; mainly the compile/eval-defun/region[-and-go] commands.
706;;; This was painful, but necessary to adhere to the gnumacs standard.
707;;; For some backwards compatibility, see the
708;;; cmulisp-install-letter-bindings
709;;; function.
710;;;
711;;; 8/2/91 Olin
712;;; - The lisp-compile/eval-defun/region commands now take a prefix arg,
713;;; which means switch-to-lisp after sending the text to the Lisp process.
714;;; This obsoletes all the -and-go commands. The -and-go commands are
715;;; kept around for historical reasons, and because the user can bind
716;;; them to key sequences shorter than C-u C-c C-<letter>.
717;;; - If M-x cmulisp is invoked with a prefix arg, it allows you to
718;;; edit the command line.
49116ac0 719
926d5019 720(provide 'inf-lisp)
49116ac0 721
926d5019 722;;; inf-lisp.el ends here