Subject: Re: bug#13177: 24.3.50; doc of `read-char-by-name'

From: Juri Linkov <[email-masked]>
Date: Sun, 16 Dec 2012 11:12:04 +0200

> Great.  That's what I would prefer also.  And that was exactly what
> I said in the original bug report: that's what the other `read*'
> functions do: return the thing their names say they read.

`read-char' says it reads a character but it returns 0 (^@) for
invalid characters.  I see no reason why 0 would be better than nil.
Using an arbitrary character ^@ for invalid characters makes no sense.

Try to eval

  (insert-char (read-char))

and type `C-SPC'.  It inserts the character ^@ with the value 0.

Typing `C-M-SPC' reports:

  (wrong-type-argument characterp 134217728)

Clicking a mouse button reports in the echo area:

  "Non-character input-event"

This exhibits three different types of error processing for invalid
characters.  I think that displaying "Non-character input-event"
in the echo area is the most reasonable and user-friendly.

> So we start with a code bug - make sure it always returns a char.
> Then we fix the doc.
> Anyway, FWIW you've got my vote in favor of fixing the code
> to always return a char.

Also in bug#13195 the same request:

> Seems like `read-char-by-name' should always return something
> that `insert-char' can use, i.e., something that passes `characterp'.

Yes, to always return a valid char or nil, we could check for `characterp'
like in the patch below.

So when you type `C-x 8 RET #10r1111111111 RET' it will report
in the echo area:

  "You did not specify a valid character"

IMO, this is a sufficient error processing, no?

=== modified file 'lisp/international/mule-cmds.el'
--- lisp/international/mule-cmds.el	2012-12-15 13:07:58 +0000
+++ lisp/international/mule-cmds.el	2012-12-16 09:06:59 +0000
@@ -2944,7 +2944,10 @@ (defun read-char-by-name (prompt)
 
 This function also accepts a hexadecimal number of Unicode code
 point or a number in hash notation, e.g. #o21430 for octal,
-#x2318 for hex, or #10r8984 for decimal."
+#x2318 for hex, or #10r8984 for decimal.
+
+When input is neither a known Unicode name nor a hex number
+that specifies a valid character, return nil."
   (let* ((enable-recursive-minibuffers t)
 	 (input
 	  (completing-read
@@ -2953,14 +2956,16 @@ (defun read-char-by-name (prompt)
 	     (let ((completion-ignore-case t))
 	       (if (eq action 'metadata)
 		   '(metadata (category . unicode-name))
-		 (complete-with-action action (ucs-names) string pred)))))))
-    (cond
-     ((string-match-p "\\`[0-9a-fA-F]+\\'" input)
-      (string-to-number input 16))
-     ((string-match-p "\\`#" input)
-      (read input))
-     (t
-      (cdr (assoc-string input (ucs-names) t))))))
+		 (complete-with-action action (ucs-names) string pred))))))
+	 (character
+	  (cond
+	   ((string-match-p "\\`[0-9a-fA-F]+\\'" input)
+	    (string-to-number input 16))
+	   ((string-match-p "\\`#" input)
+	    (read input))
+	   (t
+	    (cdr (assoc-string input (ucs-names) t))))))
+    (and (characterp character) character)))
 
 (define-obsolete-function-alias 'ucs-insert 'insert-char "24.3")
 (define-key ctl-x-map "8\r" 'insert-char)