Update template syntax, allow capture directly to nodes

This commit is contained in:
Jethro Kuan
2021-04-13 19:28:47 +08:00
parent c9636d6551
commit e612b3f068
2 changed files with 97 additions and 115 deletions

View File

@ -54,10 +54,8 @@ during the Org-roam capture process.")
"Keywords used in `org-roam-capture-templates' specific to Org-roam.") "Keywords used in `org-roam-capture-templates' specific to Org-roam.")
(defcustom org-roam-capture-templates (defcustom org-roam-capture-templates
(list (list :key "d" '(("d" "default" plain "%?"
:desc "default" :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org"
:body "%?"
:if-new '(file+head "%<%Y%m%d%H%M%S>-${slug}.org"
"#+title: ${title}\n") "#+title: ${title}\n")
:unnarrowed t)) :unnarrowed t))
"Capture templates for Org-roam. "Capture templates for Org-roam.
@ -68,10 +66,8 @@ TODO: Document this"
) )
(defcustom org-roam-capture-ref-templates (defcustom org-roam-capture-ref-templates
(list (list :key "r" '(("r" "ref" plain "%?"
:desc "ref" :if-new (file+head "${slug}.org"
:body "%?"
:if-new '(file+head "${slug}.org"
"#+title: ${title}") "#+title: ${title}")
:unnarrowed t)) :unnarrowed t))
"The Org-roam templates used during a capture from the roam-ref protocol. "The Org-roam templates used during a capture from the roam-ref protocol.
@ -140,42 +136,27 @@ This function is to be called in the Org-capture finalization process."
(insert (org-link-make-string (concat "id:" id) (insert (org-link-make-string (concat "id:" id)
(org-roam-capture--get :link-description))))))) (org-roam-capture--get :link-description)))))))
(defun org-roam-capture--finalize-create-id () (defun org-roam-capture--add-ref ()
"Get ID for newly captured information."
(let ((buf (org-capture-get :buffer))
(pos (org-capture-get :exact-position)))
(with-current-buffer buf
(org-with-point-at pos
(org-id-get-create)))))
(defun org-roam-capture--add-ref (ref)
"Add REF to the newly captured item." "Add REF to the newly captured item."
(let ((buf (org-capture-get :buffer)) (when-let ((ref (org-roam-capture--get :ref)))
(pos (org-capture-get :exact-position)) (let ((ref-lst (org-entry-get (point) "ROAM_REFS")))n
ref-lst)
(with-current-buffer buf
(org-with-point-at pos
(setq ref-lst (org-entry-get (point) "ROAM_REFS"))
(setq ref-lst (if ref-lst (setq ref-lst (if ref-lst
(cl-pushnew (split-string-and-unquote ref-lst) ref) (cl-pushnew (split-string-and-unquote ref-lst) ref)
(list ref))) (list ref)))
(org-set-property "ROAM_REFS" (combine-and-quote-strings ref-lst)))))) (org-set-property "ROAM_REFS" (combine-and-quote-strings ref-lst)))
(org-roam-capture--add-ref ref)))
(defun org-roam-capture--finalize () (defun org-roam-capture--finalize ()
"Finalize the `org-roam-capture' process." "Finalize the `org-roam-capture' process."
(let ((region (org-roam-capture--get :region)) (when-let ((region (org-roam-capture--get :region)))
id)
(when region
(org-roam-unshield-region (car region) (cdr region))) (org-roam-unshield-region (car region) (cdr region)))
(unless org-note-abort (unless org-note-abort
(setq id (org-roam-capture--finalize-create-id))
(when-let ((ref (org-roam-capture--get :ref)))
(org-roam-capture--add-ref ref))
(when-let ((finalize (org-roam-capture--get :finalize))) (when-let ((finalize (org-roam-capture--get :finalize)))
(funcall (intern (concat "org-roam-capture--finalize-" (funcall (intern (concat "org-roam-capture--finalize-"
(symbol-name (org-roam-capture--get :finalize)))) (symbol-name (org-roam-capture--get :finalize))))
:id id))) :id (org-roam-capture--get :id))))
(remove-hook 'org-capture-after-finalize-hook #'org-roam-capture--finalize))) (remove-hook 'org-capture-after-finalize-hook #'org-roam-capture--finalize))
(defun org-roam-capture--install-finalize () (defun org-roam-capture--install-finalize ()
"Install `org-roam-capture--finalize' if the capture is an Org-roam capture." "Install `org-roam-capture--finalize' if the capture is an Org-roam capture."
@ -184,48 +165,53 @@ This function is to be called in the Org-capture finalization process."
(add-hook 'org-capture-prepare-finalize-hook #'org-roam-capture--install-finalize) (add-hook 'org-capture-prepare-finalize-hook #'org-roam-capture--install-finalize)
(defun org-roam-capture--fill-template (str) (defun org-roam-capture--fill-template (str &optional org-capture-p)
"Expand the template STR, returning the string. "Expand the template STR, returning the expanded template. It expands ${var} occurrences in STR.
This is an extension of org-capture's template expansion. When ORG-CAPTURE-P, also run Org-capture's template expansion."
(funcall (if org-capture-p #'org-capture-fill-template #'identity)
First, it expands ${var} occurrences in STR, using the node in
`org-roam-capture--info'. Next, it expands the remaining template
string using `org-capture-fill-template'."
(org-capture-fill-template
(s-format str (s-format str
(lambda (key) (lambda (key)
(let ((fn (intern (concat "org-roam-node-" key)))) (let ((fn (intern (concat "org-roam-node-" key))))
(if (fboundp fn) (if (fboundp fn)
(funcall fn org-roam-capture--node) (funcall fn org-roam-capture--node)
(completing-read (format "%s: " key) nil))))))) p(completing-read (format "%s: " key) nil)))))))
(defun org-roam-capture--goto-location () (defun org-roam-capture--goto-location ()
"Initialize the buffer, and goto the location of the new capture." "Initialize the buffer, and goto the location of the new capture.
Return the ID of the location."
(pcase (or (org-roam-capture--get :if-new) (pcase (or (org-roam-capture--get :if-new)
(user-error "Template needs to specify `:if-new'")) (user-error "Template needs to specify `:if-new'"))
(`(file ,path) (`(file ,path)
(setq path (expand-file-name (setq path (expand-file-name
(s-trim (org-roam-capture--fill-template path)) (s-trim (org-roam-capture--fill-template path t))
org-roam-directory)) org-roam-directory))
(set-buffer (org-capture-target-buffer path)) (set-buffer (org-capture-target-buffer path))
(widen)) (widen)
(org-roam-capture--add-ref)
(org-id-get-create))
(`(file+olp ,path ,olp) (`(file+olp ,path ,olp)
(setq path (expand-file-name (setq path (expand-file-name
(s-trim (org-roam-capture--fill-template path)) (s-trim (org-roam-capture--fill-template path t))
org-roam-directory)) org-roam-directory))
(set-buffer (org-capture-target-buffer path)) (set-buffer (org-capture-target-buffer path))
(let ((m (org-roam-capture-find-or-create-olp olp))) (let ((m (org-roam-capture-find-or-create-olp olp)))
(goto-char m)) (goto-char m))
(widen)) (widen)
(org-with-point-at 1
(org-roam-capture--add-ref)
(org-id-get-create)))
(`(file+head ,path ,head) (`(file+head ,path ,head)
(setq path (expand-file-name (setq path (expand-file-name
(s-trim (org-roam-capture--fill-template path)) (s-trim (org-roam-capture--fill-template path t))
org-roam-directory)) org-roam-directory))
(let ((exists-p (file-exists-p path))) (let ((exists-p (file-exists-p path)))
(set-buffer (org-capture-target-buffer path)) (set-buffer (org-capture-target-buffer path))
(unless exists-p (unless exists-p
(insert (org-roam-capture--fill-template head)))) (insert (org-roam-capture--fill-template head t))))
(widen)) (widen)
(org-with-point-at 1
(org-roam-capture--add-ref)
(org-id-get-create)))
;; TODO: support node ;; TODO: support node
)) ))
@ -292,7 +278,7 @@ you can catch it with `condition-case'."
"Return exact point to file for org-capture-template. "Return exact point to file for org-capture-template.
This function is used solely in Org-roam's capture templates: see This function is used solely in Org-roam's capture templates: see
`org-roam-capture-templates'." `org-roam-capture-templates'."
(cond ((plist-get org-roam-capture--info :ref) (let ((id (cond ((plist-get org-roam-capture--info :ref)
(if-let ((file-pos (org-roam-capture--get-ref-path (if-let ((file-pos (org-roam-capture--get-ref-path
(plist-get org-roam-capture--info :ref)))) (plist-get org-roam-capture--info :ref))))
(progn (progn
@ -304,30 +290,25 @@ This function is used solely in Org-roam's capture templates: see
(org-roam-node-point org-roam-capture--node)) (org-roam-node-point org-roam-capture--node))
(set-buffer (org-capture-target-buffer (org-roam-node-file org-roam-capture--node))) (set-buffer (org-capture-target-buffer (org-roam-node-file org-roam-capture--node)))
(goto-char (org-roam-node-point org-roam-capture--node)) (goto-char (org-roam-node-point org-roam-capture--node))
(org-end-of-subtree)) (widen)
(org-end-of-subtree t t)
(org-roam-node-id org-roam-capture--node))
(t (t
(org-roam-capture--goto-location))) (org-roam-capture--goto-location)))))
(org-capture-put :template (org-capture-put :template
(org-roam-capture--fill-template (org-capture-get :template))) (org-roam-capture--fill-template (org-capture-get :template)))
(org-roam-capture--put :id id)
(org-roam-capture--put :finalize (or (org-capture-get :finalize) (org-roam-capture--put :finalize (or (org-capture-get :finalize)
(org-roam-capture--get :finalize)))) (org-roam-capture--get :finalize)))))
(defun org-roam-capture--convert-template (template &optional props) (defun org-roam-capture--convert-template (template &optional props)
"Convert TEMPLATE from Org-roam syntax to `org-capture-templates' syntax. "Convert TEMPLATE from Org-roam syntax to `org-capture-templates' syntax.
PROPS is a plist containing additional Org-roam specific PROPS is a plist containing additional Org-roam specific
properties to be added to the template." properties to be added to the template."
(let* ((key (or (plist-get template :key) (pcase template
(user-error "Template has no :key"))) (`(,key ,desc ,type ,body . ,rest)
(desc (or (plist-get template :desc) (setq rest (append rest props))
(user-error "Template has no :desc"))) (let (org-roam-plist options)
(body (or (plist-get template :body)
(user-error "Template has no :body")))
(rest (org-plist-delete template :key))
(rest (org-plist-delete rest :desc))
(rest (org-plist-delete rest :body))
(rest (append rest props))
org-roam-plist
options)
(while rest (while rest
(let* ((key (pop rest)) (let* ((key (pop rest))
(val (pop rest)) (val (pop rest))
@ -338,9 +319,11 @@ properties to be added to the template."
(if custom (if custom
(setq org-roam-plist (plist-put org-roam-plist key val)) (setq org-roam-plist (plist-put org-roam-plist key val))
(setq options (plist-put options key val))))) (setq options (plist-put options key val)))))
(append `(,key ,desc plain #'org-roam-capture--get-point ,body) (append `(,key ,desc ,type #'org-roam-capture--get-point ,body)
options options
(list :org-roam org-roam-plist)))) (list :org-roam org-roam-plist))))
(_
(signal 'invalid-template template))))
;;;###autoload ;;;###autoload
(cl-defun org-roam-capture- (&key goto keys node info props templates) (cl-defun org-roam-capture- (&key goto keys node info props templates)

View File

@ -61,9 +61,8 @@
:type 'hook) :type 'hook)
(defcustom org-roam-dailies-capture-templates (defcustom org-roam-dailies-capture-templates
(list (list :key "d" '(("d" "default" entry
:desc "default" "* %?"
:body "* %?"
:if-new `(file+head ,(concat org-roam-dailies-directory "%<%Y-%m-%d>.org") :if-new `(file+head ,(concat org-roam-dailies-directory "%<%Y-%m-%d>.org")
"#+title: %<%Y-%m-%d>\n"))) "#+title: %<%Y-%m-%d>\n")))
"Capture templates for daily-notes in Org-roam." "Capture templates for daily-notes in Org-roam."