help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Force character display width


From: Yuri Khan
Subject: Force character display width
Date: Thu, 8 Jun 2017 00:28:16 +0700

Hello, everybody.

I am trying to customize Ibuffer to display the read-only status
differently. By default, it displays a percent sign if the buffer is
read-only, and a space if not. I want it to display a lock character
(πŸ”’ U+1f512 LOCK) instead of the percent sign. Of course this is all
on a GUI frame.

That was the big picture. Now for the XY problem :)

    (define-ibuffer-column yk-read-only (:name "R") nil
      (if (buffer-local-value 'buffer-read-only buffer)
          "πŸ”’"
        " "))

This would work in the ideal world where my font of choice has full
Unicode coverage. That is not the case. My default font is Liberation
Mono and the lock is displayed in Symbola. The widths do not match, so
the columns do not line up perfectly.

This leads me to the idea that I need to somehow tweak the lock
character so that it takes up exactly one character cell; or,
alternatively, tweak the space so it takes as much space as the lock;
or tweak both that they take up the same width.


I can achieve the desired effect by changing font size:

    (propertize "πŸ”’" 'display '(height 0.75))

but this strikes me as inelegant and prone to breaking if I ever change fonts.


I suppose I could calculate the factor dynamically if I could get the
pixel width of the lock character. However, the only thing I can find
on that path is the β€˜window-text-pixel-size’ function which requires
the text being  measured to already be in the buffer. I’d prefer to
avoid fiddling with a temporary buffer and window.


I could use the same character for both cases, but propertize it with
different faces. That will solve the display problem at the cost of
breaking semantics.


I could also do this:

    (concat (if (yk-buffer-read-only-p buffer) "πŸ”’" " ")
            (propertize " " 'display '(space . (:align-to 3.5))))

This will break if I ever decide to move the column to a different
position, and is also slightly fragile against font changes.


I also tried using a string of two spaces and the following composition:

    (compose-chars ?\s '(Br . Bc) ?πŸ”’ '(Bc . Bl) ?\s)

which do occupy the same width, but there are visual glitches when
cursor passes that point in the buffer.


Am I overlooking some other option?



reply via email to

[Prev in Thread] Current Thread [Next in Thread]