Subject: Re: bug#21771: 25.0.50; Can't customize whitespace-display-mappings

From: Ivan Andrus <[email-masked]>
Date: Tue, 29 Dec 2015 20:38:49 -0700

Ivan Andrus <[email-masked]> writes:

> This might be related to bug #2689,
> http://debbugs.gnu.org/cgi/bugreport.cgi?bug=2689
>
> ;; emacs -Q
> ;; Evaluated
> (require 'whitespace)
> (customize-variable 'whitespace-display-mappings)
> ;; Change anything, say deleting one of space mappings
> ;; Try to save
> ;; Get the error
> custom-variable-set: This field should contain a single character
>
> -Ivan

It turns out this is due to one of the characters being a newline.
There are two problems.  First, the validation regex doesn't match a
newline.  This is easily addressed with the following patch:

diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el
index d0410aa..55e8ac7 100644
--- a/lisp/wid-edit.el
+++ b/lisp/wid-edit.el
@@ -3400,7 +3400,7 @@ 'character
   :value 0
   :size 1
   :format "%{%t%}: %v\n"
-  :valid-regexp "\\`.\\'"
+  :valid-regexp "\\`\\(.\\|\n\\)\\'"
   :error "This field should contain a single character"
   :value-get (lambda (w) (widget-field-value-get w t))
   :value-to-internal (lambda (_widget value)

Second, a string consisting of only a newline is returned as an empty
string from `widget-field-value-get' even with `no-truncate' non-nil.  I
have worked around this, but I suspect it's a suboptimal solution.  It
seems like the special handling of newlines is probably intended, so a
"proper" solution might be tricky.

diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el
index 55e8ac7..7ff4ac2 100644
--- a/lisp/wid-edit.el
+++ b/lisp/wid-edit.el
@@ -3406,7 +3406,9 @@ 'character
   :value-to-internal (lambda (_widget value)
                       (if (stringp value)
                           value
-                        (char-to-string value)))
+                        (if (eq value ?\n)
+                            "\n\n"
+                          (char-to-string value))))
   :value-to-external (lambda (_widget value)
                       (if (stringp value)
                           (aref value 0)

Any pointers as to a better fix (or if this is sufficient) and/or how to
write a test for this would be much appreciated.

-Ivan