Change 'M-:' to not error out on incomplete expressions
* lisp/simple.el (read--expression-try-read): New function to read a Lisp expression from the minibuffer (bug#30697). This will not (as before) signal an error on incomplete expressions, but allow users to continue editing it. (read--expression): Use it (and add a doc string).
This commit is contained in:
parent
70825a4d31
commit
4a6dd13fa4
2 changed files with 52 additions and 0 deletions
7
etc/NEWS
7
etc/NEWS
|
@ -101,6 +101,13 @@ deprecated. Errors in the Inscript method were corrected.
|
|||
|
||||
* Editing Changes in Emacs 28.1
|
||||
|
||||
---
|
||||
** 'eval-expression' now no longer signals an error on incomplete expressions.
|
||||
Previously, typing 'M-: ( RET' would result in Emacs saying "End of
|
||||
file during parsing" and dropping out of the minibuffer. The user
|
||||
would have to type 'M-: M-p' to edit and redo the expression. Now
|
||||
Emacs will echo the message and allow the user to continue editing.
|
||||
|
||||
+++
|
||||
** New command 'undo-redo'.
|
||||
It undoes previous undo commands, but doesn't record itself as an
|
||||
|
|
|
@ -1619,6 +1619,10 @@ display the result of expression evaluation."
|
|||
"Hook run by `eval-expression' when entering the minibuffer.")
|
||||
|
||||
(defun read--expression (prompt &optional initial-contents)
|
||||
"Read an Emacs Lisp expression from the minibuffer.
|
||||
|
||||
PROMPT and optional argument INITIAL-CONTENTS do the same as in
|
||||
function `read-from-minibuffer'."
|
||||
(let ((minibuffer-completing-symbol t))
|
||||
(minibuffer-with-setup-hook
|
||||
(lambda ()
|
||||
|
@ -1629,11 +1633,52 @@ display the result of expression evaluation."
|
|||
(set-syntax-table emacs-lisp-mode-syntax-table)
|
||||
(add-hook 'completion-at-point-functions
|
||||
#'elisp-completion-at-point nil t)
|
||||
(local-set-key "\r" 'read--expression-try-read)
|
||||
(local-set-key "\n" 'read--expression-try-read)
|
||||
(run-hooks 'eval-expression-minibuffer-setup-hook))
|
||||
(read-from-minibuffer prompt initial-contents
|
||||
read-expression-map t
|
||||
'read-expression-history))))
|
||||
|
||||
(defun read--expression-try-read ()
|
||||
"Try to read an Emacs Lisp expression in the minibuffer.
|
||||
|
||||
Exit the minibuffer if successful, else report the error to the
|
||||
user and move point to the location of the error. If point is
|
||||
not already at the location of the error, push a mark before
|
||||
moving point."
|
||||
(interactive)
|
||||
(unless (> (minibuffer-depth) 0)
|
||||
(error "Minibuffer must be active"))
|
||||
(if (let* ((contents (minibuffer-contents))
|
||||
(error-point nil))
|
||||
(with-temp-buffer
|
||||
(condition-case err
|
||||
(progn
|
||||
(insert contents)
|
||||
(goto-char (point-min))
|
||||
;; `read' will signal errors like "End of file during
|
||||
;; parsing" and "Invalid read syntax".
|
||||
(read (current-buffer))
|
||||
;; Since `read' does not signal the "Trailing garbage
|
||||
;; following expression" error, we check for trailing
|
||||
;; garbage ourselves.
|
||||
(or (progn
|
||||
;; This check is similar to what `string_to_object'
|
||||
;; does in minibuf.c.
|
||||
(skip-chars-forward " \t\n")
|
||||
(= (point) (point-max)))
|
||||
(error "Trailing garbage following expression")))
|
||||
(error
|
||||
(setq error-point (+ (length (minibuffer-prompt)) (point)))
|
||||
(with-current-buffer (window-buffer (minibuffer-window))
|
||||
(unless (= (point) error-point)
|
||||
(push-mark))
|
||||
(goto-char error-point)
|
||||
(minibuffer-message (error-message-string err)))
|
||||
nil))))
|
||||
(exit-minibuffer)))
|
||||
|
||||
(defun eval-expression-get-print-arguments (prefix-argument)
|
||||
"Get arguments for commands that print an expression result.
|
||||
Returns a list (INSERT-VALUE NO-TRUNCATE CHAR-PRINT-LIMIT)
|
||||
|
|
Loading…
Add table
Reference in a new issue