mirror of
https://github.com/org-roam/org-roam
synced 2025-08-01 12:17:21 -05:00
refactor: improve speed of retrieving and formatting nodes
The original code uses macros that when expanded use a lot memory and are relatively slow. This removes some of that processing: - Add a constructor to org-roam-node that does uses parameters by position instead or by name - Add the option of using a function to format nodes. The current code uses a string template. But this template is processes for every node. Using a function will further improve performance significantly. Simplified expected return value user's template function. As suggested by akashpal-21, the return value of the user's template function can be simpler. I have refactored the code such that the function only returns a string (potentially propertized) with the formatted node. I have also modified the documentation of org-roam-node-display-template with an example of the user defined function. Acknowledgement: akashpal-21 for the suggestion for improvement Close: #2511
This commit is contained in:
committed by
Dustin Farris
parent
2ff616fbd8
commit
fed577f805
108
org-roam-node.el
108
org-roam-node.el
@ -39,6 +39,16 @@
|
||||
;;;; Completing-read
|
||||
(defcustom org-roam-node-display-template "${title}"
|
||||
"Configures display formatting for Org-roam node.
|
||||
|
||||
If it is a function, it will be called to format a node.
|
||||
Its result is expected to be a string (potentially with
|
||||
embedded properties).
|
||||
|
||||
If it is a string and it will be used as described in org-roam
|
||||
(see org-roam-node-display-template)
|
||||
|
||||
When it is a string, the following processing is done:
|
||||
|
||||
Patterns of form \"${field-name:length}\" are interpolated based
|
||||
on the current node.
|
||||
|
||||
@ -64,7 +74,21 @@ as many characters as possible and will be aligned accordingly.
|
||||
|
||||
A closure can also be assigned to this variable in which case the
|
||||
closure is evaluated and the return value is used as the
|
||||
template. The closure must evaluate to a valid template string."
|
||||
template. The closure must evaluate to a valid template string.
|
||||
|
||||
When org-roam-node-display-template is a function, the function is
|
||||
expected to return a string, potentially propertized. For example, the
|
||||
following function shows the title and base filename of the node:
|
||||
|
||||
\(defun my--org-roam-format (node)
|
||||
\"formats the node\"
|
||||
(format \"%-40s %s\"
|
||||
(if (org-roam-node-title node)
|
||||
(propertize (org-roam-node-title node) 'face 'org-todo)
|
||||
\"\")
|
||||
(file-name-nondirectory (org-roam-node-file node))))
|
||||
|
||||
\q(setq org-roam-node-display-template 'my--org-roam-format)"
|
||||
:group 'org-roam
|
||||
:type '(string function))
|
||||
|
||||
@ -151,6 +175,11 @@ This path is relative to `org-roam-directory'."
|
||||
|
||||
;;; Definition
|
||||
(cl-defstruct (org-roam-node (:constructor org-roam-node-create)
|
||||
(:constructor org-roam-node-create-from-db
|
||||
(title aliases ; 2
|
||||
id file file-title level todo ; 5
|
||||
point priority scheduled deadline properties ;;5
|
||||
olp file-atime file-mtime tags refs)) ;;5
|
||||
(:copier nil))
|
||||
"A heading or top level file with an assigned ID property."
|
||||
file file-title file-hash file-atime file-mtime
|
||||
@ -352,23 +381,27 @@ nodes."
|
||||
(defun org-roam-node-list ()
|
||||
"Return all nodes stored in the database as a list of `org-roam-node's."
|
||||
(let ((rows (org-roam-db-query
|
||||
"SELECT
|
||||
"
|
||||
SELECT
|
||||
title,
|
||||
aliases,
|
||||
|
||||
id,
|
||||
file,
|
||||
filetitle,
|
||||
\"level\",
|
||||
todo,
|
||||
|
||||
pos,
|
||||
priority ,
|
||||
scheduled ,
|
||||
deadline ,
|
||||
title,
|
||||
properties ,
|
||||
|
||||
olp,
|
||||
atime,
|
||||
mtime,
|
||||
'(' || group_concat(tags, ' ') || ')' as tags,
|
||||
aliases,
|
||||
refs
|
||||
FROM
|
||||
(
|
||||
@ -417,32 +450,20 @@ FROM
|
||||
LEFT JOIN refs ON refs.node_id = nodes.id
|
||||
GROUP BY nodes.id, tags.tag, aliases.alias )
|
||||
GROUP BY id, tags )
|
||||
GROUP BY id")))
|
||||
(cl-loop for row in rows
|
||||
append (pcase-let* ((`(
|
||||
,id ,file ,file-title ,level ,todo ,pos ,priority ,scheduled ,deadline
|
||||
,title ,properties ,olp ,atime ,mtime ,tags ,aliases ,refs)
|
||||
row)
|
||||
(all-titles (cons title aliases)))
|
||||
(mapcar (lambda (temp-title)
|
||||
(org-roam-node-create :id id
|
||||
:file file
|
||||
:file-title file-title
|
||||
:file-atime atime
|
||||
:file-mtime mtime
|
||||
:level level
|
||||
:point pos
|
||||
:todo todo
|
||||
:priority priority
|
||||
:scheduled scheduled
|
||||
:deadline deadline
|
||||
:title temp-title
|
||||
:aliases aliases
|
||||
:properties properties
|
||||
:olp olp
|
||||
:tags tags
|
||||
:refs refs))
|
||||
all-titles)))))
|
||||
GROUP BY id
|
||||
")))
|
||||
(mapcan
|
||||
(lambda (row)
|
||||
(let (
|
||||
(all-titles (cons (car row) (nth 1 row)))
|
||||
)
|
||||
(mapcar (lambda (temp-title)
|
||||
(apply 'org-roam-node-create-from-db (cons temp-title (cdr row))))
|
||||
all-titles)
|
||||
))
|
||||
rows)
|
||||
)
|
||||
)
|
||||
|
||||
;;;; Finders
|
||||
(defun org-roam-node-marker (node)
|
||||
@ -556,6 +577,25 @@ PROMPT is a string to show at the beginning of the mini-buffer, defaulting to \"
|
||||
(or (cdr (assoc node nodes))
|
||||
(org-roam-node-create :title node))))
|
||||
|
||||
(defun org-roam--format-nodes-using-template (nodes)
|
||||
"Formats NODES using org-roam template features.
|
||||
Uses org-roam--node-display-template."
|
||||
(let (
|
||||
(wTemplate (org-roam-node--process-display-format org-roam-node-display-template))
|
||||
)
|
||||
(mapcar (lambda (node)
|
||||
(org-roam-node-read--to-candidate node wTemplate)) nodes))
|
||||
)
|
||||
|
||||
(defun org-roam--format-nodes-using-function (nodes)
|
||||
"Formats NODES using the function org-roam-node-display-template."
|
||||
(mapcar (lambda (node)
|
||||
(cons
|
||||
(propertize (funcall org-roam-node-display-template node) 'node node)
|
||||
node))
|
||||
nodes)
|
||||
)
|
||||
|
||||
(defun org-roam-node-read--completions (&optional filter-fn sort-fn)
|
||||
"Return an alist for node completion.
|
||||
The car is the displayed title or alias for the node, and the cdr
|
||||
@ -565,15 +605,17 @@ and when nil is returned the node will be filtered out.
|
||||
SORT-FN is a function to sort nodes. See `org-roam-node-read-sort-by-file-mtime'
|
||||
for an example sort function.
|
||||
The displayed title is formatted according to `org-roam-node-display-template'."
|
||||
(let* ((template (org-roam-node--process-display-format org-roam-node-display-template))
|
||||
(let* (
|
||||
(nodes (org-roam-node-list))
|
||||
(nodes (if filter-fn
|
||||
(cl-remove-if-not
|
||||
(lambda (n) (funcall filter-fn n))
|
||||
nodes)
|
||||
nodes))
|
||||
(nodes (mapcar (lambda (node)
|
||||
(org-roam-node-read--to-candidate node template)) nodes))
|
||||
(nodes (if (functionp org-roam-node-display-template)
|
||||
(org-roam--format-nodes-using-function nodes)
|
||||
(org-roam--format-nodes-using-template nodes)))
|
||||
|
||||
(sort-fn (or sort-fn
|
||||
(when org-roam-node-default-sort
|
||||
(intern (concat "org-roam-node-read-sort-by-"
|
||||
|
Reference in New Issue
Block a user