* lisp/simple.el (eval-expression-print-format): Don't check for
[bpt/emacs.git] / lisp / ielm.el
CommitLineData
04a19a79 1;;; -*- lexical-binding: t -*-
813f532d 2;;; ielm.el --- interaction mode for Emacs Lisp
b578f267 3
ab422c4d 4;; Copyright (C) 1994, 2001-2013 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
61c11870 47 "If non-nil, IELM will beep on error."
94114394
RS
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
61c11870 59override the read-only-ness of IELM prompts is to call
7655d378
LT
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
865fe16f 63wish to put something like the following in your init file:
7655d378
LT
64
65\(add-hook 'ielm-mode-hook
04a19a79
DC
66 (lambda ()
67 (define-key ielm-map \"\\C-w\" 'comint-kill-region)
68 (define-key ielm-map [C-S-backspace]
69 'comint-kill-whole-line)))
7655d378
LT
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
61c11870 74buffers, including IELM buffers. If you sometimes use IELM on
7655d378
LT
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
61c11870 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
61c11870 111 "Force multiline inputs to start from column zero?
e848854a
RS
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 119(defcustom ielm-mode-hook nil
61c11870 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)
61c11870 124(defvaralias 'inferior-emacs-lisp-mode-hook 'ielm-mode-hook)
813f532d 125
d38e7d5f
RS
126(defvar * nil
127 "Most recent value evaluated in IELM.")
128
129(defvar ** nil
130 "Second-most-recent value evaluated in IELM.")
131
132(defvar *** nil
133 "Third-most-recent value evaluated in IELM.")
690ec649 134
565f89ec
SM
135(defvar ielm-match-data nil
136 "Match data saved at the end of last command.")
137
1322516b 138(defvar *1 nil
5d9655bb
RS
139 "During IELM evaluation, most recent value evaluated in IELM.
140Normally identical to `*'. However, if the working buffer is an IELM
141buffer, distinct from the process buffer, then `*' gives the value in
71296446 142the working buffer, `*1' the value in the process buffer.
5d9655bb
RS
143The intended value is only accessible during IELM evaluation.")
144
145(defvar *2 nil
146 "During IELM evaluation, second-most-recent value evaluated in IELM.
147Normally identical to `**'. However, if the working buffer is an IELM
148buffer, distinct from the process buffer, then `**' gives the value in
149the working buffer, `*2' the value in the process buffer.
150The intended value is only accessible during IELM evaluation.")
151
152(defvar *3 nil
153 "During IELM evaluation, third-most-recent value evaluated in IELM.
154Normally identical to `***'. However, if the working buffer is an IELM
155buffer, distinct from the process buffer, then `***' gives the value in
156the working buffer, `*3' the value in the process buffer.
157The intended value is only accessible during IELM evaluation.")
158
813f532d
RS
159;;; System variables
160
161(defvar ielm-working-buffer nil
e848854a
RS
162 "Buffer in which IELM sexps will be evaluated.
163This variable is buffer-local.")
813f532d 164
690ec649 165(defvar ielm-header
0a13146e 166 "*** Welcome to IELM *** Type (describe-mode) for help.\n"
e848854a 167 "Message to display when IELM is started.")
813f532d 168
61c11870
JB
169(defvar ielm-map
170 (let ((map (make-sparse-keymap)))
d209d4a9 171 (define-key map "\t" 'completion-at-point)
61c11870 172 (define-key map "\C-m" 'ielm-return)
04a19a79 173 (define-key map "\e\C-m" 'ielm-return-for-effect)
61c11870
JB
174 (define-key map "\C-j" 'ielm-send-input)
175 (define-key map "\e\C-x" 'eval-defun) ; for consistency with
51ef56c4 176 (define-key map "\e\t" 'completion-at-point) ; lisp-interaction-mode
61c11870
JB
177 ;; These bindings are from `lisp-mode-shared-map' -- can you inherit
178 ;; from more than one keymap??
179 (define-key map "\e\C-q" 'indent-sexp)
180 (define-key map "\177" 'backward-delete-char-untabify)
181 ;; Some convenience bindings for setting the working buffer
182 (define-key map "\C-c\C-b" 'ielm-change-working-buffer)
183 (define-key map "\C-c\C-f" 'ielm-display-working-buffer)
184 (define-key map "\C-c\C-v" 'ielm-print-working-buffer)
185 map)
186 "Keymap for IELM mode.")
187(defvaralias 'inferior-emacs-lisp-mode-map 'ielm-map)
813f532d 188
fe1eb856
RS
189(easy-menu-define ielm-menu ielm-map
190 "IELM mode menu."
191 '("IELM"
192 ["Change Working Buffer" ielm-change-working-buffer t]
193 ["Display Working Buffer" ielm-display-working-buffer t]
194 ["Print Working Buffer" ielm-print-working-buffer t]))
195
9d42eea3 196(defvar ielm-font-lock-keywords
016b8f71 197 '(("\\(^\\*\\*\\*[^*]+\\*\\*\\*\\)\\(.*$\\)"
883212ce
SM
198 (1 font-lock-comment-face)
199 (2 font-lock-constant-face)))
61c11870 200 "Additional expressions to highlight in IELM buffers.")
690ec649 201
813f532d
RS
202;;; Completion stuff
203
204(defun ielm-tab nil
e5927b52 205 "Possibly indent the current line as Lisp code."
813f532d 206 (interactive)
61c11870 207 (when (or (eq (preceding-char) ?\n)
04a19a79 208 (eq (char-syntax (preceding-char)) ?\s))
61c11870
JB
209 (ielm-indent-line)
210 t))
690ec649 211
813f532d 212(defun ielm-complete-symbol nil
e5927b52 213 "Complete the Lisp symbol before point."
d209d4a9 214 ;; A wrapper for completion-at-point that returns non-nil if
e848854a 215 ;; completion has occurred
813f532d 216 (let* ((btick (buffer-modified-tick))
04a19a79
DC
217 (cbuffer (get-buffer "*Completions*"))
218 (ctick (and cbuffer (buffer-modified-tick cbuffer)))
219 (completion-at-point-functions '(lisp-completion-at-point)))
d209d4a9 220 (completion-at-point)
813f532d 221 ;; completion has occurred if:
690ec649 222 (or
813f532d 223 ;; the buffer has been modified
690ec649 224 (not (= btick (buffer-modified-tick)))
a7acbbe4 225 ;; a completions buffer has been modified or created
813f532d 226 (if cbuffer
04a19a79 227 (not (= ctick (buffer-modified-tick cbuffer)))
e58df0dc 228 (get-buffer "*Completions*")))))
813f532d
RS
229
230(defun ielm-complete-filename nil
e848854a 231 "Dynamically complete filename before point, if in a string."
61c11870
JB
232 (when (nth 3 (parse-partial-sexp comint-last-input-start (point)))
233 (comint-dynamic-complete-filename)))
690ec649 234
813f532d 235(defun ielm-indent-line nil
e848854a 236 "Indent the current line as Lisp code if it is not a prompt line."
3250010d 237 (when (save-excursion (comint-bol) (bolp))
813f532d
RS
238 (lisp-indent-line)))
239
e848854a
RS
240;;; Working buffer manipulation
241
242(defun ielm-print-working-buffer nil
243 "Print the current IELM working buffer's name in the echo area."
244 (interactive)
245 (message "The current working buffer is: %s" (buffer-name ielm-working-buffer)))
246
247(defun ielm-display-working-buffer nil
248 "Display the current IELM working buffer.
249Don't forget that selecting that buffer will change its value of `point'
250to its value of `window-point'!"
251 (interactive)
252 (display-buffer ielm-working-buffer)
253 (ielm-print-working-buffer))
254
255(defun ielm-change-working-buffer (buf)
256 "Change the current IELM working buffer to BUF.
257This is the buffer in which all sexps entered at the IELM prompt are
258evaluated. You can achieve the same effect with a call to
259`set-buffer' at the IELM prompt."
260 (interactive "bSet working buffer to: ")
61c11870
JB
261 (let ((buffer (get-buffer buf)))
262 (if (and buffer (buffer-live-p buffer))
04a19a79 263 (setq ielm-working-buffer buffer)
61c11870 264 (error "No such buffer: %S" buf)))
e848854a
RS
265 (ielm-print-working-buffer))
266
813f532d
RS
267;;; Other bindings
268
04a19a79 269(defun ielm-return (&optional for-effect)
e848854a
RS
270 "Newline and indent, or evaluate the sexp before the prompt.
271Complete sexps are evaluated; for incomplete sexps inserts a newline
272and indents. If however `ielm-dynamic-return' is nil, this always
273simply inserts a newline."
813f532d 274 (interactive)
690ec649
SS
275 (if ielm-dynamic-return
276 (let ((state
04a19a79
DC
277 (save-excursion
278 (end-of-line)
279 (parse-partial-sexp (ielm-pm)
280 (point)))))
281 (if (and (< (car state) 1) (not (nth 3 state)))
282 (ielm-send-input for-effect)
283 (when (and ielm-dynamic-multiline-inputs
284 (save-excursion
285 (beginning-of-line)
286 (looking-at-p comint-prompt-regexp)))
287 (save-excursion
288 (goto-char (ielm-pm))
289 (newline 1)))
290 (newline-and-indent)))
813f532d
RS
291 (newline)))
292
04a19a79
DC
293(defun ielm-return-for-effect ()
294 "Like `ielm-return', but do not print the result."
295 (interactive)
296 (ielm-return t))
297
94aba130
RS
298(defvar ielm-input)
299
06b60517 300(defun ielm-input-sender (_proc input)
690ec649 301 ;; Just sets the variable ielm-input, which is in the scope of
e848854a 302 ;; `ielm-send-input's call.
813f532d
RS
303 (setq ielm-input input))
304
04a19a79 305(defun ielm-send-input (&optional for-effect)
e848854a 306 "Evaluate the Emacs Lisp expression after the prompt."
813f532d 307 (interactive)
04a19a79
DC
308 (let (ielm-input) ; set by ielm-input-sender
309 (comint-send-input) ; update history, markers etc.
310 (ielm-eval-input ielm-input for-effect)))
813f532d
RS
311
312;;; Utility functions
313
6ad18d45 314(defun ielm-is-whitespace-or-comment (string)
2ef180f7 315 "Return non-nil if STRING is all whitespace or a comment."
61c11870
JB
316 (or (string= string "")
317 (string-match-p "\\`[ \t\n]*\\(?:;.*\\)*\\'" string)))
813f532d 318
813f532d
RS
319;;; Evaluation
320
04a19a79
DC
321(defun ielm-standard-output-impl (process)
322 "Return a function to use for `standard-output' while in ielm eval.
323The returned function takes one character as input. Passing nil
324to this function instead of a character flushes the output
325buffer. Passing t appends a terminating newline if the buffer is
326nonempty, then flushes the buffer."
327 ;; Use an intermediate output buffer because doing redisplay for
328 ;; each character we output is too expensive. Set up a flush timer
329 ;; so that users don't have to wait for whole lines to appear before
330 ;; seeing output.
331 (let* ((output-buffer nil)
332 (flush-timer nil)
333 (flush-buffer
334 (lambda ()
335 (comint-output-filter
336 process
337 (apply #'string (nreverse output-buffer)))
338 (redisplay)
339 (setf output-buffer nil)
340 (when flush-timer
341 (cancel-timer flush-timer)
342 (setf flush-timer nil)))))
343 (lambda (char)
344 (let (flush-now)
345 (cond ((and (eq char t) output-buffer)
346 (push ?\n output-buffer)
347 (setf flush-now t))
348 ((characterp char)
349 (push char output-buffer)))
350 (if flush-now
351 (funcall flush-buffer)
352 (unless flush-timer
353 (setf flush-timer (run-with-timer 0.1 nil flush-buffer))))))))
354
355(defun ielm-eval-input (input-string &optional for-effect)
06b60517 356 "Evaluate the Lisp expression INPUT-STRING, and pretty-print the result."
813f532d 357 ;; This is the function that actually `sends' the input to the
e848854a 358 ;; `inferior Lisp process'. All comint-send-input does is works out
813f532d
RS
359 ;; what that input is. What this function does is evaluates that
360 ;; input and produces `output' which gets inserted into the buffer,
361 ;; along with a new prompt. A better way of doing this might have
362 ;; been to actually send the output to the `cat' process, and write
363 ;; this as in output filter that converted sexps in the output
364 ;; stream to their evaluated value. But that would have involved
365 ;; more process coordination than I was happy to deal with.
04a19a79
DC
366 (let ((string input-string) ; input expression, as a string
367 form ; form to evaluate
368 pos ; End posn of parse in string
369 result ; Result, or error message
370 error-type ; string, nil if no error
371 (output "") ; result to display
372 (wbuf ielm-working-buffer) ; current buffer after evaluation
373 (pmark (ielm-pm)))
374 (unless (ielm-is-whitespace-or-comment string)
61c11870 375 (condition-case err
04a19a79
DC
376 (let ((rout (read-from-string string)))
377 (setq form (car rout)
378 pos (cdr rout)))
379 (error (setq result (error-message-string err))
380 (setq error-type "Read error")))
381 (unless error-type
382 ;; Make sure working buffer has not been killed
383 (if (not (buffer-name ielm-working-buffer))
384 (setq result "Working buffer has been killed"
385 error-type "IELM Error"
386 wbuf (current-buffer))
387 (if (ielm-is-whitespace-or-comment (substring string pos))
388 ;; To correctly handle the ielm-local variables *,
389 ;; ** and ***, we need a temporary buffer to be
390 ;; current at entry to the inner of the next two let
391 ;; forms. We need another temporary buffer to exit
392 ;; that same let. To avoid problems, neither of
393 ;; these buffers should be alive during the
394 ;; evaluation of form.
395 (let* ((*1 *)
396 (*2 **)
397 (*3 ***)
398 (active-process (ielm-process))
399 (old-standard-output standard-output)
400 new-standard-output
401 ielm-temp-buffer)
402 (set-match-data ielm-match-data)
403 (save-excursion
404 (with-temp-buffer
405 (condition-case err
406 (unwind-protect
407 ;; The next let form creates default
408 ;; bindings for *, ** and ***. But
409 ;; these default bindings are
410 ;; identical to the ielm-local
411 ;; bindings. Hence, during the
412 ;; evaluation of form, the
413 ;; ielm-local values are going to be
414 ;; used in all buffers except for
415 ;; other ielm buffers, which override
416 ;; them. Normally, the variables *1,
417 ;; *2 and *3 also have default
418 ;; bindings, which are not overridden.
419 (let ((* *1)
420 (** *2)
421 (*** *3))
422 (when (eq standard-output t)
423 (setf new-standard-output
424 (ielm-standard-output-impl
425 active-process))
426 (setf standard-output new-standard-output))
427 (kill-buffer (current-buffer))
428 (set-buffer wbuf)
429 (setq result
430 (eval form lexical-binding))
431 (setq wbuf (current-buffer))
432 (setq
433 ielm-temp-buffer
434 (generate-new-buffer " *ielm-temp*"))
435 (set-buffer ielm-temp-buffer))
436 (when ielm-temp-buffer
437 (kill-buffer ielm-temp-buffer))
438 (when (eq new-standard-output standard-output)
439 (ignore-errors
440 (funcall standard-output t))
441 (setf standard-output old-standard-output)))
442 (error (setq result (error-message-string err))
443 (setq error-type "Eval error"))
444 (quit (setq result "Quit during evaluation")
445 (setq error-type "Eval error")))))
446 (setq ielm-match-data (match-data)))
447 (setq error-type "IELM error")
448 (setq result "More than one sexp in input"))))
61c11870
JB
449
450 ;; If the eval changed the current buffer, mention it here
04a19a79
DC
451 (unless (eq wbuf ielm-working-buffer)
452 (message "current buffer is now: %s" wbuf)
453 (setq ielm-working-buffer wbuf))
454
455 (goto-char pmark)
456 (unless error-type
457 (condition-case nil
458 ;; Self-referential objects cause loops in the printer, so
459 ;; trap quits here. May as well do errors, too
460 (unless for-effect
b41594fd
JL
461 (setq output (concat output (pp-to-string result)
462 (let ((str (eval-expression-print-format result)))
463 (if str (propertize str 'font-lock-face 'shadow))))))
04a19a79
DC
464 (error (setq error-type "IELM Error")
465 (setq result "Error during pretty-printing (bug in pp)"))
466 (quit (setq error-type "IELM Error")
467 (setq result "Quit during pretty-printing"))))
468 (if error-type
469 (progn
470 (when ielm-noisy (ding))
471 (setq output (concat output "*** " error-type " *** "))
472 (setq output (concat output result)))
473 ;; There was no error, so shift the *** values
474 (setq *** **)
475 (setq ** *)
476 (setq * result))
477 (when (or (not for-effect) (not (equal output "")))
478 (setq output (concat output "\n"))))
479 (setq output (concat output ielm-prompt-internal))
480 (comint-output-filter (ielm-process) output)))
813f532d
RS
481
482;;; Process and marker utilities
483
484(defun ielm-process nil
e848854a 485 ;; Return the current buffer's process.
813f532d
RS
486 (get-buffer-process (current-buffer)))
487
488(defun ielm-pm nil
e848854a 489 ;; Return the process mark of the current buffer.
813f532d
RS
490 (process-mark (get-buffer-process (current-buffer))))
491
492(defun ielm-set-pm (pos)
e848854a 493 ;; Set the process mark in the current buffer to POS.
813f532d
RS
494 (set-marker (process-mark (get-buffer-process (current-buffer))) pos))
495
496;;; Major mode
497
61c11870 498(define-derived-mode inferior-emacs-lisp-mode comint-mode "IELM"
e848854a
RS
499 "Major mode for interactively evaluating Emacs Lisp expressions.
500Uses the interface provided by `comint-mode' (which see).
501
66f06793
SM
502* \\<ielm-map>\\[ielm-send-input] evaluates the sexp following the prompt. There must be at most
503 one top level sexp per prompt.
813f532d 504
e848854a
RS
505* \\[ielm-return] inserts a newline and indents, or evaluates a
506 complete expression (but see variable `ielm-dynamic-return').
507 Inputs longer than one line are moved to the line following the
508 prompt (but see variable `ielm-dynamic-multiline-inputs').
509
04a19a79
DC
510* \\[ielm-return-for-effect] works like `ielm-return', except
511 that it doesn't print the result of evaluating the input. This
512 functionality is useful when forms would generate voluminous
513 output.
514
d209d4a9 515* \\[completion-at-point] completes Lisp symbols (or filenames, within strings),
e848854a 516 or indents the line if there is nothing to complete.
813f532d 517
61c11870
JB
518The current working buffer may be changed (with a call to `set-buffer',
519or with \\[ielm-change-working-buffer]), and its value is preserved between successive
520evaluations. In this way, expressions may be evaluated in a different
521buffer than the *ielm* buffer. By default, its name is shown on the
522mode line; you can always display it with \\[ielm-print-working-buffer], or the buffer itself
523with \\[ielm-display-working-buffer].
813f532d 524
5d9655bb
RS
525During evaluations, the values of the variables `*', `**', and `***'
526are the results of the previous, second previous and third previous
527evaluations respectively. If the working buffer is another IELM
528buffer, then the values in the working buffer are used. The variables
529`*1', `*2' and `*3', yield the process buffer values.
530
04a19a79
DC
531If, at the start of evaluation, `standard-output' is `t' (the
532default), `standard-output' is set to a special function that
533causes output to be directed to the ielm buffer.
534`standard-output' is restored after evaluation unless explicitly
535set to a different value during evaluation. You can use (princ
536VALUE) or (pp VALUE) to write to the ielm buffer.
537
e848854a
RS
538Expressions evaluated by IELM are not subject to `debug-on-quit' or
539`debug-on-error'.
813f532d 540
291cfc0c 541The behavior of IELM may be customized with the following variables:
0382cf8f 542* To stop beeping on error, set `ielm-noisy' to nil.
813f532d 543* If you don't like the prompt, you can change it by setting `ielm-prompt'.
759f960a
LT
544* If you do not like that the prompt is (by default) read-only, set
545 `ielm-prompt-read-only' to nil.
0382cf8f 546* Set `ielm-dynamic-return' to nil for bindings like `lisp-interaction-mode'.
813f532d
RS
547* Entry to this mode runs `comint-mode-hook' and `ielm-mode-hook'
548 (in that order).
549
0382cf8f 550Customized bindings may be defined in `ielm-map', which currently contains:
813f532d 551\\{ielm-map}"
61c11870
JB
552 :syntax-table emacs-lisp-mode-syntax-table
553
813f532d 554 (setq comint-prompt-regexp (concat "^" (regexp-quote ielm-prompt)))
85ab9f4e 555 (set (make-local-variable 'paragraph-separate) "\\'")
61c11870 556 (set (make-local-variable 'paragraph-start) comint-prompt-regexp)
813f532d
RS
557 (setq comint-input-sender 'ielm-input-sender)
558 (setq comint-process-echoes nil)
d209d4a9 559 (set (make-local-variable 'completion-at-point-functions)
61c11870 560 '(ielm-tab comint-replace-by-expanded-history
04a19a79 561 ielm-complete-filename ielm-complete-symbol))
016b8f71
LT
562 (set (make-local-variable 'ielm-prompt-internal) ielm-prompt)
563 (set (make-local-variable 'comint-prompt-read-only) ielm-prompt-read-only)
e848854a 564 (setq comint-get-old-input 'ielm-get-old-input)
61c11870 565 (set (make-local-variable 'comint-completion-addsuffix) '("/" . ""))
76364803 566 (setq mode-line-process '(":%s on " (:eval (buffer-name ielm-working-buffer))))
fe1eb856
RS
567 ;; Useful for `hs-minor-mode'.
568 (setq-local comment-start ";")
569 (setq-local comment-use-global-state t)
813f532d 570
61c11870
JB
571 (set (make-local-variable 'indent-line-function) 'ielm-indent-line)
572 (set (make-local-variable 'ielm-working-buffer) (current-buffer))
573 (set (make-local-variable 'fill-paragraph-function) 'lisp-fill-paragraph)
813f532d 574
e848854a 575 ;; Value holders
61c11870
JB
576 (set (make-local-variable '*) nil)
577 (set (make-local-variable '**) nil)
578 (set (make-local-variable '***) nil)
565f89ec 579 (set (make-local-variable 'ielm-match-data) nil)
813f532d 580
9d42eea3 581 ;; font-lock support
61c11870
JB
582 (set (make-local-variable 'font-lock-defaults)
583 '(ielm-font-lock-keywords nil nil ((?: . "w") (?- . "w") (?* . "w"))))
690ec649 584
813f532d 585 ;; A dummy process to keep comint happy. It will never get any input
20b13009 586 (unless (comint-check-proc (current-buffer))
33a65176
JR
587 ;; Was cat, but on non-Unix platforms that might not exist, so
588 ;; use hexl instead, which is part of the Emacs distribution.
66f06793 589 (condition-case nil
04a19a79 590 (start-process "ielm" (current-buffer) "hexl")
66f06793 591 (file-error (start-process "ielm" (current-buffer) "cat")))
e5927b52 592 (set-process-query-on-exit-flag (ielm-process) nil)
813f532d 593 (goto-char (point-max))
71296446 594
20b13009
MB
595 ;; Lisp output can include raw characters that confuse comint's
596 ;; carriage control code.
597 (set (make-local-variable 'comint-inhibit-carriage-motion) t)
598
813f532d
RS
599 ;; Add a silly header
600 (insert ielm-header)
601 (ielm-set-pm (point-max))
85ab9f4e 602 (unless comint-use-prompt-regexp
76364803
JB
603 (let ((inhibit-read-only t))
604 (add-text-properties
605 (point-min) (point-max)
606 '(rear-nonsticky t field output inhibit-line-move-field-capture t))))
016b8f71 607 (comint-output-filter (ielm-process) ielm-prompt-internal)
813f532d 608 (set-marker comint-last-input-start (ielm-pm))
61c11870 609 (set-process-filter (get-buffer-process (current-buffer)) 'comint-output-filter)))
813f532d 610
e848854a
RS
611(defun ielm-get-old-input nil
612 ;; Return the previous input surrounding point
613 (save-excursion
614 (beginning-of-line)
61c11870 615 (unless (looking-at-p comint-prompt-regexp)
e848854a
RS
616 (re-search-backward comint-prompt-regexp))
617 (comint-skip-prompt)
618 (buffer-substring (point) (progn (forward-sexp 1) (point)))))
619
813f532d
RS
620;;; User command
621
e848854a 622;;;###autoload
813f532d 623(defun ielm nil
e848854a 624 "Interactively evaluate Emacs Lisp expressions.
04a19a79
DC
625Switches to the buffer `*ielm*', or creates it if it does not exist.
626See `inferior-emacs-lisp-mode' for details."
813f532d 627 (interactive)
ee9cd72d
LT
628 (let (old-point)
629 (unless (comint-check-proc "*ielm*")
630 (with-current-buffer (get-buffer-create "*ielm*")
04a19a79
DC
631 (unless (zerop (buffer-size)) (setq old-point (point)))
632 (inferior-emacs-lisp-mode)))
37ac18a3 633 (switch-to-buffer "*ielm*")
ee9cd72d 634 (when old-point (push-mark old-point))))
813f532d 635
896546cd
RS
636(provide 'ielm)
637
e848854a 638;;; ielm.el ends here