X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/e848854a118c4044869058dff7f11ba7c7c86ef3..1b33e237605724471fa486643252702feca7a6e1:/lisp/ielm.el diff --git a/lisp/ielm.el b/lisp/ielm.el index b20b5c54dc..2f2a9861e6 100644 --- a/lisp/ielm.el +++ b/lisp/ielm.el @@ -1,7 +1,9 @@ ;;; ielm.el --- interaction mode for Emacs Lisp + ;; Copyright (C) 1994 Free Software Foundation, Inc. ;; Author: David Smith +;; Maintainer: FSF ;; Created: 25 Feb 1994 ;; Keywords: lisp @@ -18,8 +20,9 @@ ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to -;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. ;;; Commentary: @@ -32,7 +35,7 @@ ;; ;; (autoload 'ielm "ielm" "Start an inferior Emacs Lisp session" t) ;; -;; For completion to work, the comint.el from FSF Emacs 19.23 is +;; For completion to work, the comint.el from Emacs 19.23 is ;; required. If you do not have it, or if you are running Lemacs, ;; also add the following code to your .emacs: ;; @@ -57,27 +60,49 @@ ;;; User variables -(defvar ielm-noisy t - "*If non-nil, IELM will beep on error.") +(defgroup ielm nil + "Interaction mode for Emacs Lisp." + :group 'lisp) + + +(defcustom ielm-noisy t + "*If non-nil, IELM will beep on error." + :type 'boolean + :group 'ielm) (defvar ielm-prompt "ELISP> " "Prompt used in IELM.") -(defvar ielm-dynamic-return t +(defcustom ielm-dynamic-return t "*Controls whether \\\\[ielm-return] has intelligent behaviour in IELM. If non-nil, \\[ielm-return] evaluates input for complete sexps, or inserts a newline -and indents for incomplete sexps. If nil, always inserts newlines.") +and indents for incomplete sexps. If nil, always inserts newlines." + :type 'boolean + :group 'ielm) -(defvar ielm-dynamic-multiline-inputs t +(defcustom ielm-dynamic-multiline-inputs t "*Force multiline inputs to start from column zero? If non-nil, after entering the first line of an incomplete sexp, a newline will be inserted after the prompt, moving the input to the next line. This gives more frame width for large indented sexps, and allows functions -such as `edebug-defun' to work with such inputs.") +such as `edebug-defun' to work with such inputs." + :type 'boolean + :group 'ielm) -(defvar ielm-mode-hook nil - "*Hooks to be run when IELM (`inferior-emacs-lisp-mode') is started.") +(defcustom ielm-mode-hook nil + "*Hooks to be run when IELM (`inferior-emacs-lisp-mode') is started." + :type 'hook + :group 'ielm) +(defvar * nil + "Most recent value evaluated in IELM.") + +(defvar ** nil + "Second-most-recent value evaluated in IELM.") + +(defvar *** nil + "Third-most-recent value evaluated in IELM.") + ;;; System variables (defvar ielm-working-buffer nil @@ -85,11 +110,7 @@ such as `edebug-defun' to work with such inputs.") This variable is buffer-local.") (defvar ielm-header - (concat - "*** Welcome to IELM version " - (substring "$Revision: 1.25 $" 11 -2) - " *** Type (describe-mode) for help.\n" - "IELM has ABSOLUTELY NO WARRANTY; type (describe-no-warranty) for details.\n") + "*** Welcome to IELM *** Type (describe-mode) for help.\n" "Message to display when IELM is started.") (defvar ielm-map nil) @@ -109,13 +130,20 @@ This variable is buffer-local.") ;; These bindings are from shared-lisp-mode-map -- can you inherit ;; from more than one keymap?? (define-key ielm-map "\e\C-q" 'indent-sexp) - (define-key ielm-map "\eq" 'lisp-fill-paragraph) (define-key ielm-map "\177" 'backward-delete-char-untabify) ;; Some convenience bindings for setting the working buffer (define-key ielm-map "\C-c\C-b" 'ielm-change-working-buffer) (define-key ielm-map "\C-c\C-f" 'ielm-display-working-buffer) (define-key ielm-map "\C-c\C-v" 'ielm-print-working-buffer)) +(defvar ielm-font-lock-keywords + (list + (cons (concat "^" (regexp-quote ielm-prompt)) 'font-lock-keyword-face) + '("\\(^\\*\\*\\*[^*]+\\*\\*\\*\\)\\(.*$\\)" + (1 font-lock-comment-face) + (2 font-lock-constant-face))) + "Additional expressions to highlight in ielm buffers.") + ;;; Completion stuff (defun ielm-tab nil @@ -132,17 +160,17 @@ This variable is buffer-local.") ;; A wrapper for lisp-complete symbol that returns non-nil if ;; completion has occurred (let* ((btick (buffer-modified-tick)) - (cbuffer (get-buffer " *Completions*")) + (cbuffer (get-buffer "*Completions*")) (ctick (and cbuffer (buffer-modified-tick cbuffer)))) (lisp-complete-symbol) ;; completion has occurred if: (or ;; the buffer has been modified (not (= btick (buffer-modified-tick))) - ;; a completions buffer has been modifed or created + ;; a completions buffer has been modified or created (if cbuffer (not (= ctick (buffer-modified-tick cbuffer))) - (get-buffer " *Completions*"))))) + (get-buffer "*Completions*"))))) (defun ielm-complete-filename nil "Dynamically complete filename before point, if in a string." @@ -206,6 +234,8 @@ simply inserts a newline." (newline-and-indent))) (newline))) +(defvar ielm-input) + (defun ielm-input-sender (proc input) ;; Just sets the variable ielm-input, which is in the scope of ;; `ielm-send-input's call. @@ -282,15 +312,15 @@ simply inserts a newline." (if (ielm-is-whitespace (substring ielm-string ielm-pos)) ;; need this awful let convolution to work around ;; an Emacs bug involving local vbls and let binding - (let ((:save :) - (::save ::) - (:::save :::)) + (let ((*save *) + (**save **) + (***save ***)) (save-excursion (set-buffer ielm-working-buffer) (condition-case err - (let ((: :save) - (:: ::save) - (::: :::save) + (let ((* *save) + (** **save) + (*** ***save) (ielm-obuf (current-buffer))) (setq ielm-result (eval ielm-form)) (setq ielm-wbuf (current-buffer)) @@ -326,10 +356,10 @@ simply inserts a newline." (if ielm-noisy (ding)) (setq ielm-output (concat ielm-output "*** " ielm-error-type " *** ")) (setq ielm-output (concat ielm-output ielm-result))) - ;; There was no error, so shift the ::: values - (setq ::: ::) - (setq :: :) - (setq : ielm-result)) + ;; There was no error, so shift the *** values + (setq *** **) + (setq ** *) + (setq * ielm-result)) (setq ielm-output (concat ielm-output "\n")))) (setq ielm-output (concat ielm-output ielm-prompt)) (comint-output-filter (ielm-process) ielm-output))) @@ -350,6 +380,8 @@ simply inserts a newline." ;;; Major mode +(put 'inferior-emacs-lisp-mode 'mode-class 'special) + (defun inferior-emacs-lisp-mode nil "Major mode for interactively evaluating Emacs Lisp expressions. Uses the interface provided by `comint-mode' (which see). @@ -365,7 +397,7 @@ Uses the interface provided by `comint-mode' (which see). * \\[comint-dynamic-complete] completes Lisp symbols (or filenames, within strings), or indents the line if there is nothing to complete. -During evaluations, the values of the variables `:', `::', and `:::' +During evaluations, the values of the variables `*', `**', and `***' are the results of the previous, second previous and third previous evaluations respectively. @@ -398,6 +430,9 @@ Customised bindings may be defined in `ielm-map', which currently contains: (setq comint-dynamic-complete-functions '(ielm-tab comint-replace-by-expanded-history ielm-complete-filename ielm-complete-symbol)) (setq comint-get-old-input 'ielm-get-old-input) + (make-local-variable 'comint-completion-addsuffix) + (setq comint-completion-addsuffix + (cons (char-to-string directory-sep-char) "")) (setq major-mode 'inferior-emacs-lisp-mode) (setq mode-name "IELM") @@ -408,15 +443,22 @@ Customised bindings may be defined in `ielm-map', which currently contains: (make-local-variable 'ielm-working-buffer) (setq ielm-working-buffer (current-buffer)) (setq indent-line-function 'ielm-indent-line) + (make-local-variable 'fill-paragraph-function) + (setq fill-paragraph-function 'lisp-fill-paragraph) ;; Value holders - (setq : nil) - (make-local-variable ':) - (setq :: nil) - (make-local-variable '::) - (setq ::: nil) - (make-local-variable ':::) - + (setq * nil) + (make-local-variable '*) + (setq ** nil) + (make-local-variable '**) + (setq *** nil) + (make-local-variable '***) + + ;; font-lock support + (make-local-variable 'font-lock-defaults) + (setq font-lock-defaults + '(ielm-font-lock-keywords nil nil ((?: . "w") (?- . "w") (?* . "w")))) + ;; A dummy process to keep comint happy. It will never get any input (if (comint-check-proc (current-buffer)) nil (start-process "ielm" (current-buffer) "cat") @@ -441,15 +483,20 @@ Customised bindings may be defined in `ielm-map', which currently contains: ;;; User command +;;;###autoload (add-hook 'same-window-buffer-names "*ielm*") + ;;;###autoload (defun ielm nil "Interactively evaluate Emacs Lisp expressions. -Switches to the buffer *ielm*, or creates it if it does not exist." +Switches to the buffer `*ielm*', or creates it if it does not exist." (interactive) - (if (comint-check-proc "*ielm*") nil - (progn + (if (comint-check-proc "*ielm*") + nil + (save-excursion (set-buffer (get-buffer-create "*ielm*")) (inferior-emacs-lisp-mode))) - (switch-to-buffer "*ielm*")) + (pop-to-buffer "*ielm*")) + +(provide 'ielm) ;;; ielm.el ends here