5

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

enter image description here

2 Answers 2

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.")
7
  • Thanks for the answer. I also want to know what setting makes the zero width space become an underscore like thing.
    – FunkyBaby
    Jun 1, 2021 at 23:54
  • Can I hide these only in org-mode?
    – HappyFace
    Jun 3, 2021 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, 2021 at 2: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 4, 2023 at 17:44
  • 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, 2023 at 23:23
0

Related to the above answer: in emacs 29, there's glyphless-display-mode. That shows big boxes for such characters.

That's not what you're asking for, but if you've turned that mode on, you certainly won't be hiding zero-width spaces and similar things. It's also an arguably simpler way to accomplish the red highlighting in the above answer -- and the boxes have the character abbreviations, such as "ZWSP", "ZWJ", "ZWNJ", and so on, which are nice. (Although of course there's describe-char.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.