Task management with org-roam Vol. 4: Automatic tagging
In the previous article we covered automatic tagging of notes related to a specific person, and today we are going to cover automatic tagging of an org-mode heading upon insertion of link related to a person. To put it simple, when I mention someone in the task, I would love this task to be automatically tagged with that persons name. As they say, it’s better to see once, than imagine multiple times, so here is a screencast.
Change Log:
[2021-01-24 Sun]
: Since some of the functionality mentioned in the original article was merged toorg-roam
, all code is updated to reflect the current state of affairs.[2021-03-02 Tue]
: Update naming convention to match personal configurations.[2021-05-10 Mon]
: Update post to reflect changes in org-roam v2. Previous version of this article is available on GitHub.[2021-11-19 Fri]
: Update post to reflect inclusion ofvulpea-insert
function tovulpea
library. You can find previous version of this article in git history.
Once could just write an advice for org-roam-node-insert
by using a relatively recent change that makes this function to return what was inserted. This also uses name manipulation from the previous article and tags lookup from Org-roam tags article.
defun org-roam-node-insert-wrapper (fn)
("Insert a link to the note using FN.
If inserted node has PEOPLE tag on it, tag the current outline
accordingly."
(interactive)
(when-let*funcall fn))
((node (
(title (org-roam-node-title node))
(tags (org-roam-node-tags node)))when (seq-contains-p tags "people")
(
(save-excursionignore-errors
(
(org-back-to-heading)
(org-set-tags
(seq-uniqcons
(
(vulpea--title-to-tag title)nil t)))))))))
(org-get-tags
(advice-add
#'org-roam-node-insert
:around #'org-roam-node-insert-wrapper)
The implementation is straight-forward. We start with calling fn
(e.g. org-roam-node-insert
) that asks for the note to insert. Then we parse result and query the roam tags to understand if the inserted note is related to a person. And if the answer is yes, we use org-set-tags
to automatically tag the heading.
And while advicing is powerful tool and allows us to solve the problem, there is slightly different, less intrusive and composable solution provided by vulpea
library - vulpea-insert
function that acts like org-roam-node-insert
, but provides ability setup hooks on insertion. First, we define a handler (pretty much the same as org-roam-node-insert-wrapper
but without any calls to insertion function).
defun my-vulpea-insert-handle (note)
("Hook to be called on NOTE after `vulpea-insert'."
(when-let* ((title (vulpea-note-title note))
(tags (vulpea-note-tags note)))when (seq-contains-p tags "people")
(
(save-excursionignore-errors
(
(org-back-to-heading)when (eq 'todo (org-element-property
(
:todo-type
(org-element-at-point)))
(org-set-tags
(seq-uniqcons
(
(vulpea--title-to-tag title)nil t)))))))))) (org-get-tags
And then you just need to add it as a hook:
(add-hook 'vulpea-insert-handle-functions #'my-vulpea-insert-handle)
With this approach you can add as many handlers as you wish without the need to grow your advice/wrapper too much.
Complete solution
defun my-vulpea-insert-handle (note)
("Hook to be called on NOTE after `vulpea-insert'."
(when-let* ((title (vulpea-note-title note))
(tags (vulpea-note-tags note)))when (seq-contains-p tags "people")
(
(save-excursionignore-errors
(
(org-back-to-heading)when (eq 'todo (org-element-property
(
:todo-type
(org-element-at-point)))
(org-set-tags
(seq-uniqcons
(
(vulpea--title-to-tag title)nil t))))))))))
(org-get-tags
defun vulpea--title-to-tag (title)
("Convert TITLE to tag."
"@" (s-replace " " "" title)))
(concat
(add-hook 'vulpea-insert-handle-functions
#'my-vulpea-insert-handle)
Task Management with org-roam Series
- Path to Roam
- Categories
- FILETAGS
- Automatic tagging
- Dynamic and fast agenda
- Select a person and view related tasks
- Capture
References
org-roam
documentation on GitHub.org-mode
documentation on the official site.- Org-roam tags post.
- personal configurations on GitHub.