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