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