(mail-interactive): Change default.
[bpt/emacs.git] / lisp / ielm.el
CommitLineData
813f532d 1;;; ielm.el --- interaction mode for Emacs Lisp
b578f267 2
c90f2757 3;; Copyright (C) 1994, 2001, 2002, 2003, 2004, 2005,
409cc4a3 4;; 2006, 2007, 2008 Free Software Foundation, Inc.
813f532d
RS
5
6;; Author: David Smith <maa036@lancaster.ac.uk>
4228277d 7;; Maintainer: FSF
813f532d
RS
8;; Created: 25 Feb 1994
9;; Keywords: lisp
10
11;; This file is part of GNU Emacs.
12
eb3fa2cf 13;; GNU Emacs is free software: you can redistribute it and/or modify
813f532d 14;; it under the terms of the GNU General Public License as published by
eb3fa2cf
GM
15;; the Free Software Foundation, either version 3 of the License, or
16;; (at your option) any later version.
813f532d
RS
17
18;; GNU Emacs is distributed in the hope that it will be useful,
19;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21;; GNU General Public License for more details.
22
23;; You should have received a copy of the GNU General Public License
eb3fa2cf 24;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
813f532d
RS
25
26;;; Commentary:
27
e848854a 28;; Provides a nice interface to evaluating Emacs Lisp expressions.
813f532d
RS
29;; Input is handled by the comint package, and output is passed
30;; through the pretty-printer.
31
813f532d
RS
32;; To start: M-x ielm. Type C-h m in the *ielm* buffer for more info.
33
813f532d
RS
34;;; Code:
35
36(require 'comint)
37(require 'pp)
38
39;;; User variables
40
94114394
RS
41(defgroup ielm nil
42 "Interaction mode for Emacs Lisp."
43 :group 'lisp)
44
45
46(defcustom ielm-noisy t
47 "*If non-nil, IELM will beep on error."
48 :type 'boolean
49 :group 'ielm)
813f532d 50
759f960a
LT
51(defcustom ielm-prompt-read-only t
52 "If non-nil, the IELM prompt is read only.
7655d378 53The read only region includes the newline before the prompt.
759f960a 54Setting this variable does not affect existing IELM runs.
016b8f71 55This works by setting the buffer-local value of `comint-prompt-read-only'.
7655d378
LT
56Setting that value directly affects new prompts in the current buffer.
57
58If this option is enabled, then the safe way to temporarily
59override the read-only-ness of ielm prompts is to call
60`comint-kill-whole-line' or `comint-kill-region' with no
61narrowing in effect. This way you will be certain that none of
62the remaining prompts will be accidentally messed up. You may
63wish to put something like the following in your `.emacs' file:
64
65\(add-hook 'ielm-mode-hook
66 '(lambda ()
1ab3c04f 67 (define-key ielm-map \"\\C-w\" 'comint-kill-region)
7655d378
LT
68 (define-key ielm-map [C-S-backspace]
69 'comint-kill-whole-line)))
70
71If you set `comint-prompt-read-only' to t, you might wish to use
72`comint-mode-hook' and `comint-mode-map' instead of
73`ielm-mode-hook' and `ielm-map'. That will affect all comint
74buffers, including ielm buffers. If you sometimes use ielm on
75text-only terminals or with `emacs -nw', you might wish to use
76another binding for `comint-kill-whole-line'."
759f960a
LT
77 :type 'boolean
78 :group 'ielm
bf247b6e 79 :version "22.1")
759f960a 80
40cf8f25 81(defcustom ielm-prompt "ELISP> "
759f960a 82 "Prompt used in IELM.
016b8f71 83Setting this variable does not affect existing IELM runs.
ee9cd72d
LT
84
85Interrupting the IELM process with \\<ielm-map>\\[comint-interrupt-subjob],
86and then restarting it using \\[ielm], makes the then current
016b8f71 87default value affect _new_ prompts. Unless the new prompt
ee9cd72d
LT
88differs only in text properties from the old one, IELM will no
89longer recognize the old prompts. However, executing \\[ielm]
90does not update the prompt of an *ielm* buffer with a running process.
9eca7c03 91For IELM buffers that are not called `*ielm*', you can execute
ee9cd72d
LT
92\\[inferior-emacs-lisp-mode] in that IELM buffer to update the value,
93for new prompts. This works even if the buffer has a running process."
40cf8f25 94 :type 'string
759f960a 95 :group 'ielm)
813f532d 96
016b8f71
LT
97(defvar ielm-prompt-internal "ELISP> "
98 "Stored value of `ielm-prompt' in the current IELM buffer.
99This is an internal variable used by IELM. Its purpose is to
100prevent a running IELM process from being messed up when the user
101customizes `ielm-prompt'.")
102
94114394 103(defcustom ielm-dynamic-return t
291cfc0c 104 "*Controls whether \\<ielm-map>\\[ielm-return] has intelligent behavior in IELM.
e848854a 105If non-nil, \\[ielm-return] evaluates input for complete sexps, or inserts a newline
94114394
RS
106and indents for incomplete sexps. If nil, always inserts newlines."
107 :type 'boolean
108 :group 'ielm)
e848854a 109
94114394 110(defcustom ielm-dynamic-multiline-inputs t
e848854a
RS
111 "*Force multiline inputs to start from column zero?
112If non-nil, after entering the first line of an incomplete sexp, a newline
113will be inserted after the prompt, moving the input to the next line.
114This gives more frame width for large indented sexps, and allows functions
94114394
RS
115such as `edebug-defun' to work with such inputs."
116 :type 'boolean
117 :group 'ielm)
813f532d 118
94114394
RS
119(defcustom ielm-mode-hook nil
120 "*Hooks to be run when IELM (`inferior-emacs-lisp-mode') is started."
10fea268 121 :options '(turn-on-eldoc-mode)
94114394
RS
122 :type 'hook
123 :group 'ielm)
813f532d 124
d38e7d5f
RS
125(defvar * nil
126 "Most recent value evaluated in IELM.")
127
128(defvar ** nil
129 "Second-most-recent value evaluated in IELM.")
130
131(defvar *** nil
132 "Third-most-recent value evaluated in IELM.")
690ec649 133
565f89ec
SM
134(defvar ielm-match-data nil
135 "Match data saved at the end of last command.")
136
1322516b 137(defvar *1 nil
5d9655bb
RS
138 "During IELM evaluation, most recent value evaluated in IELM.
139Normally identical to `*'. However, if the working buffer is an IELM
140buffer, distinct from the process buffer, then `*' gives the value in
71296446 141the working buffer, `*1' the value in the process buffer.
5d9655bb
RS
142The intended value is only accessible during IELM evaluation.")
143
144(defvar *2 nil
145 "During IELM evaluation, second-most-recent value evaluated in IELM.
146Normally identical to `**'. However, if the working buffer is an IELM
147buffer, distinct from the process buffer, then `**' gives the value in
148the working buffer, `*2' the value in the process buffer.
149The intended value is only accessible during IELM evaluation.")
150
151(defvar *3 nil
152 "During IELM evaluation, third-most-recent value evaluated in IELM.
153Normally identical to `***'. However, if the working buffer is an IELM
154buffer, distinct from the process buffer, then `***' gives the value in
155the working buffer, `*3' the value in the process buffer.
156The intended value is only accessible during IELM evaluation.")
157
813f532d
RS
158;;; System variables
159
160(defvar ielm-working-buffer nil
e848854a
RS
161 "Buffer in which IELM sexps will be evaluated.
162This variable is buffer-local.")
813f532d 163
690ec649 164(defvar ielm-header
0a13146e 165 "*** Welcome to IELM *** Type (describe-mode) for help.\n"
e848854a 166 "Message to display when IELM is started.")
813f532d
RS
167
168(defvar ielm-map nil)
169(if ielm-map nil
6546555e 170 (if (featurep 'xemacs)
813f532d
RS
171 ;; Lemacs
172 (progn
173 (setq ielm-map (make-sparse-keymap))
174 (set-keymap-parent ielm-map comint-mode-map))
175 ;; FSF
176 (setq ielm-map (cons 'keymap comint-mode-map)))
177 (define-key ielm-map "\t" 'comint-dynamic-complete)
178 (define-key ielm-map "\C-m" 'ielm-return)
e848854a
RS
179 (define-key ielm-map "\C-j" 'ielm-send-input)
180 (define-key ielm-map "\e\C-x" 'eval-defun) ; for consistency with
181 (define-key ielm-map "\e\t" 'lisp-complete-symbol) ; lisp-interaction-mode
690ec649 182 ;; These bindings are from `lisp-mode-shared-map' -- can you inherit
e848854a 183 ;; from more than one keymap??
690ec649 184 (define-key ielm-map "\e\C-q" 'indent-sexp)
e848854a
RS
185 (define-key ielm-map "\177" 'backward-delete-char-untabify)
186 ;; Some convenience bindings for setting the working buffer
187 (define-key ielm-map "\C-c\C-b" 'ielm-change-working-buffer)
188 (define-key ielm-map "\C-c\C-f" 'ielm-display-working-buffer)
189 (define-key ielm-map "\C-c\C-v" 'ielm-print-working-buffer))
813f532d 190
9d42eea3 191(defvar ielm-font-lock-keywords
016b8f71 192 '(("\\(^\\*\\*\\*[^*]+\\*\\*\\*\\)\\(.*$\\)"
883212ce
SM
193 (1 font-lock-comment-face)
194 (2 font-lock-constant-face)))
9d42eea3 195 "Additional expressions to highlight in ielm buffers.")
690ec649 196
813f532d
RS
197;;; Completion stuff
198
199(defun ielm-tab nil
e5927b52 200 "Possibly indent the current line as Lisp code."
813f532d
RS
201 (interactive)
202 (if (or (eq (preceding-char) ?\n)
203 (eq (char-syntax (preceding-char)) ? ))
204 (progn
205 (ielm-indent-line)
206 t)))
690ec649 207
813f532d 208(defun ielm-complete-symbol nil
e5927b52 209 "Complete the Lisp symbol before point."
e848854a
RS
210 ;; A wrapper for lisp-complete symbol that returns non-nil if
211 ;; completion has occurred
813f532d 212 (let* ((btick (buffer-modified-tick))
e58df0dc 213 (cbuffer (get-buffer "*Completions*"))
813f532d
RS
214 (ctick (and cbuffer (buffer-modified-tick cbuffer))))
215 (lisp-complete-symbol)
216 ;; completion has occurred if:
690ec649 217 (or
813f532d 218 ;; the buffer has been modified
690ec649 219 (not (= btick (buffer-modified-tick)))
a7acbbe4 220 ;; a completions buffer has been modified or created
813f532d
RS
221 (if cbuffer
222 (not (= ctick (buffer-modified-tick cbuffer)))
e58df0dc 223 (get-buffer "*Completions*")))))
813f532d
RS
224
225(defun ielm-complete-filename nil
e848854a 226 "Dynamically complete filename before point, if in a string."
813f532d
RS
227 (if (nth 3 (parse-partial-sexp comint-last-input-start (point)))
228 (comint-dynamic-complete-filename)))
690ec649 229
813f532d 230(defun ielm-indent-line nil
e848854a 231 "Indent the current line as Lisp code if it is not a prompt line."
3250010d 232 (when (save-excursion (comint-bol) (bolp))
813f532d
RS
233 (lisp-indent-line)))
234
e848854a
RS
235;;; Working buffer manipulation
236
237(defun ielm-print-working-buffer nil
238 "Print the current IELM working buffer's name in the echo area."
239 (interactive)
240 (message "The current working buffer is: %s" (buffer-name ielm-working-buffer)))
241
242(defun ielm-display-working-buffer nil
243 "Display the current IELM working buffer.
244Don't forget that selecting that buffer will change its value of `point'
245to its value of `window-point'!"
246 (interactive)
247 (display-buffer ielm-working-buffer)
248 (ielm-print-working-buffer))
249
250(defun ielm-change-working-buffer (buf)
251 "Change the current IELM working buffer to BUF.
252This is the buffer in which all sexps entered at the IELM prompt are
253evaluated. You can achieve the same effect with a call to
254`set-buffer' at the IELM prompt."
255 (interactive "bSet working buffer to: ")
256 (setq ielm-working-buffer (or (get-buffer buf) (error "No such buffer")))
257 (ielm-print-working-buffer))
258
813f532d
RS
259;;; Other bindings
260
261(defun ielm-return nil
e848854a
RS
262 "Newline and indent, or evaluate the sexp before the prompt.
263Complete sexps are evaluated; for incomplete sexps inserts a newline
264and indents. If however `ielm-dynamic-return' is nil, this always
265simply inserts a newline."
813f532d 266 (interactive)
690ec649
SS
267 (if ielm-dynamic-return
268 (let ((state
813f532d
RS
269 (save-excursion
270 (end-of-line)
271 (parse-partial-sexp (ielm-pm)
272 (point)))))
273 (if (and (< (car state) 1) (not (nth 3 state)))
274 (ielm-send-input)
e848854a
RS
275 (if (and ielm-dynamic-multiline-inputs
276 (save-excursion
277 (beginning-of-line)
278 (looking-at comint-prompt-regexp)))
279 (save-excursion
280 (goto-char (ielm-pm))
281 (newline 1)))
813f532d
RS
282 (newline-and-indent)))
283 (newline)))
284
94aba130
RS
285(defvar ielm-input)
286
813f532d 287(defun ielm-input-sender (proc input)
690ec649 288 ;; Just sets the variable ielm-input, which is in the scope of
e848854a 289 ;; `ielm-send-input's call.
813f532d
RS
290 (setq ielm-input input))
291
292(defun ielm-send-input nil
e848854a 293 "Evaluate the Emacs Lisp expression after the prompt."
813f532d 294 (interactive)
016b8f71 295 (let (ielm-input) ; set by ielm-input-sender
813f532d
RS
296 (comint-send-input) ; update history, markers etc.
297 (ielm-eval-input ielm-input)))
298
299;;; Utility functions
300
6ad18d45 301(defun ielm-is-whitespace-or-comment (string)
2ef180f7 302 "Return non-nil if STRING is all whitespace or a comment."
6ad18d45
BG
303 (or (string= string "")
304 (string-match "\\`[ \t\n]*\\(?:;.*\\)*\\'" string)))
813f532d 305
813f532d
RS
306;;; Evaluation
307
e848854a
RS
308(defun ielm-eval-input (ielm-string)
309 "Evaluate the Lisp expression IELM-STRING, and pretty-print the result."
813f532d 310 ;; This is the function that actually `sends' the input to the
e848854a 311 ;; `inferior Lisp process'. All comint-send-input does is works out
813f532d
RS
312 ;; what that input is. What this function does is evaluates that
313 ;; input and produces `output' which gets inserted into the buffer,
314 ;; along with a new prompt. A better way of doing this might have
315 ;; been to actually send the output to the `cat' process, and write
316 ;; this as in output filter that converted sexps in the output
317 ;; stream to their evaluated value. But that would have involved
318 ;; more process coordination than I was happy to deal with.
e848854a
RS
319 ;;
320 ;; NOTE: all temporary variables in this function will be in scope
321 ;; during the eval, and so need to have non-clashing names.
322 (let (ielm-form ; form to evaluate
323 ielm-pos ; End posn of parse in string
324 ielm-result ; Result, or error message
325 ielm-error-type ; string, nil if no error
326 (ielm-output "") ; result to display
327 (ielm-wbuf ielm-working-buffer) ; current buffer after evaluation
328 (ielm-pmark (ielm-pm)))
6ad18d45 329 (if (not (ielm-is-whitespace-or-comment ielm-string))
813f532d
RS
330 (progn
331 (condition-case err
332 (let (rout)
e848854a
RS
333 (setq rout (read-from-string ielm-string))
334 (setq ielm-form (car rout))
335 (setq ielm-pos (cdr rout)))
568bbe5e 336 (error (setq ielm-result (error-message-string err))
e848854a
RS
337 (setq ielm-error-type "Read error")))
338 (if ielm-error-type nil
339 ;; Make sure working buffer has not been killed
340 (if (not (buffer-name ielm-working-buffer))
341 (setq ielm-result "Working buffer has been killed"
342 ielm-error-type "IELM Error"
343 ielm-wbuf (current-buffer))
6ad18d45
BG
344 (if (ielm-is-whitespace-or-comment
345 (substring ielm-string ielm-pos))
5d9655bb
RS
346 ;; To correctly handle the ielm-local variables *,
347 ;; ** and ***, we need a temporary buffer to be
348 ;; current at entry to the inner of the next two let
349 ;; forms. We need another temporary buffer to exit
350 ;; that same let. To avoid problems, neither of
351 ;; these buffers should be alive during the
352 ;; evaluation of ielm-form.
353 (let ((*1 *)
354 (*2 **)
355 (*3 ***)
356 ielm-temp-buffer)
565f89ec 357 (set-match-data ielm-match-data)
e848854a 358 (save-excursion
5d9655bb
RS
359 (with-temp-buffer
360 (condition-case err
361 (unwind-protect
362 ;; The next let form creates default
363 ;; bindings for *, ** and ***. But
364 ;; these default bindings are
365 ;; identical to the ielm-local
366 ;; bindings. Hence, during the
367 ;; evaluation of ielm-form, the
368 ;; ielm-local values are going to be
369 ;; used in all buffers except for
370 ;; other ielm buffers, which override
371 ;; them. Normally, the variables *1,
372 ;; *2 and *3 also have default
373 ;; bindings, which are not overridden.
374 (let ((* *1)
375 (** *2)
376 (*** *3))
377 (kill-buffer (current-buffer))
378 (set-buffer ielm-wbuf)
379 (setq ielm-result (eval ielm-form))
380 (setq ielm-wbuf (current-buffer))
381 (setq
382 ielm-temp-buffer
383 (generate-new-buffer " *ielm-temp*"))
384 (set-buffer ielm-temp-buffer))
385 (when ielm-temp-buffer
386 (kill-buffer ielm-temp-buffer)))
5967d963 387 (error (setq ielm-result (error-message-string err))
5d9655bb
RS
388 (setq ielm-error-type "Eval error"))
389 (quit (setq ielm-result "Quit during evaluation")
390 (setq ielm-error-type "Eval error")))))
565f89ec 391 (setq ielm-match-data (match-data)))
e848854a
RS
392 (setq ielm-error-type "IELM error")
393 (setq ielm-result "More than one sexp in input"))))
813f532d
RS
394
395 ;; If the eval changed the current buffer, mention it here
e848854a
RS
396 (if (eq ielm-wbuf ielm-working-buffer) nil
397 (message "current buffer is now: %s" ielm-wbuf)
398 (setq ielm-working-buffer ielm-wbuf))
813f532d 399
e848854a
RS
400 (goto-char ielm-pmark)
401 (if (not ielm-error-type)
813f532d
RS
402 (condition-case err
403 ;; Self-referential objects cause loops in the printer, so
404 ;; trap quits here. May as well do errors, too
e848854a
RS
405 (setq ielm-output (concat ielm-output (pp-to-string ielm-result)))
406 (error (setq ielm-error-type "IELM Error")
407 (setq ielm-result "Error during pretty-printing (bug in pp)"))
408 (quit (setq ielm-error-type "IELM Error")
409 (setq ielm-result "Quit during pretty-printing"))))
410 (if ielm-error-type
813f532d
RS
411 (progn
412 (if ielm-noisy (ding))
e848854a
RS
413 (setq ielm-output (concat ielm-output "*** " ielm-error-type " *** "))
414 (setq ielm-output (concat ielm-output ielm-result)))
d38e7d5f 415 ;; There was no error, so shift the *** values
71d54f88
RS
416 (setq *** **)
417 (setq ** *)
418 (setq * ielm-result))
e848854a 419 (setq ielm-output (concat ielm-output "\n"))))
016b8f71 420 (setq ielm-output (concat ielm-output ielm-prompt-internal))
e848854a 421 (comint-output-filter (ielm-process) ielm-output)))
813f532d
RS
422
423;;; Process and marker utilities
424
425(defun ielm-process nil
e848854a 426 ;; Return the current buffer's process.
813f532d
RS
427 (get-buffer-process (current-buffer)))
428
429(defun ielm-pm nil
e848854a 430 ;; Return the process mark of the current buffer.
813f532d
RS
431 (process-mark (get-buffer-process (current-buffer))))
432
433(defun ielm-set-pm (pos)
e848854a 434 ;; Set the process mark in the current buffer to POS.
813f532d
RS
435 (set-marker (process-mark (get-buffer-process (current-buffer))) pos))
436
437;;; Major mode
438
95b20f3b
RS
439(put 'inferior-emacs-lisp-mode 'mode-class 'special)
440
813f532d 441(defun inferior-emacs-lisp-mode nil
e848854a
RS
442 "Major mode for interactively evaluating Emacs Lisp expressions.
443Uses the interface provided by `comint-mode' (which see).
444
66f06793
SM
445* \\<ielm-map>\\[ielm-send-input] evaluates the sexp following the prompt. There must be at most
446 one top level sexp per prompt.
813f532d 447
e848854a
RS
448* \\[ielm-return] inserts a newline and indents, or evaluates a
449 complete expression (but see variable `ielm-dynamic-return').
450 Inputs longer than one line are moved to the line following the
451 prompt (but see variable `ielm-dynamic-multiline-inputs').
452
690ec649 453* \\[comint-dynamic-complete] completes Lisp symbols (or filenames, within strings),
e848854a 454 or indents the line if there is nothing to complete.
813f532d 455
e848854a
RS
456The current working buffer may be changed (with a call to
457`set-buffer', or with \\[ielm-change-working-buffer]), and its value
458is preserved between successive evaluations. In this way, expressions
459may be evaluated in a different buffer than the *ielm* buffer.
76364803
JB
460By default, its name is shown on the mode line; you can always display
461it with \\[ielm-print-working-buffer], or the buffer itself with \\[ielm-display-working-buffer].
813f532d 462
5d9655bb
RS
463During evaluations, the values of the variables `*', `**', and `***'
464are the results of the previous, second previous and third previous
465evaluations respectively. If the working buffer is another IELM
466buffer, then the values in the working buffer are used. The variables
467`*1', `*2' and `*3', yield the process buffer values.
468
e848854a
RS
469Expressions evaluated by IELM are not subject to `debug-on-quit' or
470`debug-on-error'.
813f532d 471
291cfc0c 472The behavior of IELM may be customized with the following variables:
0382cf8f 473* To stop beeping on error, set `ielm-noisy' to nil.
813f532d 474* If you don't like the prompt, you can change it by setting `ielm-prompt'.
759f960a
LT
475* If you do not like that the prompt is (by default) read-only, set
476 `ielm-prompt-read-only' to nil.
0382cf8f 477* Set `ielm-dynamic-return' to nil for bindings like `lisp-interaction-mode'.
813f532d
RS
478* Entry to this mode runs `comint-mode-hook' and `ielm-mode-hook'
479 (in that order).
480
0382cf8f 481Customized bindings may be defined in `ielm-map', which currently contains:
813f532d
RS
482\\{ielm-map}"
483 (interactive)
9c5e65b2
LT
484 (delay-mode-hooks
485 (comint-mode))
813f532d 486 (setq comint-prompt-regexp (concat "^" (regexp-quote ielm-prompt)))
85ab9f4e 487 (set (make-local-variable 'paragraph-separate) "\\'")
813f532d
RS
488 (make-local-variable 'paragraph-start)
489 (setq paragraph-start comint-prompt-regexp)
490 (setq comint-input-sender 'ielm-input-sender)
491 (setq comint-process-echoes nil)
27cfbf4b 492 (make-local-variable 'comint-dynamic-complete-functions)
016b8f71
LT
493 (set (make-local-variable 'ielm-prompt-internal) ielm-prompt)
494 (set (make-local-variable 'comint-prompt-read-only) ielm-prompt-read-only)
690ec649 495 (setq comint-dynamic-complete-functions
813f532d 496 '(ielm-tab comint-replace-by-expanded-history ielm-complete-filename ielm-complete-symbol))
e848854a 497 (setq comint-get-old-input 'ielm-get-old-input)
34ce46c8 498 (make-local-variable 'comint-completion-addsuffix)
016b8f71 499 (setq comint-completion-addsuffix '("/" . ""))
813f532d
RS
500 (setq major-mode 'inferior-emacs-lisp-mode)
501 (setq mode-name "IELM")
76364803 502 (setq mode-line-process '(":%s on " (:eval (buffer-name ielm-working-buffer))))
813f532d
RS
503 (use-local-map ielm-map)
504 (set-syntax-table emacs-lisp-mode-syntax-table)
505
506 (make-local-variable 'indent-line-function)
507 (make-local-variable 'ielm-working-buffer)
508 (setq ielm-working-buffer (current-buffer))
509 (setq indent-line-function 'ielm-indent-line)
950086e6
KH
510 (make-local-variable 'fill-paragraph-function)
511 (setq fill-paragraph-function 'lisp-fill-paragraph)
813f532d 512
e848854a 513 ;; Value holders
fed9da13 514 (make-local-variable '*)
5d9655bb 515 (setq * nil)
fed9da13 516 (make-local-variable '**)
5d9655bb 517 (setq ** nil)
fed9da13 518 (make-local-variable '***)
5d9655bb 519 (setq *** nil)
565f89ec 520 (set (make-local-variable 'ielm-match-data) nil)
813f532d 521
9d42eea3
RS
522 ;; font-lock support
523 (make-local-variable 'font-lock-defaults)
690ec649 524 (setq font-lock-defaults
9d42eea3 525 '(ielm-font-lock-keywords nil nil ((?: . "w") (?- . "w") (?* . "w"))))
690ec649 526
813f532d 527 ;; A dummy process to keep comint happy. It will never get any input
20b13009 528 (unless (comint-check-proc (current-buffer))
33a65176
JR
529 ;; Was cat, but on non-Unix platforms that might not exist, so
530 ;; use hexl instead, which is part of the Emacs distribution.
66f06793
SM
531 (condition-case nil
532 (start-process "ielm" (current-buffer) "hexl")
533 (file-error (start-process "ielm" (current-buffer) "cat")))
e5927b52 534 (set-process-query-on-exit-flag (ielm-process) nil)
813f532d 535 (goto-char (point-max))
71296446 536
20b13009
MB
537 ;; Lisp output can include raw characters that confuse comint's
538 ;; carriage control code.
539 (set (make-local-variable 'comint-inhibit-carriage-motion) t)
540
813f532d
RS
541 ;; Add a silly header
542 (insert ielm-header)
543 (ielm-set-pm (point-max))
85ab9f4e 544 (unless comint-use-prompt-regexp
76364803
JB
545 (let ((inhibit-read-only t))
546 (add-text-properties
547 (point-min) (point-max)
548 '(rear-nonsticky t field output inhibit-line-move-field-capture t))))
016b8f71 549 (comint-output-filter (ielm-process) ielm-prompt-internal)
813f532d
RS
550 (set-marker comint-last-input-start (ielm-pm))
551 (set-process-filter (get-buffer-process (current-buffer)) 'comint-output-filter))
20b13009 552
d395b3b5 553 (run-mode-hooks 'ielm-mode-hook))
813f532d 554
e848854a
RS
555(defun ielm-get-old-input nil
556 ;; Return the previous input surrounding point
557 (save-excursion
558 (beginning-of-line)
559 (if (looking-at comint-prompt-regexp) nil
560 (re-search-backward comint-prompt-regexp))
561 (comint-skip-prompt)
562 (buffer-substring (point) (progn (forward-sexp 1) (point)))))
563
813f532d
RS
564;;; User command
565
9e983c78
RS
566;;;###autoload (add-hook 'same-window-buffer-names "*ielm*")
567
e848854a 568;;;###autoload
813f532d 569(defun ielm nil
e848854a 570 "Interactively evaluate Emacs Lisp expressions.
9e983c78 571Switches to the buffer `*ielm*', or creates it if it does not exist."
813f532d 572 (interactive)
ee9cd72d
LT
573 (let (old-point)
574 (unless (comint-check-proc "*ielm*")
575 (with-current-buffer (get-buffer-create "*ielm*")
016b8f71 576 (unless (zerop (buffer-size)) (setq old-point (point)))
ee9cd72d
LT
577 (inferior-emacs-lisp-mode)))
578 (pop-to-buffer "*ielm*")
579 (when old-point (push-mark old-point))))
813f532d 580
896546cd
RS
581(provide 'ielm)
582
cbee283d 583;; arch-tag: ef60e4c0-9c4f-4bdb-8402-271313329790
e848854a 584;;; ielm.el ends here