Subject: bug#6238: momentary-string-display => "(nil) is undefined"

From: Juanma Barranquero <[email-masked]>
Date: Fri, 21 May 2010 12:24:54 +0200

emacs -Q
M-: (momentary-string-display "xxx" (point)) <RET>
<right>              ; or any non-char event
  =>  "(nil) is undefined"

The reason is this code:

(let (char)
  (if (integerp exit-char)
      (condition-case nil
          (progn
            (setq char (read-char))
            (or (eq char exit-char)
                (setq unread-command-events (list char))))
        (error
         ;; `exit-char' is a character, hence it differs
         ;; from char, which is an event.
         (setq unread-command-events (list char))))
    ...

but, whenever wer're inside the condition-case, any error (which can
only happen in read-char) will make char = nil, so the error handler
will set `unread-command-events' to (nil).

It's easy to fix like this:

=== modified file 'lisp/subr.el'
--- lisp/subr.el	2010-05-18 20:31:44 +0000
+++ lisp/subr.el	2010-05-21 09:59:28 +0000
@@ -2207,13 +2207,8 @@
           (let (char)
             (if (integerp exit-char)
-                (condition-case nil
-                    (progn
-                      (setq char (read-char))
-                      (or (eq char exit-char)
-                          (setq unread-command-events (list char))))
-                  (error
-                   ;; `exit-char' is a character, hence it differs
-                   ;; from char, which is an event.
-                   (setq unread-command-events (list char))))
+                (ignore-errors
+		  (setq char (read-char))
+		  (or (eq char exit-char)
+		      (setq unread-command-events (list char))))
               ;; `exit-char' can be an event, or an event description list.
               (setq char (read-event))

but the real question is, why all the hoopla around char vs. event? Why not just

=== modified file 'lisp/subr.el'
--- lisp/subr.el	2010-05-18 20:31:44 +0000
+++ lisp/subr.el	2010-05-21 10:19:56 +0000
@@ -2205,20 +2205,9 @@
           (message (or message "Type %s to continue editing.")
                    (single-key-description exit-char))
-          (let (char)
-            (if (integerp exit-char)
-                (condition-case nil
-                    (progn
-                      (setq char (read-char))
-                      (or (eq char exit-char)
-                          (setq unread-command-events (list char))))
-                  (error
-                   ;; `exit-char' is a character, hence it differs
-                   ;; from char, which is an event.
-                   (setq unread-command-events (list char))))
-              ;; `exit-char' can be an event, or an event description list.
-              (setq char (read-event))
-              (or (eq char exit-char)
-                  (eq char (event-convert-list exit-char))
-                  (setq unread-command-events (list char))))))
+	  (let ((event (read-event)))
+	    ;; `exit-char' can be an event, or an event description list.
+	    (or (eq event exit-char)
+		(eq event (event-convert-list exit-char))
+		(setq unread-command-events (list event)))))
       (delete-overlay ol))))

which seems to work for chars, events and event description lists?