I am trying to calculate the width of text within either a buffer or a string after it has been displayed, i.e. after taking into account the width of any
display properties, such as embedded images, in the text.
The documentation of
string-width talks about the displayed representation of strings in the current buffer, but neither takes the
display property into account:
(require 'org) (let ((s (propertize " " 'display "123"))) (with-temp-buffer (insert s) (current-column)) ; => 1 (string-width s) ; => 1 (org-string-width s)) ; => 3
The problem with
org-string-width is that it does not work with complex display properties such as images.
This is the best alternative to
current-column I have come up with so far:
(/ (- (car (window-absolute-pixel-position)) (car (window-absolute-pixel-position (line-beginning-position)))) (default-font-width))
It approximates the "current window column" by calculating the current X-coordinate as a multiple of the default face font.
Is there a better way to achieve this purpose?
My motivation for this question is the misalignment/truncation of Org agenda tags in the presence of
org-agenda-category-icon-alist. For example, with:
(setq org-agenda-category-icon-alist '(("travel" "/usr/share/icons/Adwaita/scalable/status/airplane-mode-symbolic.svg" nil nil :ascent center)))
I get the following truncation in the agenda buffer:
Luckily, this can be hacked around with some advice:
(define-advice org-agenda-align-tags (:around (align &rest args) my-column) "Override `current-column' to include display properties." (let ((override (lambda () (/ (- (car (window-absolute-pixel-position)) (car (window-absolute-pixel-position (line-beginning-position)))) (default-font-width))))) (unwind-protect (progn (advice-add 'current-column :override override) (apply align args)) (advice-remove 'current-column override))))
which no longer causes truncation: