From 3c6e1b5194ab70e5a3f41029bd4da69d14d47408 Mon Sep 17 00:00:00 2001 From: Jethro Kuan Date: Wed, 21 Apr 2021 01:53:47 +0800 Subject: [PATCH] add interactive functions Added org-roam-{alias,ref}-{add,remove}. Fixed org-roam-protocol. Added some docs. --- doc/org-roam.org | 96 +++++++++++++++++++++++++++++++------------- org-roam-capture.el | 36 ++++++----------- org-roam-protocol.el | 1 - org-roam.el | 40 ++++++++++++++++++ 4 files changed, 122 insertions(+), 51 deletions(-) diff --git a/doc/org-roam.org b/doc/org-roam.org index 708be4f..46b957d 100644 --- a/doc/org-roam.org +++ b/doc/org-roam.org @@ -467,42 +467,84 @@ for predictable navigation: Org-roam buffer. - ~C-u RET~ navigates to thing-at-point in the other window. -* TODO Node Properties -** TODO Standard Org properties -** TODO Aliases -** TODO Refs -:PROPERTIES: -:ID: 57c1f991-be38-4fab-b27d-60227047f3b7 -:END: -Refs are unique identifiers for files. For example, a note for a website may -contain a ref: +* Node Properties +** Standard Org properties -#+BEGIN_SRC org - #+title: Google - #+roam_key: https://www.google.com/ -#+END_SRC +Org-roam caches most of the standard Org properties. The full list now includes: -These keys allow references to the key to show up in the backlinks buffer. For -instance, with the example above, if another file then links to -https://www.google.com, that will show up as a “Ref Backlink”. +- outline level +- todo state +- priority +- scheduled +- deadline +- tags + +** Titles and Aliases + +Each node has a single title. For file nodes, this is specified with the +`#+title` property for the file. For headline nodes, this is the main text. + +Nodes can also have multiple aliases. Aliases allow searching for nodes via an +alternative name. For example, one may want to assign a well-known acronym (AI) +to a node titled "Artificial Intelligence". + +To assign an alias to a node, add the "ROAM_ALIASES" property to the node: + +#+begin_src org + ,* Artificial Intelligence + :PROPERTIES: + :ROAM_ALIASES: AI + :END: +#+end_src + +Alternatively, Org-roam provides some functions to add or remove aliases. + +- Function: org-roam-alias-add alias + + Add ALIAS to the node at point. When called interactively, prompt for the + alias to add. + +- Function: org-roam-alias-remove + + Remove an alias from the node at point. + +** Refs + +Refs are unique identifiers for nodes. These keys allow references to the key to +show up in the Org-roam buffer. For example, a node for a website may use the URL +as the ref, and a node for a paper may use an Org-ref citation key. + +To add a ref, add to the "ROAM_REFS" property as follows: + +#+begin_src org + ,* Google + :PROPERTIES: + :ROAM_REFS: https://www.google.com/ + :END: +#+end_src + +With the above example, if another node links to https://www.google.com/, it +will show up as a “reference backlink”. These keys also come in useful for when taking website notes, using the ~roam-ref~ protocol (see [[*Roam Protocol][Roam Protocol]]). -[[https://github.com/jkitchin/org-ref][org-ref]] citation keys can also be used as refs: - -#+BEGIN_SRC org - #+title: Neural Ordinary Differential Equations - #+roam_key: cite:chen18_neural_ordin_differ_equat -#+END_SRC - -#+CAPTION: org-ref-citelink -[[file:images/org-ref-citelink.png]] - -You may assign multiple refs to a single file, for example when you want +You may assign multiple refs to a single node, for example when you want multiple papers in a series to share the same note, or an article has a citation key and a URL at the same time. +Org-roam also provides some functions to add or remove refs. + +- Function: org-roam-ref-add ref + + Add REF to the node at point. When called interactively, prompt for the + ref to add. + +- Function: org-roam-ref-remove + + Remove a ref from the node at point. + + * TODO The Org-roam Buffer * TODO Styling Org-roam * TODO Completion diff --git a/org-roam-capture.el b/org-roam-capture.el index 066915d..b85f3ca 100644 --- a/org-roam-capture.el +++ b/org-roam-capture.el @@ -40,6 +40,8 @@ (require 'cl-lib) ;; Declarations +(declare-function org-roam-ref-add "org-roam" (ref)) + (defvar org-roam-directory) (defvar org-roam-capture--node nil @@ -458,16 +460,6 @@ This function is to be called in the Org-capture finalization process." (insert (org-link-make-string (concat "id:" (org-roam-capture--get :id)) (org-roam-capture--get :link-description))))))) -(defun org-roam-capture--add-ref () - "Add REF to the newly captured item." - (when-let ((ref (org-roam-capture--get :ref))) - (let ((ref-lst (org-entry-get (point) "ROAM_REFS")))n - (setq ref-lst (if ref-lst - (cl-pushnew (split-string-and-unquote ref-lst) ref) - (list ref))) - (org-set-property "ROAM_REFS" (combine-and-quote-strings ref-lst))) - (org-roam-capture--add-ref ref))) - (defun org-roam-capture--finalize () "Finalize the `org-roam-capture' process." (when-let ((region (org-roam-capture--get :region))) @@ -500,7 +492,7 @@ run Org-capture's template expansion." (defun org-roam-capture--goto-location () "Initialize the buffer, and goto the location of the new capture. Return the ID of the location." - (let (id) + (let (p) (pcase (or (org-roam-capture--get :if-new) (user-error "Template needs to specify `:if-new'")) (`(file ,path) @@ -509,16 +501,13 @@ Return the ID of the location." org-roam-directory)) (set-buffer (org-capture-target-buffer path)) (widen) - (org-roam-capture--add-ref) - (setq id (org-id-get-create))) + (setq p (point))) (`(file+olp ,path ,olp) (setq path (expand-file-name (s-trim (org-roam-capture--fill-template path t)) org-roam-directory)) (set-buffer (org-capture-target-buffer path)) - (org-with-point-at 1 - (org-roam-capture--add-ref) - (setq id (org-id-get-create))) + (setq p (point-min)) (let ((m (org-roam-capture-find-or-create-olp olp))) (goto-char m)) (widen)) @@ -531,9 +520,7 @@ Return the ID of the location." (unless exists-p (insert (org-roam-capture--fill-template head t)))) (widen) - (org-with-point-at 1 - (org-roam-capture--add-ref) - (setq id (org-id-get-create)))) + (setq p (point-min))) (`(file+head+olp ,path ,head ,olp) (setq path (expand-file-name (s-trim (org-roam-capture--fill-template path t)) @@ -543,9 +530,7 @@ Return the ID of the location." (set-buffer (org-capture-target-buffer path)) (unless exists-p (insert (org-roam-capture--fill-template head t)))) - (org-with-point-at 1 - (org-roam-capture--add-ref) - (setq id (org-id-get-create))) + (setq p (point-min)) (let ((m (org-roam-capture-find-or-create-olp olp))) (goto-char m))) (`(node ,title-or-id) @@ -555,9 +540,14 @@ Return the ID of the location." (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)) + (setq p (org-roam-node-point node)) (org-end-of-subtree t t) (setq id (org-roam-node-id node))))) - id)) + (save-excursion + (goto-char p) + (when-let ((ref (plist-get org-roam-capture--info :ref))) + (org-roam-ref-add ref)) + (org-id-get-create)))) (defun org-roam-capture-find-or-create-olp (olp) "Return a marker pointing to the entry at OLP in the current buffer. diff --git a/org-roam-protocol.el b/org-roam-protocol.el index 343305d..2a962b4 100644 --- a/org-roam-protocol.el +++ b/org-roam-protocol.el @@ -79,7 +79,6 @@ It opens or creates a note with the given ref. :node (org-roam-node-create :title (plist-get info :title)) :info (list :ref (plist-get info :ref) :body (plist-get info :body)) - :props (list :ref (plist-get info :ref)) :templates org-roam-capture-ref-templates) nil) diff --git a/org-roam.el b/org-roam.el index a87227c..4ba9556 100644 --- a/org-roam.el +++ b/org-roam.el @@ -771,6 +771,46 @@ window instead." :point (nth 2 random-row)) other-window))) +;;;; Properties +(defun org-roam-add-property (s prop) + "Add S to property PROP." + (let* ((p (org-entry-get (point) prop)) + (lst (when p (split-string-and-unquote p))) + (lst (if (memq s lst) lst (cons s lst)))) + (org-set-property prop (combine-and-quote-strings lst)))) + +(defun org-roam-remove-property (prop) + "Prompt to remove an item from PROP." + (let* ((p (org-entry-get (point) prop)) + (lst (when p (split-string-and-unquote p))) + (prop-to-remove (completing-read "Remove: " lst)) + (lst (delete prop-to-remove lst))) + (if lst + (org-set-property prop (combine-and-quote-strings lst)) + (org-delete-property prop)))) + +;;;; Aliases +(defun org-roam-alias-add (alias) + "Add ALIAS to the node at point." + (interactive "sAlias: ") + (org-roam-add-property alias "ROAM_ALIASES")) + +(defun org-roam-alias-remove () + "Remove an alias from the node at point." + (interactive) + (org-roam-remove-property "ROAM_ALIASES")) + +;;;; Refs +(defun org-roam-ref-add (ref) + "Add REF to the node at point." + (interactive "sRef: ") + (org-roam-add-property ref "ROAM_REFS")) + +(defun org-roam-ref-remove () + "Remove a ref from the node at point." + (interactive) + (org-roam-remove-property "ROAM_REFS")) + ;;;; Backlinks (cl-defstruct (org-roam-backlink (:constructor org-roam-backlink-create) (:copier nil))