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