2

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 current-column and 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:

Org agenda misalignment screenshot

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:

enter image description here

  • Good question...... – Drew Sep 2 '18 at 2:55
  • 1
    I think you could get the right effect using an :align-to space specifier before :tag: – rpluim Sep 3 '18 at 9:00
  • 1
    @rpluim Thanks, you're right. Patching org-agenda-align-tags to use :align-to instead of a fixed-width string solves the alignment issue. Would you consider this a bug with org-agenda.el? – Basil Sep 3 '18 at 9:42
  • I'm not an org developer, but probably. :align-to has existed since 2004 or so :-) – rpluim Sep 3 '18 at 9:57
  • @rpluim I initially read that as ":align-to is so 2004". :) – Basil Sep 3 '18 at 10:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.