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