reddit / emacs

Temporarily change org-agenda-add-note to add below LOGBOOK

pragmat1c1 · 2022-05-20 20:32
In org-agenda, I can hit "z" key to add a note to an item. I need to set `(org-log-into-drawer nil)` so that the notes are not written to the LOGBOOK. But in that case state changes (TODO => DONE) will be written below LOGBOOK as well. Since I only want to add the notes to the section below LOGBOOK, but the state changes into the LOGBOOK drawer, I try to temporarily change the variable `org-log-into-drawer` to `nil` before calling `org-agenda-add-note` and back to `t` after calling it. I can't seem to make this work. The notes are still written to the LOGBOOK drawer. What am I missing? ## Code for temporarily writing notes outside LOGBOOK (defun ugt-org-agenda-add-note-below-drawer () "Add note in org-agenda to item, below drawer (usually into drawer)." (interactive) (setq org-log-into-drawer nil) (org-agenda-add-note) (setq org-log-into-drawer t)) ;;;; overwrite "z" key in org-agenda to use my function (add-hook 'org-agenda-mode-hook (lambda () (local-set-key (kbd "z") 'ugt-org-agenda-add-note-below-drawer) )) ## Edit: Advising the function does not work either ;;;; org-agenda-add-note (add to below LOGBOOK, but state changes to LOGBOOK) (defun ugt-org-agenda-add-note-below-drawer (orig-fun &rest args) "Add note in org-agenda to item, below drawer (usually into drawer)." (let ((org-log-into-drawer nil)) (apply orig-fun args))) (advice-add 'org-agenda-add-note :around #'ugt-org-agenda-add-note-below-drawer) ;; see https://www.gnu.org/software/emacs/manual/html_node/elisp/Porting-Old-Advice.html => Still puts the notes into LOGBOOK. ## Here is the solution Taken from: https://emacs.stackexchange.com/a/46736/29404 (defun with-no-drawer (func &rest args) (interactive "P") (if (eq org-log-note-purpose 'note) (let ((org-log-state-notes-insert-after-drawers t)) (flet ((org-log-into-drawer (&rest args) nil)) (apply func args))) (apply func args))) (advice-add 'org-log-beginning :around #'with-no-drawer) ## Update: How to write into a drawer named "NOTES" Answering a comment below, here's a solution that will log to "NOTES" drawer instead of "LOGBOOK". ;;;; org-agenda-add-note (add to below LOGBOOK, but state changes to LOGBOOK) ;; https://emacs.stackexchange.com/a/46736/29404 (defun ugt-org-agenda-add-note-below-drawer (func &rest args) (interactive "P") (if (eq org-log-note-purpose 'note) (let ((org-log-state-notes-insert-after-drawers t)) (flet ((org-log-into-drawer (&rest args) "NOTES")) ;; initially `nil' (apply func args))) (apply func args))) ;; org-log-beginning needs to be advised ;; because org-add-note simply sets up post-command hook ;; and advice operates only during that setup. (advice-add 'org-log-beginning :around #'ugt-org-agenda-add-note-below-drawer)
vfclists · 2022-05-24 18:12
Is there some way this code can be adapted to put the notes in a named drawer such `NOTES` but still store state changes in the `LOGBOOK` drawer? They way I'm accomplishing that now is by using different functions with different shortcuts. For state changes the function executes `(setq-local org-log-into-drawer "LOGBOOK")` before `org-todo` and for notes it is `(setq-local org-log-into-drawer "NOTES")` before `org-add-note`.
pragmat1c1 · 2022-05-24 18:40
I have updated my post to show how to log into a drawer that's named "NOTES" instead of to "LOGBOOK". See my post above.
vfclists · 2022-05-24 22:44
I'm sure I tried something alog those lines but was confused by the meaning of `flet`. What does the `flet` accomplish? flet is a Lisp macro in ‘cl.el’. (flet ((FUNC ARGLIST BODY...) ...) FORM...) This macro is obsolete since 24.3; use either `cl-flet' or `cl-letf'. Probably introduced at or before Emacs version 24.3. Make temporary overriding function definitions. This is an analogue of a dynamically scoped ‘let’ that operates on the function cell of FUNCs rather than their value cell. If you want the Common-Lisp style of ‘flet’, you should use ‘cl-flet’. The FORMs are evaluated with the specified function definitions in place, then the definitions are undone (the FUNCs go back to their previous definitions, or lack thereof). Does that mean it sets the result of calling the `org-log-into-drawer function` to `"NOTES"`?
pragmat1c1 · 2022-05-25 17:58
`org-log-into-drawer` is defined in `org.el`, and all it does is return the value of the custom variable `org-log-into-drawer` (see `org.el`, there: `(defcustom org-log-into-drawer nil `. `flet` creates a temporary, local binding for functions, not for values (like `let` does). So here we override the function `org-log-into-drawer` temporarily to return the string "NOTES": `(flet ((org-log-into-drawer (&rest args) "NOTES"))`