5

Typing a zero-width space in TERMINAL emacs shows an underscore-ish character. How to make it showing nothing?

enter image description here

Drew
  • 75,699
  • 9
  • 109
  • 225
FunkyBaby
  • 767
  • 1
  • 4
  • 10

1 Answers1

13

Refer to C-hig (elisp)Glyphless Chars

By default the zero-width characters are displayed using the thin-space display method which will "Display a thin space, 1-pixel wide on graphical displays, or 1-character wide on text terminals"; also noting that "The ‘thin-space’, ‘empty-box’, ‘hex-code’, and ASCII string display methods are drawn with the ‘glyphless-char’ face" which by default inherits from the underline face.

This default ensures that these (potentially-confusing) characters are not 100% invisible to the user, and can easily be made much more visible if desired; but there is also a zero-width display method which you can use to truly hide them from display:

(set-char-table-range glyphless-char-display
                      (char-from-name "ZERO WIDTH SPACE") 'zero-width)

Personally I want these things to be as visible as possible -- I've encountered a situation where I was unwittingly copying and pasting zero-width joiners between visible characters, and I created a mess because I never knew they were there. To make sure they are apparent to me (as I don't expect such things to normally be in the text I edit), I use this:

(set-face-background 'glyphless-char "red")

(If you want to see how that looks, ‌c‍o‍p‍y​ ‌t‍h‍i‍s​ ‌s‍e‍n‍t‌e‍n‍c‍e​ ‌i‍n‍t‍o​ ‌E‍m‍a‍c‍s​ ‌a‍n‍d​ ‌c‍o‍n‍f‍i‍g‍u‍r‍e​ ‌t‍h‍a‍t​ ‌b‍a‍c‍k‍g‍r‍o‍u‍n‍d‍.)


To hide such chars for a particular mode only, you could make the char table buffer-local in that mode.

;; Make glyphless chars highly visible.
(set-face-background 'glyphless-char "red")

;; Hide ZERO WIDTH chars completely in `org-mode'.
(add-hook 'org-mode-hook #'my-hide-zero-width-chars)

(defun my-hide-zero-width-chars ()
  "Make ZERO WIDTH characters completely invisible."
  (setq-local glyphless-char-display
              my-zero-width-glyphless-char-display))

(defvar my-zero-width-glyphless-char-display
  (let ((table (copy-sequence glyphless-char-display))
        (charnames (list "ZERO WIDTH SPACE"
                         "ZERO WIDTH NO-BREAK SPACE"
                         "ZERO WIDTH JOINER"
                         "ZERO WIDTH NON-JOINER")))
    (dolist (name charnames)
      (set-char-table-range table (char-from-name name) 'zero-width))
    table)
  "Variant of `glyphless-char-display' which hides ZERO WIDTH chars.")
phils
  • 48,657
  • 3
  • 76
  • 115
  • Thanks for the answer. I also want to know what setting makes the zero width space become an underscore like thing. – FunkyBaby Jun 01 '21 at 23:54
  • Can I hide these only in org-mode? – HappyFace Jun 03 '21 at 15:00
  • n.b. I've updated the answer with all of the additional information and responses from my earlier comments. – phils Jun 30 '21 at 02:23
  • Not working for me. I run that code. In an org buffer I can confirm it partially worked, because if I eval `(aref glyphless-char-display (char-from-name "ZERO WIDTH SPACE"))` I get `zero-width`. But if I then insert that character in my org buffer, I still see an red underscore. – Rob N May 04 '23 at 17:44
  • phils, could a simalar method be used to change the glyph of `NARROW NO-BREAK SPACE`? It is the same as no-break space when using fixed-width font,and it would be useful to be able to distinguish them. – pglpm Jun 14 '23 at 21:38
  • 1
    I can't reproduce your issue: for me, in a GUI emacs frame, the narrow no-break space *is* narrow (tested with `emacs -Q` for both Emacs 27 and 28). I only have "wide narrow glyphs" in terminal frames (which is expected). If you're not *already* getting narrow glyphs, I'm not sure whether this answer could help; you'd need to play with the code to find out. – phils Jun 14 '23 at 23:23
  • Thank you for the feedback. In a GUI frame and starting emacs (28) with `-Q`, `no-break space` is shown as an underlined empty space, which usefully distinguishes it from normal space. But `narrow no-break space` is shown in exactly the same way. Maybe I'll ask a question here about that. – pglpm Jun 15 '23 at 05:22