reddit / emacs

Command that can re-evaluates a variable? Or maybe there is a better alternative?

teckau22 · 2022-12-21 14:25
I have customized the variable `org-agenda-custom-commands` as shown below. Currently, the classic approach "General tasks (simple version)" and my custom approach "General tasks (complicated version)" both do the same thing (and this works well). What I'm trying to do is that I would like the whole section "General tasks (complicated version)" to be gone if there are no NEXT/WAIT tasks in the associated file (notes.org). The problem that I have is that once the variable `org-agenda-custom-commands` is evaluated initially (when Emacs launches), the `if` block decides if the section will be displayed or not. Further changes to notes.org will not change the behavior of `org-agenda-custom-commands` since its `if` block has already been evaluated. However, manually re-evaluating `org-agenda-custom-commands` updates the agenda view in the way I want it to. Here is a simple example: (defun teckau22/agenda-custom-section (title files) (if (> (apply '+ (mapcar (lambda (arg) (with-temp-buffer (insert-file-contents arg) (count-matches "^\\(\\*\\)+ \\(NEXT\\|WAIT\\)" (point-min) (point-max)))) files)) 0) `(todo "NEXT|WAIT" ((org-agenda-overriding-header ,(concat "\n" title)) (org-agenda-files (quote ,files)))) `(todo "NEXT|WAIT" ((org-agenda-overriding-header "") (org-agenda-files (quote ())))))) (setq org-agenda-custom-commands `(("a" "Custom agenda view" ((agenda "" ((org-agenda-overriding-header nil))) (todo "NEXT|WAIT" ((org-agenda-overriding-header "\nGeneral tasks (simple version)") (org-agenda-files '("/home/teckau22/emacs/org/notes.org")))) ,(teckau22/agenda-custom-section "General tasks (complicated version)" `(,(concat teckau22/org-directory "/notes.org")))) ((org-agenda-compact-blocks nil) (org-agenda-block-separator nil))))) Is there a way to re-evaluate `org-agenda-custom-commands` automatically (e.g., every time I open the agenda)? Note that even if there is such a way to do this, it kinda seems like a hacky solution and I feel like there is probably a better approach to solving this. I would appreciate any input. PS: I know about `org-super-agenda`, but I would like to solve this problem myself for the fun/challenge of it.
churchzebra · 2022-12-21 15:01
use hook or advice
popska · 2022-12-21 15:02
I haven't tested this, but does advice work? `(advice-add 'org-agenda :before (lambda (&rest _) (setq ...)))`
arozbiz · 2022-12-21 16:14
Create your own function that wraps `org-agenda` in a `let` block that redefines the variable.
deaddyfreddy · 2022-12-21 16:17
https://www.gnu.org/software/emacs/manual/html_node/elisp/Watching-Variables.html
teckau22 · 2022-12-21 16:29
This is what I did and it works, thanks! It feels a bit hacky though :P It will be my solution for now, until I find something more elegant.
eleven_cupfuls · 2022-12-21 18:13
Not hacky except in the good sense. Making a custom command should probably be the most preferred way to do this kind of thing, whenever possible.