10

I have an Emacs Org file with list of tasks with a set of properties each one. Say I have three properties called ESTIMATED, SPENT and REMAINING, which account for the number of hours that I estimated the task will take to be done (ESTIMATED), the number of hours I already worked on it (SPENT) and the hours left from the original estimate (REMAINING). Obviously (and assuming we do not re-estimate the time it will take), for each task REMAINING = ESTIMATED - SPENT

I use a lot Column view to update status, work spent and so on. Is it possible to set up the property REMAINING so that when I change in Column View the value of the property SPENT, the property REMAINING gets automatically recalculated?

1 Answer 1

2

In column view, it is possible to calculate both the display value of a property, and set the actual value in an entries property drawer, from any other property by setting org-columns-modify-value-for-display-function suitably. This function is called for each value (cell) that is displayed in column view, with point at the entry whose values are to be be displayed. This means that all the entries other property values are accessible via (org-entry-get nil PROPERTY).

For the given example, say we have the following Org file:

:PROPERTIES:
:COLUMNS:       %30ITEM %ESTIMATED %SPENT %REMAINING
:END:

* task 1
:PROPERTIES:
:ESTIMATED:     8
:SPENT:         5
:END:

* task 2
:PROPERTIES:
:ESTIMATED:     5
:SPENT:         4
:END:

After we set

(defun my-column-display-value-transformer (column-title value)
  "Modifies the value to display in column view.
Calculates a value for the REMAINING column when
both the ESTIMATE and SPENT properties are non-nil."
  (when (equal column-title "REMAINING")
    (let ((estimated (org-entry-get nil "ESTIMATED"))
          (spent (org-entry-get nil "SPENT")))
      (when (and estimated spent)
        (number-to-string
         (- (string-to-number estimated)
            (string-to-number spent)))))))

(setq org-columns-modify-value-for-display-function
      #'my-column-display-value-transformer)

activating column view (M-x org-columns) will show the values of the REMAINING column as desired, and these values will be updated when the values of in the SPENT column are changed from column view. However, no actual values get written for the REMAINING property into the entries property drawers; they are just display values.

If you really want to write the REMAINING values into the property drawers you can use this instead:

(defun my-column-display-value-transformer (column-title value)
  "Modifies the value to display in column view.
Calculates a value for the REMAINING column when
both the ESTIMATE and SPENT properties are non-nil."
  (when (equal column-title "REMAINING")
    (let ((estimated (org-entry-get nil "ESTIMATED"))
          (spent (org-entry-get nil "SPENT"))
          remaining)
      (when (and estimated spent)
        (setq remaining (number-to-string
                         (- (string-to-number estimated)
                            (string-to-number spent))))
        (org-entry-put nil "REMAINING" remaining)
        remaining))))

(setq org-columns-modify-value-for-display-function
      #'my-column-display-value-transformer)
1
  • A very nice answer, exactly what I was looking for. Thanks! Commented Jan 19, 2023 at 10:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.