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