1

When I use org column view with my custom price property the numbers are aligned left which looks weird. How can I make them align right in column view?

Example

#+COLUMNS: %25ITEM %TODO %TAGS %PRICE

* Stuff I wand to sell
** My book
:PROPERTIES:
:PRICE: 20
:END:
** My old bike
:PROPERTIES:
:PRICE: 120
:END:

Then activate column view with C-c C-x C-c

  • 1
    I don't think there is a mechanism to align the columns in column view. OTOH, if you capture the column view using a `columnview` dynamic block (`C-h i g(org)Capturing column view`), the table *is* aligned properly. I haven't gone through the code in detail, but it seems that the function `org-columns--display-here`, which is responsible for the overlays in "regular" column view, just does not bother about justification within a column. – NickD Apr 23 '22 at 18:32
  • @NickD: Thanks for the hint, I will report back when I find further infos. – breathe_in_breathe_out Apr 29 '22 at 09:28

2 Answers2

3

If you would like to overrule the automatic alignment of number-rich columns to the right, center or to the left, you can place "<r>", "<c>" or "<l>" at the header of the table. You may also combine alignment and field width like this: "<r10>".

reference: https://orgmode.org/manual/Column-Width-and-Alignment.html#Column-Width-and-Alignment

Eg:

#+NAME: Stuff_I_Want_To_Sell
|----------------------+--------|
|         <c>          |    <r> |
| Stuff I Want To Sell | Amount |
|----------------------+--------|
|         Book         |     20 |
|       Old bike       |    120 |
|----------------------+--------|
|        Total         |    140 |
|----------------------+--------|
#+TBLFM: @>$2=vsum(@3..@-1)
orion
  • 805
  • 8
  • 16
0

General case

The following can be used to right-align all numbers (to align only integers or floats without exponents see here):

(require 'cl-seq)

(defconst my-string-number-regex
  (concat "^[+-]?\\(?:[0-9]+\\(?:[.,][0-9]*\\)?\\(?:e[+-]?[0-9]+\\)?"
          "\\|[.,][0-9]+\\(?:e[+-]?[0-9]+\\)?\\)$")
  "Matches integers and floats with exponent.
This allows for leading and trailing decimal point, leading zeros in base,
leading zeros in exponent, + signs, and , as alternative decimal separator.")

(defun my-column-display-value-transformer (column-title value)
  "Modifies the value to display in column view.
This modifies all numbers to align right."
  (when (string-match-p my-string-number-regex value)
    (let ((pos
           (cl-position column-title org-columns-current-fmt-compiled
                        :test (lambda (x y) (equal x (car y))))))
      (when-let
          ((target-width
            (or (nth 2 (nth pos org-columns-current-fmt-compiled))
                (aref org-columns-current-maxwidths pos)))
           (vlength
            (length value)))
        (when (< vlength target-width)
          (concat
           (make-string (- target-width
                           vlength)
                        ? )
           value))))))
           
(setq org-columns-modify-value-for-display-function
      #'my-column-display-value-transformer)

To instead right-align all values in the specific column "PRICE", replace the first when statement with (when (equal column-title "PRICE"). To center add (/ ... 2) around the (- ...) in make-string.

Column view uses org-columns-current-maxwidths to set the column widths, but that varible is not updated yet when org-columns-modify-value-for-display-function is called (it is called through org-columns--collect-values in org-columns one line before org-columns--set-widths sets org-columns-current-maxwidths). So to actually get the right alignment you have to either set a width in the column specification (%5PRICE) or call org-columns-redo directly after entering column view, for example by pressing r or g.

Summary values

Another solution works for the special case of the summary values of summary column types. For these can specify a format string which allows you to right align the displayed summary values. For example, if the largest number has 5 digits:

#+COLUMNS: %25ITEM %TODO %TAGS %PRICE{+;% 5d}

Unfortunately this only applies for summary types and also only for summary type entries which have at least one children to summarize over. So in the example given it would just apply in the heading row.

orgtre
  • 1,012
  • 4
  • 15