diff options
| author | Richard M. Stallman | 1994-05-02 17:13:42 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1994-05-02 17:13:42 +0000 |
| commit | e848854a118c4044869058dff7f11ba7c7c86ef3 (patch) | |
| tree | 1ba742d78ab50b80073bb505e741e137a0f3d1b9 /lisp | |
| parent | 389c907cd717f11bc5998ecfc878fceb4c8e5a8f (diff) | |
| download | emacs-e848854a118c4044869058dff7f11ba7c7c86ef3.tar.gz emacs-e848854a118c4044869058dff7f11ba7c7c86ef3.zip | |
(ielm-dynamic-multiline-inputs): New variable.
(ielm-return): Support it.
(ielm-print-working-buffer): New command
(ielm-change-working-buffer): New command
(ielm-display-working-buffer): New command
(ielm-map): Bindings for new commands; bindings from
shared-lisp-mode-map; Lemacs support.
(ielm-eval-input): Give bindings in scope during the eval
non-clashing names (ielm- prefix)
(ielm-get-old-input): New function
(inferior-emacs-lisp-mode): Bind it to comint-get-old-input
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/ielm.el | 285 |
1 files changed, 187 insertions, 98 deletions
diff --git a/lisp/ielm.el b/lisp/ielm.el index 3b5b1242140..b20b5c54dca 100644 --- a/lisp/ielm.el +++ b/lisp/ielm.el | |||
| @@ -23,14 +23,14 @@ | |||
| 23 | 23 | ||
| 24 | ;;; Commentary: | 24 | ;;; Commentary: |
| 25 | 25 | ||
| 26 | ;; Provides a nice interface to evaluating Emacs-Lisp expressions. | 26 | ;; Provides a nice interface to evaluating Emacs Lisp expressions. |
| 27 | ;; Input is handled by the comint package, and output is passed | 27 | ;; Input is handled by the comint package, and output is passed |
| 28 | ;; through the pretty-printer. | 28 | ;; through the pretty-printer. |
| 29 | 29 | ||
| 30 | ;; To install: copy this file to a directory in your load-path, and | 30 | ;; To install: copy this file to a directory in your load-path, and |
| 31 | ;; add the line | 31 | ;; add the following line to your .emacs file: |
| 32 | ;; | 32 | ;; |
| 33 | ;; (autoload 'ielm "ielm" "Start an inferior emacs-lisp session" t) | 33 | ;; (autoload 'ielm "ielm" "Start an inferior Emacs Lisp session" t) |
| 34 | ;; | 34 | ;; |
| 35 | ;; For completion to work, the comint.el from FSF Emacs 19.23 is | 35 | ;; For completion to work, the comint.el from FSF Emacs 19.23 is |
| 36 | ;; required. If you do not have it, or if you are running Lemacs, | 36 | ;; required. If you do not have it, or if you are running Lemacs, |
| @@ -58,28 +58,39 @@ | |||
| 58 | ;;; User variables | 58 | ;;; User variables |
| 59 | 59 | ||
| 60 | (defvar ielm-noisy t | 60 | (defvar ielm-noisy t |
| 61 | "*If non-nil, beep on error") | 61 | "*If non-nil, IELM will beep on error.") |
| 62 | 62 | ||
| 63 | (defvar ielm-prompt "ELISP> ") | 63 | (defvar ielm-prompt "ELISP> " |
| 64 | "Prompt used in IELM.") | ||
| 64 | 65 | ||
| 65 | (defvar ielm-dynamic-return t | 66 | (defvar ielm-dynamic-return t |
| 66 | "*If non-nil, RET either evaluates input or inserts a newline, | 67 | "*Controls whether \\<ielm-map>\\[ielm-return] has intelligent behaviour in IELM. |
| 67 | depending on context") | 68 | If non-nil, \\[ielm-return] evaluates input for complete sexps, or inserts a newline |
| 69 | and indents for incomplete sexps. If nil, always inserts newlines.") | ||
| 70 | |||
| 71 | (defvar ielm-dynamic-multiline-inputs t | ||
| 72 | "*Force multiline inputs to start from column zero? | ||
| 73 | If non-nil, after entering the first line of an incomplete sexp, a newline | ||
| 74 | will be inserted after the prompt, moving the input to the next line. | ||
| 75 | This gives more frame width for large indented sexps, and allows functions | ||
| 76 | such as `edebug-defun' to work with such inputs.") | ||
| 68 | 77 | ||
| 69 | (defvar ielm-mode-hook nil | 78 | (defvar ielm-mode-hook nil |
| 70 | "*Hooks to be run when the inferior-emacs-lisp-mode is started") | 79 | "*Hooks to be run when IELM (`inferior-emacs-lisp-mode') is started.") |
| 71 | 80 | ||
| 72 | ;;; System variables | 81 | ;;; System variables |
| 73 | 82 | ||
| 74 | (defvar ielm-working-buffer nil | 83 | (defvar ielm-working-buffer nil |
| 75 | "Buffer, if any, to use in ielm. Usually buffer-local") | 84 | "Buffer in which IELM sexps will be evaluated. |
| 85 | This variable is buffer-local.") | ||
| 76 | 86 | ||
| 77 | (defvar ielm-header | 87 | (defvar ielm-header |
| 78 | (concat | 88 | (concat |
| 79 | "*** Welcome to IELM mode version " | 89 | "*** Welcome to IELM version " |
| 80 | (substring "$Revision: 1.15 $" 11 -2) | 90 | (substring "$Revision: 1.25 $" 11 -2) |
| 81 | " *** Type (describe-mode) for help.\n" | 91 | " *** Type (describe-mode) for help.\n" |
| 82 | "IELM has ABSOLUTELY NO WARRANTY; type (describe-no-warranty) for details\n")) | 92 | "IELM has ABSOLUTELY NO WARRANTY; type (describe-no-warranty) for details.\n") |
| 93 | "Message to display when IELM is started.") | ||
| 83 | 94 | ||
| 84 | (defvar ielm-map nil) | 95 | (defvar ielm-map nil) |
| 85 | (if ielm-map nil | 96 | (if ielm-map nil |
| @@ -92,12 +103,23 @@ depending on context") | |||
| 92 | (setq ielm-map (cons 'keymap comint-mode-map))) | 103 | (setq ielm-map (cons 'keymap comint-mode-map))) |
| 93 | (define-key ielm-map "\t" 'comint-dynamic-complete) | 104 | (define-key ielm-map "\t" 'comint-dynamic-complete) |
| 94 | (define-key ielm-map "\C-m" 'ielm-return) | 105 | (define-key ielm-map "\C-m" 'ielm-return) |
| 95 | (define-key ielm-map "\C-j" 'ielm-send-input)) | 106 | (define-key ielm-map "\C-j" 'ielm-send-input) |
| 107 | (define-key ielm-map "\e\C-x" 'eval-defun) ; for consistency with | ||
| 108 | (define-key ielm-map "\e\t" 'lisp-complete-symbol) ; lisp-interaction-mode | ||
| 109 | ;; These bindings are from shared-lisp-mode-map -- can you inherit | ||
| 110 | ;; from more than one keymap?? | ||
| 111 | (define-key ielm-map "\e\C-q" 'indent-sexp) | ||
| 112 | (define-key ielm-map "\eq" 'lisp-fill-paragraph) | ||
| 113 | (define-key ielm-map "\177" 'backward-delete-char-untabify) | ||
| 114 | ;; Some convenience bindings for setting the working buffer | ||
| 115 | (define-key ielm-map "\C-c\C-b" 'ielm-change-working-buffer) | ||
| 116 | (define-key ielm-map "\C-c\C-f" 'ielm-display-working-buffer) | ||
| 117 | (define-key ielm-map "\C-c\C-v" 'ielm-print-working-buffer)) | ||
| 96 | 118 | ||
| 97 | ;;; Completion stuff | 119 | ;;; Completion stuff |
| 98 | 120 | ||
| 99 | (defun ielm-tab nil | 121 | (defun ielm-tab nil |
| 100 | "Possibly indent the current line as lisp code" | 122 | "Possibly indent the current line as lisp code." |
| 101 | (interactive) | 123 | (interactive) |
| 102 | (if (or (eq (preceding-char) ?\n) | 124 | (if (or (eq (preceding-char) ?\n) |
| 103 | (eq (char-syntax (preceding-char)) ? )) | 125 | (eq (char-syntax (preceding-char)) ? )) |
| @@ -106,8 +128,9 @@ depending on context") | |||
| 106 | t))) | 128 | t))) |
| 107 | 129 | ||
| 108 | (defun ielm-complete-symbol nil | 130 | (defun ielm-complete-symbol nil |
| 109 | "Just like lisp-complete-symbol" | 131 | "Complete the lisp symbol before point." |
| 110 | ;; except that it returns non-nil if completion has occurred | 132 | ;; A wrapper for lisp-complete symbol that returns non-nil if |
| 133 | ;; completion has occurred | ||
| 111 | (let* ((btick (buffer-modified-tick)) | 134 | (let* ((btick (buffer-modified-tick)) |
| 112 | (cbuffer (get-buffer " *Completions*")) | 135 | (cbuffer (get-buffer " *Completions*")) |
| 113 | (ctick (and cbuffer (buffer-modified-tick cbuffer)))) | 136 | (ctick (and cbuffer (buffer-modified-tick cbuffer)))) |
| @@ -122,22 +145,48 @@ depending on context") | |||
| 122 | (get-buffer " *Completions*"))))) | 145 | (get-buffer " *Completions*"))))) |
| 123 | 146 | ||
| 124 | (defun ielm-complete-filename nil | 147 | (defun ielm-complete-filename nil |
| 125 | ;; Completes filenames if in a string | 148 | "Dynamically complete filename before point, if in a string." |
| 126 | (if (nth 3 (parse-partial-sexp comint-last-input-start (point))) | 149 | (if (nth 3 (parse-partial-sexp comint-last-input-start (point))) |
| 127 | (comint-dynamic-complete-filename))) | 150 | (comint-dynamic-complete-filename))) |
| 128 | 151 | ||
| 129 | (defun ielm-indent-line nil | 152 | (defun ielm-indent-line nil |
| 130 | "Indent the current line as lisp code if it is not a prompt line" | 153 | "Indent the current line as Lisp code if it is not a prompt line." |
| 131 | (if (save-excursion | 154 | (if (save-excursion |
| 132 | (beginning-of-line) | 155 | (beginning-of-line) |
| 133 | (looking-at comint-prompt-regexp)) nil | 156 | (looking-at comint-prompt-regexp)) nil |
| 134 | (lisp-indent-line))) | 157 | (lisp-indent-line))) |
| 135 | 158 | ||
| 159 | ;;; Working buffer manipulation | ||
| 160 | |||
| 161 | (defun ielm-print-working-buffer nil | ||
| 162 | "Print the current IELM working buffer's name in the echo area." | ||
| 163 | (interactive) | ||
| 164 | (message "The current working buffer is: %s" (buffer-name ielm-working-buffer))) | ||
| 165 | |||
| 166 | (defun ielm-display-working-buffer nil | ||
| 167 | "Display the current IELM working buffer. | ||
| 168 | Don't forget that selecting that buffer will change its value of `point' | ||
| 169 | to its value of `window-point'!" | ||
| 170 | (interactive) | ||
| 171 | (display-buffer ielm-working-buffer) | ||
| 172 | (ielm-print-working-buffer)) | ||
| 173 | |||
| 174 | (defun ielm-change-working-buffer (buf) | ||
| 175 | "Change the current IELM working buffer to BUF. | ||
| 176 | This is the buffer in which all sexps entered at the IELM prompt are | ||
| 177 | evaluated. You can achieve the same effect with a call to | ||
| 178 | `set-buffer' at the IELM prompt." | ||
| 179 | (interactive "bSet working buffer to: ") | ||
| 180 | (setq ielm-working-buffer (or (get-buffer buf) (error "No such buffer"))) | ||
| 181 | (ielm-print-working-buffer)) | ||
| 182 | |||
| 136 | ;;; Other bindings | 183 | ;;; Other bindings |
| 137 | 184 | ||
| 138 | (defun ielm-return nil | 185 | (defun ielm-return nil |
| 139 | "Evaluate the sexp at the prompt if it is complete, otherwise newline | 186 | "Newline and indent, or evaluate the sexp before the prompt. |
| 140 | and indent. If ielm-dynamic-return is nil, just insert a newline." | 187 | Complete sexps are evaluated; for incomplete sexps inserts a newline |
| 188 | and indents. If however `ielm-dynamic-return' is nil, this always | ||
| 189 | simply inserts a newline." | ||
| 141 | (interactive) | 190 | (interactive) |
| 142 | (if ielm-dynamic-return | 191 | (if ielm-dynamic-return |
| 143 | (let ((state | 192 | (let ((state |
| @@ -147,14 +196,23 @@ and indent. If ielm-dynamic-return is nil, just insert a newline." | |||
| 147 | (point))))) | 196 | (point))))) |
| 148 | (if (and (< (car state) 1) (not (nth 3 state))) | 197 | (if (and (< (car state) 1) (not (nth 3 state))) |
| 149 | (ielm-send-input) | 198 | (ielm-send-input) |
| 199 | (if (and ielm-dynamic-multiline-inputs | ||
| 200 | (save-excursion | ||
| 201 | (beginning-of-line) | ||
| 202 | (looking-at comint-prompt-regexp))) | ||
| 203 | (save-excursion | ||
| 204 | (goto-char (ielm-pm)) | ||
| 205 | (newline 1))) | ||
| 150 | (newline-and-indent))) | 206 | (newline-and-indent))) |
| 151 | (newline))) | 207 | (newline))) |
| 152 | 208 | ||
| 153 | (defun ielm-input-sender (proc input) | 209 | (defun ielm-input-sender (proc input) |
| 210 | ;; Just sets the variable ielm-input, which is in the scope of | ||
| 211 | ;; `ielm-send-input's call. | ||
| 154 | (setq ielm-input input)) | 212 | (setq ielm-input input)) |
| 155 | 213 | ||
| 156 | (defun ielm-send-input nil | 214 | (defun ielm-send-input nil |
| 157 | "Evaluate the Emacs Lisp expression after the prompt" | 215 | "Evaluate the Emacs Lisp expression after the prompt." |
| 158 | (interactive) | 216 | (interactive) |
| 159 | (let ((buf (current-buffer)) | 217 | (let ((buf (current-buffer)) |
| 160 | ielm-input) ; set by ielm-input-sender | 218 | ielm-input) ; set by ielm-input-sender |
| @@ -164,7 +222,7 @@ and indent. If ielm-dynamic-return is nil, just insert a newline." | |||
| 164 | ;;; Utility functions | 222 | ;;; Utility functions |
| 165 | 223 | ||
| 166 | (defun ielm-is-whitespace (string) | 224 | (defun ielm-is-whitespace (string) |
| 167 | "Return non-nil if STRING is all whitespace" | 225 | "Return non-nil if STRING is all whitespace." |
| 168 | (or (string= string "") (string-match "\\`[ \t\n]+\\'" string))) | 226 | (or (string= string "") (string-match "\\`[ \t\n]+\\'" string))) |
| 169 | 227 | ||
| 170 | (defun ielm-format-errors (errlist) | 228 | (defun ielm-format-errors (errlist) |
| @@ -176,7 +234,7 @@ and indent. If ielm-dynamic-return is nil, just insert a newline." | |||
| 176 | 234 | ||
| 177 | 235 | ||
| 178 | (defun ielm-format-error (err) | 236 | (defun ielm-format-error (err) |
| 179 | "Return a string form of the error ERR" | 237 | ;; Return a string form of the error ERR. |
| 180 | (format "%s%s" | 238 | (format "%s%s" |
| 181 | (or (get (car err) 'error-message) "Peculiar error") | 239 | (or (get (car err) 'error-message) "Peculiar error") |
| 182 | (if (cdr err) | 240 | (if (cdr err) |
| @@ -185,10 +243,10 @@ and indent. If ielm-dynamic-return is nil, just insert a newline." | |||
| 185 | 243 | ||
| 186 | ;;; Evaluation | 244 | ;;; Evaluation |
| 187 | 245 | ||
| 188 | (defun ielm-eval-input (string) | 246 | (defun ielm-eval-input (ielm-string) |
| 189 | "Evaluate the lisp expression STRING, and pretty-print the result" | 247 | "Evaluate the Lisp expression IELM-STRING, and pretty-print the result." |
| 190 | ;; This is the function that actually `sends' the input to the | 248 | ;; This is the function that actually `sends' the input to the |
| 191 | ;; `inferior lisp process'. All comint-send-input does is works out | 249 | ;; `inferior Lisp process'. All comint-send-input does is works out |
| 192 | ;; what that input is. What this function does is evaluates that | 250 | ;; what that input is. What this function does is evaluates that |
| 193 | ;; input and produces `output' which gets inserted into the buffer, | 251 | ;; input and produces `output' which gets inserted into the buffer, |
| 194 | ;; along with a new prompt. A better way of doing this might have | 252 | ;; along with a new prompt. A better way of doing this might have |
| @@ -196,111 +254,130 @@ and indent. If ielm-dynamic-return is nil, just insert a newline." | |||
| 196 | ;; this as in output filter that converted sexps in the output | 254 | ;; this as in output filter that converted sexps in the output |
| 197 | ;; stream to their evaluated value. But that would have involved | 255 | ;; stream to their evaluated value. But that would have involved |
| 198 | ;; more process coordination than I was happy to deal with. | 256 | ;; more process coordination than I was happy to deal with. |
| 199 | (let (form ; form to evaluate | 257 | ;; |
| 200 | pos ; End posn of parse in string | 258 | ;; NOTE: all temporary variables in this function will be in scope |
| 201 | result ; Result, or error message | 259 | ;; during the eval, and so need to have non-clashing names. |
| 202 | error-type ; string, nil if no error | 260 | (let (ielm-form ; form to evaluate |
| 203 | (output "") ; result to display | 261 | ielm-pos ; End posn of parse in string |
| 204 | (wbuf ielm-working-buffer) ; current buffer after evaluation | 262 | ielm-result ; Result, or error message |
| 205 | (pmark (ielm-pm))) | 263 | ielm-error-type ; string, nil if no error |
| 206 | (if (not (ielm-is-whitespace string)) | 264 | (ielm-output "") ; result to display |
| 265 | (ielm-wbuf ielm-working-buffer) ; current buffer after evaluation | ||
| 266 | (ielm-pmark (ielm-pm))) | ||
| 267 | (if (not (ielm-is-whitespace ielm-string)) | ||
| 207 | (progn | 268 | (progn |
| 208 | (condition-case err | 269 | (condition-case err |
| 209 | (let (rout) | 270 | (let (rout) |
| 210 | (setq rout (read-from-string string)) | 271 | (setq rout (read-from-string ielm-string)) |
| 211 | (setq form (car rout)) | 272 | (setq ielm-form (car rout)) |
| 212 | (setq pos (cdr rout))) | 273 | (setq ielm-pos (cdr rout))) |
| 213 | (error (setq result (ielm-format-error err)) | 274 | (error (setq ielm-result (ielm-format-error err)) |
| 214 | (setq error-type "Read error"))) | 275 | (setq ielm-error-type "Read error"))) |
| 215 | (if error-type nil | 276 | (if ielm-error-type nil |
| 216 | (if (ielm-is-whitespace (substring string pos)) | 277 | ;; Make sure working buffer has not been killed |
| 217 | ;; need this awful let convolution to work around | 278 | (if (not (buffer-name ielm-working-buffer)) |
| 218 | ;; an Emacs bug involving local vbls and let binding | 279 | (setq ielm-result "Working buffer has been killed" |
| 219 | (let ((:save :) | 280 | ielm-error-type "IELM Error" |
| 220 | (::save ::) | 281 | ielm-wbuf (current-buffer)) |
| 221 | (:::save :::)) | 282 | (if (ielm-is-whitespace (substring ielm-string ielm-pos)) |
| 222 | (save-excursion | 283 | ;; need this awful let convolution to work around |
| 223 | (set-buffer ielm-working-buffer) | 284 | ;; an Emacs bug involving local vbls and let binding |
| 224 | (condition-case err | 285 | (let ((:save :) |
| 225 | (let ((: :save) | 286 | (::save ::) |
| 226 | (:: ::save) | 287 | (:::save :::)) |
| 227 | (::: :::save)) | 288 | (save-excursion |
| 228 | (save-excursion | 289 | (set-buffer ielm-working-buffer) |
| 229 | (setq result (eval form)) | 290 | (condition-case err |
| 230 | (setq wbuf (current-buffer)))) | 291 | (let ((: :save) |
| 231 | (error (setq result (ielm-format-error err)) | 292 | (:: ::save) |
| 232 | (setq error-type "Eval error")) | 293 | (::: :::save) |
| 233 | (quit (setq result "Quit during evaluation") | 294 | (ielm-obuf (current-buffer))) |
| 234 | (setq error-type "Eval error"))))) | 295 | (setq ielm-result (eval ielm-form)) |
| 235 | (setq error-type "IELM error") | 296 | (setq ielm-wbuf (current-buffer)) |
| 236 | (setq result "More than one sexp in input"))) | 297 | ;; The eval may have changed current-buffer; |
| 298 | ;; need to set it back here to avoid a bug | ||
| 299 | ;; in let. Don't want to use save-excursion | ||
| 300 | ;; because we want to allow changes in point. | ||
| 301 | (set-buffer ielm-obuf)) | ||
| 302 | (error (setq ielm-result (ielm-format-error err)) | ||
| 303 | (setq ielm-error-type "Eval error")) | ||
| 304 | (quit (setq ielm-result "Quit during evaluation") | ||
| 305 | (setq ielm-error-type "Eval error"))))) | ||
| 306 | (setq ielm-error-type "IELM error") | ||
| 307 | (setq ielm-result "More than one sexp in input")))) | ||
| 237 | 308 | ||
| 238 | ;; If the eval changed the current buffer, mention it here | 309 | ;; If the eval changed the current buffer, mention it here |
| 239 | (if (eq wbuf ielm-working-buffer) nil | 310 | (if (eq ielm-wbuf ielm-working-buffer) nil |
| 240 | (message "current buffer is now: %s" wbuf) | 311 | (message "current buffer is now: %s" ielm-wbuf) |
| 241 | (setq ielm-working-buffer wbuf)) | 312 | (setq ielm-working-buffer ielm-wbuf)) |
| 242 | 313 | ||
| 243 | (goto-char pmark) | 314 | (goto-char ielm-pmark) |
| 244 | (if (not error-type) | 315 | (if (not ielm-error-type) |
| 245 | (condition-case err | 316 | (condition-case err |
| 246 | ;; Self-referential objects cause loops in the printer, so | 317 | ;; Self-referential objects cause loops in the printer, so |
| 247 | ;; trap quits here. May as well do errors, too | 318 | ;; trap quits here. May as well do errors, too |
| 248 | (setq output (concat output (pp-to-string result))) | 319 | (setq ielm-output (concat ielm-output (pp-to-string ielm-result))) |
| 249 | (error (setq error-type "IELM Error") | 320 | (error (setq ielm-error-type "IELM Error") |
| 250 | (setq result "Error during pretty-printing (bug in pp)")) | 321 | (setq ielm-result "Error during pretty-printing (bug in pp)")) |
| 251 | (quit (setq error-type "IELM Error") | 322 | (quit (setq ielm-error-type "IELM Error") |
| 252 | (setq result "Quit during pretty-printing")))) | 323 | (setq ielm-result "Quit during pretty-printing")))) |
| 253 | (if error-type | 324 | (if ielm-error-type |
| 254 | (progn | 325 | (progn |
| 255 | (if ielm-noisy (ding)) | 326 | (if ielm-noisy (ding)) |
| 256 | (setq output (concat output "*** " error-type " *** ")) | 327 | (setq ielm-output (concat ielm-output "*** " ielm-error-type " *** ")) |
| 257 | (setq output (concat output result))) | 328 | (setq ielm-output (concat ielm-output ielm-result))) |
| 258 | ;; There was no error, so shift the ::: values | 329 | ;; There was no error, so shift the ::: values |
| 259 | (setq ::: ::) | 330 | (setq ::: ::) |
| 260 | (setq :: :) | 331 | (setq :: :) |
| 261 | (setq : result)) | 332 | (setq : ielm-result)) |
| 262 | (setq output (concat output "\n")))) | 333 | (setq ielm-output (concat ielm-output "\n")))) |
| 263 | (setq output (concat output ielm-prompt)) | 334 | (setq ielm-output (concat ielm-output ielm-prompt)) |
| 264 | (comint-output-filter (ielm-process) output))) | 335 | (comint-output-filter (ielm-process) ielm-output))) |
| 265 | 336 | ||
| 266 | ;;; Process and marker utilities | 337 | ;;; Process and marker utilities |
| 267 | 338 | ||
| 268 | (defun ielm-process nil | 339 | (defun ielm-process nil |
| 269 | "Return the current buffer's process" | 340 | ;; Return the current buffer's process. |
| 270 | (get-buffer-process (current-buffer))) | 341 | (get-buffer-process (current-buffer))) |
| 271 | 342 | ||
| 272 | (defun ielm-pm nil | 343 | (defun ielm-pm nil |
| 273 | "Return the process mark of the current buffer" | 344 | ;; Return the process mark of the current buffer. |
| 274 | (process-mark (get-buffer-process (current-buffer)))) | 345 | (process-mark (get-buffer-process (current-buffer)))) |
| 275 | 346 | ||
| 276 | (defun ielm-set-pm (pos) | 347 | (defun ielm-set-pm (pos) |
| 277 | "Set the process mark in the current buffer to POS" | 348 | ;; Set the process mark in the current buffer to POS. |
| 278 | (set-marker (process-mark (get-buffer-process (current-buffer))) pos)) | 349 | (set-marker (process-mark (get-buffer-process (current-buffer))) pos)) |
| 279 | 350 | ||
| 280 | ;;; Major mode | 351 | ;;; Major mode |
| 281 | 352 | ||
| 282 | (defun inferior-emacs-lisp-mode nil | 353 | (defun inferior-emacs-lisp-mode nil |
| 283 | "Major mode for interactively evaluating Emacs-Lisp expressions | 354 | "Major mode for interactively evaluating Emacs Lisp expressions. |
| 284 | Uses the interface provided by `comint-mode' (q.v.) | 355 | Uses the interface provided by `comint-mode' (which see). |
| 356 | |||
| 357 | * \\<ielm-map>\\[ielm-send-input] evaluates the sexp following the prompt. There must be at most | ||
| 358 | one top-level sexp per prompt. | ||
| 285 | 359 | ||
| 286 | \\[ielm-send-input] evaluates the sexp following the prompt. There must be at most | 360 | * \\[ielm-return] inserts a newline and indents, or evaluates a |
| 287 | one top-level sexp per prompt. | 361 | complete expression (but see variable `ielm-dynamic-return'). |
| 288 | \\[ielm-return] inserts a newline and indents. However, if the variable | 362 | Inputs longer than one line are moved to the line following the |
| 289 | ielm-dynamic-return is non-nil (the default) then it will also evaluate | 363 | prompt (but see variable `ielm-dynamic-multiline-inputs'). |
| 290 | a complete expression. | 364 | |
| 291 | \\[comint-dynamic-complete] completes lisp symbols (or filenames, within strings), | 365 | * \\[comint-dynamic-complete] completes Lisp symbols (or filenames, within strings), |
| 292 | or indents the line if there is nothing to complete. | 366 | or indents the line if there is nothing to complete. |
| 293 | 367 | ||
| 294 | During evaluations, the values of the variables `:', `::', and `:::' | 368 | During evaluations, the values of the variables `:', `::', and `:::' |
| 295 | are the results of the previous, second previous and third previous | 369 | are the results of the previous, second previous and third previous |
| 296 | evaluations respectively. | 370 | evaluations respectively. |
| 297 | 371 | ||
| 298 | The current buffer may be changed, and its value is preserved between | 372 | The current working buffer may be changed (with a call to |
| 299 | successive evaluations. In this way, expressions may be evaluated in | 373 | `set-buffer', or with \\[ielm-change-working-buffer]), and its value |
| 300 | a different buffer than the *ielm* buffer. | 374 | is preserved between successive evaluations. In this way, expressions |
| 375 | may be evaluated in a different buffer than the *ielm* buffer. | ||
| 376 | Display the name of the working buffer with \\[ielm-print-working-buffer], | ||
| 377 | or the buffer itself with \\[ielm-display-working-buffer]. | ||
| 301 | 378 | ||
| 302 | Expressions evaluated by IELM are not subject to debug-on-quit or | 379 | Expressions evaluated by IELM are not subject to `debug-on-quit' or |
| 303 | debug-on-error. | 380 | `debug-on-error'. |
| 304 | 381 | ||
| 305 | The behaviour of IELM may be customised with the following variables: | 382 | The behaviour of IELM may be customised with the following variables: |
| 306 | * To stop beeping on error, set `ielm-noisy' to nil | 383 | * To stop beeping on error, set `ielm-noisy' to nil |
| @@ -320,6 +397,7 @@ Customised bindings may be defined in `ielm-map', which currently contains: | |||
| 320 | (setq comint-process-echoes nil) | 397 | (setq comint-process-echoes nil) |
| 321 | (setq comint-dynamic-complete-functions | 398 | (setq comint-dynamic-complete-functions |
| 322 | '(ielm-tab comint-replace-by-expanded-history ielm-complete-filename ielm-complete-symbol)) | 399 | '(ielm-tab comint-replace-by-expanded-history ielm-complete-filename ielm-complete-symbol)) |
| 400 | (setq comint-get-old-input 'ielm-get-old-input) | ||
| 323 | 401 | ||
| 324 | (setq major-mode 'inferior-emacs-lisp-mode) | 402 | (setq major-mode 'inferior-emacs-lisp-mode) |
| 325 | (setq mode-name "IELM") | 403 | (setq mode-name "IELM") |
| @@ -331,7 +409,7 @@ Customised bindings may be defined in `ielm-map', which currently contains: | |||
| 331 | (setq ielm-working-buffer (current-buffer)) | 409 | (setq ielm-working-buffer (current-buffer)) |
| 332 | (setq indent-line-function 'ielm-indent-line) | 410 | (setq indent-line-function 'ielm-indent-line) |
| 333 | 411 | ||
| 334 | ;;; Value holders | 412 | ;; Value holders |
| 335 | (setq : nil) | 413 | (setq : nil) |
| 336 | (make-local-variable ':) | 414 | (make-local-variable ':) |
| 337 | (setq :: nil) | 415 | (setq :: nil) |
| @@ -352,10 +430,21 @@ Customised bindings may be defined in `ielm-map', which currently contains: | |||
| 352 | (set-process-filter (get-buffer-process (current-buffer)) 'comint-output-filter)) | 430 | (set-process-filter (get-buffer-process (current-buffer)) 'comint-output-filter)) |
| 353 | (run-hooks 'ielm-mode-hook)) | 431 | (run-hooks 'ielm-mode-hook)) |
| 354 | 432 | ||
| 433 | (defun ielm-get-old-input nil | ||
| 434 | ;; Return the previous input surrounding point | ||
| 435 | (save-excursion | ||
| 436 | (beginning-of-line) | ||
| 437 | (if (looking-at comint-prompt-regexp) nil | ||
| 438 | (re-search-backward comint-prompt-regexp)) | ||
| 439 | (comint-skip-prompt) | ||
| 440 | (buffer-substring (point) (progn (forward-sexp 1) (point))))) | ||
| 441 | |||
| 355 | ;;; User command | 442 | ;;; User command |
| 356 | 443 | ||
| 444 | ;;;###autoload | ||
| 357 | (defun ielm nil | 445 | (defun ielm nil |
| 358 | "Switch to or create the buffer *ielm* for evaluating emacs-lisp expressions" | 446 | "Interactively evaluate Emacs Lisp expressions. |
| 447 | Switches to the buffer *ielm*, or creates it if it does not exist." | ||
| 359 | (interactive) | 448 | (interactive) |
| 360 | (if (comint-check-proc "*ielm*") nil | 449 | (if (comint-check-proc "*ielm*") nil |
| 361 | (progn | 450 | (progn |
| @@ -363,4 +452,4 @@ Customised bindings may be defined in `ielm-map', which currently contains: | |||
| 363 | (inferior-emacs-lisp-mode))) | 452 | (inferior-emacs-lisp-mode))) |
| 364 | (switch-to-buffer "*ielm*")) | 453 | (switch-to-buffer "*ielm*")) |
| 365 | 454 | ||
| 366 | ;; ielm.el ends here | 455 | ;;; ielm.el ends here |