From 9add49f478a49fd1a41dd4345df56eb3e265101c Mon Sep 17 00:00:00 2001 From: Kiana Sheibani Date: Wed, 14 Aug 2024 05:15:30 -0400 Subject: [PATCH] feat(org): overhaul `org-roam` capture --- config.org | 55 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/config.org b/config.org index 3edf285..e61b230 100644 --- a/config.org +++ b/config.org @@ -3465,17 +3465,22 @@ Since Org-roam is currently my primary method of using Org, I only use its templ (read-directory-name "Directory: " org-roam-directory)))) #+end_src -I want there to only be one capture template when I'm making new links, so that I don't get distracted. However, when I'm explicitly telling Roam to make a new node, it would be a shame if there was only one option. To fix this, I'll add new variables representing the /default/ templates to use in situations where I don't want to have to choose. +I want there to only be one capture template when I'm making new links, so that I don't get distracted by a prompt. However, when I'm explicitly telling Roam to use node capture, it would be a shame if there was only one option. To fix this, I can split my capture templates into three contexts: a default template for when not explicitly capturing, a list of templates for capturing on a node that already exists, and the regular list for when the node is new. #+begin_src emacs-lisp (defvar org-roam-capture-default-template nil "The default capture template to use when not explicitly capturing.") +(defvar org-roam-capture-existing-templates nil + "Capture templates to use when capturing on an existing node.") + (defvar org-roam-dailies-capture-default-template nil "The default daily capture template to use when not explicitly capturing.") #+end_src +(We don't distinguish between new and existing dailies, since dailies are meant to follow a single format, which can just be covered by the default template.) + With those variables created, we can define our templates. #+begin_src emacs-lisp @@ -3493,26 +3498,12 @@ With those variables created, we can define our templates. "#+title: %<%Y-%m-%d>") :unnarrowed t :immediate-finish t)) - ;; Active templates + ;; new-file templates (setq org-roam-capture-templates '(("f" "Standalone file" plain "" :target (file+head "${file-maybe-dir}" "#+title: ${title}") - :unnarrowed t) - ("n" "Citation Note" plain "" - :target (file+head "${file-maybe-cite}" - "#+title: ${note-title}") - :immediate-finish t - :unnarrowed t) - ("h" "Heading" entry - "`(make-string (org-outline-level) ?*)`* ${title} -:RELATED: -Subnote of `(let ((node (org-roam-node-at-point))) - (format \"[[id:%s][%s]]\" - (org-roam-node-id node) - (org-roam-node-title node)))`$1 -:END:\n\n$0" - :target (file "20240329114914-a.org"))) + :unnarrowed t)) org-roam-dailies-capture-templates '(("e" "Event" entry "* $1\n%^t\n\n$0" :target (file+head "%<%Y-%m-%d>.org" @@ -3534,10 +3525,22 @@ Now we just have to advise Org-roam with the proper logic! #+begin_src emacs-lisp (defadvice! ~/org-roam-default-capture (old-fn &rest args) "Use default capture template when not explicitly capturing." - :around '(org-roam-node-find org-roam-node-insert) + :around #'org-roam-node-insert (let ((org-roam-capture-templates (list org-roam-capture-default-template))) (apply old-fn args))) +(cl-defun ~/org-roam-capture (&optional goto keys &key filter-fn templates info) + (let ((node (org-roam-node-read nil filter-fn))) + (org-roam-capture- :goto goto + :info info + :keys keys + :templates (or templates + (when (org-roam-node-file node) + org-roam-capture-existing-templates)) + :node node + :props '(:immediate-finish nil)))) +(advice-add #'org-roam-capture :override #'~/org-roam-capture) + (defadvice! ~/org-roam-dailies-default-capture (old-fn time &optional goto keys) "Use default capture template when not explicitly capturing." :around #'org-roam-dailies--capture @@ -3675,7 +3678,23 @@ This "overview" agenda command is very nice. It's so nice, in fact, that it's al "o A" #'org-agenda) #+end_src +*** TODO Tweaks +When finding a node with ~org-roam-node-find~, the universal argument to open it in another window doesn't work when the node is new. We can fix this with an override: + +#+begin_src emacs-lisp +(cl-defun ~/org-roam-node-find (&optional other-window initial-input filter-fn pred &key templates) + (let ((node (org-roam-node-read initial-input filter-fn pred))) + (if (org-roam-node-file node) + (org-roam-node-visit node other-window) + (org-roam-capture- + :node node + :templates (or templates (list org-roam-capture-default-template)) + :props (if other-window + '(:after-finalize find-file-other-window) + '(:finalize find-file)))))) +(advice-add #'org-roam-node-find :override #'~/org-roam-node-find) +#+end_src ** Citations