support node in org-roam-capture

This commit is contained in:
Jethro Kuan
2021-04-20 19:24:56 +08:00
parent d465ea0d72
commit 05d95abc2e
2 changed files with 48 additions and 38 deletions

View File

@ -548,8 +548,15 @@ Return the ID of the location."
(setq id (org-id-get-create))) (setq id (org-id-get-create)))
(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)))
;; TODO: support node (`(node ,title-or-id)
) ;; first try to get ID, then try to get title/alias
(let ((node (or (org-roam-node-from-id title-or-id)
(org-roam-node-from-title-or-alias title-or-id)
(user-error "No node with title or id \"%s\" title-or-id"))))
(set-buffer (org-capture-target-buffer (org-roam-node-file node)))
(goto-char (org-roam-node-point node))
(org-end-of-subtree t t)
(setq id (org-roam-node-id node)))))
id)) id))
(defun org-roam-capture-find-or-create-olp (olp) (defun org-roam-capture-find-or-create-olp (olp)

View File

@ -583,6 +583,35 @@ instead."
#'switch-to-buffer-other-window #'switch-to-buffer-other-window
#'pop-to-buffer-same-window) buf))) #'pop-to-buffer-same-window) buf)))
(defun org-roam-node-from-id (id)
"Return an `org-roam-node' for the node containing ID.
Return nil if a node with ID does not exist."
(when (org-roam-db-query [:select (funcall count) :from nodes
:where (= id $s1)]
id)
(org-roam-populate (org-roam-node-create :id id))))
(defun org-roam-node-from-title-or-alias (s)
"Return an `org-roam-node' for the node with title or alias S.
Return nil if the node does not exist.
Throw an error if multiple choices exist."
(let ((matches (seq-uniq
(append
(org-roam-db-query [:select [id] :from nodes
:where (= title $s1)]
s)
(org-roam-db-query [:select [node-id] :from aliases
:left :join nodes :on (= nodes:id aliases:node-id)
:where (= aliases:node-id $s1)]
s)))))
(cond
((seq-empty-p matches)
nil)
((= 1 (length matches))
(org-roam-populate (org-roam-node-create :id (caar matches))))
(t
(user-error "Multiple nodes exist with title or alias \"%s\"" s)))))
(defun org-roam-node--completions () (defun org-roam-node--completions ()
"Return an alist for node completion. "Return an alist for node completion.
The car is the displayed title or alias for the node, and the cdr The car is the displayed title or alias for the node, and the cdr
@ -1026,10 +1055,16 @@ References from FILE are excluded."
This function is called by Org when following links of the type This function is called by Org when following links of the type
`roam'. While the path is passed, assume that the cursor is on `roam'. While the path is passed, assume that the cursor is on
the link." the link."
(pcase-let ((`(,id ,file ,pos) (org-roam-link-locate))) (pcase (org-element-lineage (org-element-context) '(link) t)
('nil (error "Not at Org link"))
(link
(if (not (string-equal "roam" (org-element-property :type link)))
(error "Not at an Org-roam link")
(let* ((title (org-element-property :path link))
(node (org-roam-node-from-title-or-alias title)))
(when org-roam-link-auto-replace (when org-roam-link-auto-replace
(org-roam-link--replace-link id path)) (org-roam-link--replace-link (org-roam-node-id node) path))
(org-id-goto id))) (org-id-goto (org-roam-node-id node)))))))
(defun org-roam-link--replace-link (id &optional desc) (defun org-roam-link--replace-link (id &optional desc)
"Replace link at point with a vanilla Org link. "Replace link at point with a vanilla Org link.
@ -1045,38 +1080,6 @@ DESC is the link description."
(concat "id:" id) (concat "id:" id)
desc))))) desc)))))
(defun org-roam-link-locate ()
"Return the location of the roam link at point.
This is a list of three items: the node id, the file, and point
in the file."
(let ((context (org-element-context))
path matches)
(pcase (org-element-lineage context '(link) t)
('nil (error "Not at Org link"))
(link
(if (not (string-equal "roam" (org-element-property :type link)))
(error "Not at an Org-roam link")
(setq path (org-element-property :path link))
(setq matches (seq-uniq
(append
(org-roam-db-query [:select [id file pos] :from nodes
:where (= title $s1)]
path)
(org-roam-db-query [:select [node-id aliases:file nodes:pos] :from aliases
:left :join nodes :on (= nodes:id aliases:node-id)
:where (= aliases:node-id $s1)]
path))))
(cond
((seq-empty-p matches)
;; TODO: prompt to capture new note.
(message "No matches."))
((= 1 (length matches))
(car matches))
(t
;; TODO: need to fix UX somehow
(let ((choice (completing-read "Choose node:" matches nil t)))
(cdr (assoc choice matches #'string-equal))))))))))
;;; Retrieval Functions ;;; Retrieval Functions
(defun org-roam-link--get-node-from-title (title) (defun org-roam-link--get-node-from-title (title)
"Return the node id for a given TITLE." "Return the node id for a given TITLE."