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 acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.