0

Is there any way to completely delete an entry's effort property from within the org-mode agenda?

Ideally, I'd also like to be able to bulk remove efforts from the agenda view.

"org-agenda-set-effort" doesn't provide a method to remove the property.

2

There are three parts to the answer:

  • write a function that deletes an Effort entry from the properties drawer of the current headline.

  • write the corresponding agenda function that calls the function above "remotely"; i.e. you call the agenda function in the agenda and it in turn switches context to the headline in the file and calls the first function above.

  • add an entry for the agenda function to org-agenda-bulk-custom-functions, consisting of the character that you use to call the agenda function and the symbol corresponding to the name of the function.

There are plenty of examples of remote functions in the Org mode sources, so I just copied the code from the org-agenda-set-effort function and changed the local function that it calls, to come up with the following code (seems to work; very lightly tested):

#+begin_src elisp :results drawer

(defun org-delete-effort ()
   (interactive)
   (org-entry-delete (point) org-effort-property))


 (defun org-agenda-delete-effort ()
    "Set the effort property for the current headline."
    (interactive)
    (org-agenda-check-no-diary)
    (org-agenda-maybe-loop
       #'org-agenda-delete-effort nil nil nil
       (let* ((hdmarker (or (org-get-at-bol 'org-hd-marker)
                            (org-agenda-error)))
              (buffer (marker-buffer hdmarker))
              (pos (marker-position hdmarker))
              (inhibit-read-only t)
              newhead)
         (org-with-remote-undo buffer
           (with-current-buffer buffer
             (widen)
             (goto-char pos)
             (org-show-context 'agenda)
             (call-interactively 'org-delete-effort)
             (end-of-line 1)
             (setq newhead (org-get-heading)))
         (org-agenda-change-all-lines newhead hdmarker)))))


(add-to-list 'org-agenda-bulk-custom-functions
             '(?Y org-agenda-delete-effort))

#+end_src

So you mark the entries in the agenda, then do B Y to delete efforts. I chose Y as the character to call the function because it was not being used for any other bulk operation (in my case - YMMV).

This can obviously be used as a template for other such remote operations.

5
  • This code is working perfectly for me. I also bound a key so that I can call org-agenda-delete-effort on individual items from the agenda view. – Max Pfleger Jun 6 at 15:41
  • Not sure whether you can edit the answer (you probably need more reputation), but if you add a comment with what you did, I will edit the answer to add that information. – NickD Jun 6 at 15:49
  • I simply added a keybinding for your org-agenda-delete-effort function which also allows it to be called on individual items within the agenda view, versus using the bulk command. (eval-after-load "org-agenda-mode" 'my/after-load-org-agenda-mode) (defun my/after-load-org-agenda-mode () (lambda () (local-set-key org-agenda-mode-map (kbd "c E") 'org-agenda-delete-effort))) – Max Pfleger Jun 6 at 19:14
  • Oh, I misread: but do you need a separate keydef for that? Doesn't B Y work on the item you are on if you have not marked any entries? – NickD Jun 6 at 19:35
  • Yes, you are right. B Y does work, so a separate key binding is redundant. All these years and I had no idea that you could run a bulk action on an unmarked agenda item. Thank you, that is incredibly useful. – Max Pfleger Jun 7 at 1:18

Your Answer

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

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