[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 4a6dd13 2/2: Change 'M-:' to not error out on incomplete expressi
master 4a6dd13 2/2: Change 'M-:' to not error out on incomplete expressions
Mon, 10 Aug 2020 09:18:26 -0400 (EDT)
Author: Charles A. Roelli <email@example.com>
Commit: Lars Ingebrigtsen <firstname.lastname@example.org>
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).
etc/NEWS | 7 +++++++
lisp/simple.el | 45 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 52 insertions(+)
diff --git a/etc/NEWS b/etc/NEWS
index e3d7ff0..7a38b4d 100644
@@ -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
diff --git a/lisp/simple.el b/lisp/simple.el
index 4a774bc..4d59108 100644
@@ -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
(let ((minibuffer-completing-symbol t))
@@ -1629,11 +1633,52 @@ display the result of expression evaluation."
#'elisp-completion-at-point nil t)
+ (local-set-key "\r" 'read--expression-try-read)
+ (local-set-key "\n" 'read--expression-try-read)
(read-from-minibuffer prompt initial-contents
+(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
+ (unless (> (minibuffer-depth) 0)
+ (error "Minibuffer must be active"))
+ (if (let* ((contents (minibuffer-contents))
+ (error-point nil))
+ (condition-case err
+ (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")))
+ (setq error-point (+ (length (minibuffer-prompt)) (point)))
+ (with-current-buffer (window-buffer (minibuffer-window))
+ (unless (= (point) error-point)
+ (goto-char error-point)
+ (minibuffer-message (error-message-string err)))
(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)