(feat)org-roam-node-random: support filter-fn (#2050)

This commit is contained in:
Jethro Kuan
2022-01-19 14:23:57 -08:00
committed by GitHub
parent bf3ebe2121
commit c17310f0de
2 changed files with 31 additions and 24 deletions

View File

@ -2,7 +2,8 @@
## TBD ## TBD
### Added ### Added
- [#2042](https://github.com/org-roam/org-roam/pull/2042) db: add `org-roam-db-extra-links-elements` and `org-roam-db-extra-links-exclude-keys` for fine-grained control over additional link parsing - [#2042](https://github.com/org-roam/org-roam/pull/2042) db: add `org-roam-db-extra-links-elements` and `org-roam-db-extra-links-exclude-keys` for fine-grained control over additional link parsing
- [#2049](https://github.com/org-roam/org-roam/pull/2049) capture: allow ID to be used as part of `org-roam-capture-templates` - [#2049](https://github.com/org-roam/org-roam/pull/2049) capture: allow ID to be used as part of `org-roam-capture-templates`
- [#2050](https://github.com/org-roam/org-roam/pull/2050) core: add `FILTER-FN` to `org-roam-node-random`
### Removed ### Removed
### Fixed ### Fixed
### Changed ### Changed

View File

@ -477,16 +477,16 @@ The TEMPLATES, if provided, override the list of capture templates (see
:props '(:finalize find-file))))) :props '(:finalize find-file)))))
;;;###autoload ;;;###autoload
(defun org-roam-node-random (&optional other-window) (defun org-roam-node-random (filter-fn &optional other-window)
"Find and open a random Org-roam node. "Find and open a random Org-roam node.
With prefix argument OTHER-WINDOW, visit the node in another With prefix argument OTHER-WINDOW, visit the node in another
window instead." window instead.
FILTER-FN is a function to filter out nodes: it takes an `org-roam-node',
and when nil is returned the node will be filtered out."
(interactive current-prefix-arg) (interactive current-prefix-arg)
(let ((random-row (seq-random-elt (org-roam-db-query [:select [id file pos] :from nodes])))) (org-roam-node-visit
(org-roam-node-visit (org-roam-node-create :id (nth 0 random-row) (cdr (seq-random-elt (org-roam-node-read--completions filter-fn)))
:file (nth 1 random-row) other-window))
:point (nth 2 random-row))
other-window)))
;;;; Completing-read interface ;;;; Completing-read interface
(defun org-roam-node-read (&optional initial-input filter-fn sort-fn require-match prompt) (defun org-roam-node-read (&optional initial-input filter-fn sort-fn require-match prompt)
@ -498,17 +498,7 @@ SORT-FN is a function to sort nodes. See `org-roam-node-read-sort-by-file-mtime'
for an example sort function. for an example sort function.
If REQUIRE-MATCH, the minibuffer prompt will require a match. If REQUIRE-MATCH, the minibuffer prompt will require a match.
PROMPT is a string to show at the beginning of the mini-buffer, defaulting to \"Node: \"" PROMPT is a string to show at the beginning of the mini-buffer, defaulting to \"Node: \""
(let* ((nodes (org-roam-node-read--completions)) (let* ((nodes (org-roam-node-read--completions filter-fn sort-fn))
(nodes (if filter-fn
(cl-remove-if-not
(lambda (n) (funcall filter-fn (cdr n)))
nodes)
nodes))
(sort-fn (or sort-fn
(when org-roam-node-default-sort
(intern (concat "org-roam-node-read-sort-by-"
(symbol-name org-roam-node-default-sort))))))
(_ (when sort-fn (setq nodes (seq-sort sort-fn nodes))))
(prompt (or prompt "Node: ")) (prompt (or prompt "Node: "))
(node (completing-read (node (completing-read
prompt prompt
@ -529,15 +519,31 @@ PROMPT is a string to show at the beginning of the mini-buffer, defaulting to \"
(or (cdr (assoc node nodes)) (or (cdr (assoc node nodes))
(org-roam-node-create :title node)))) (org-roam-node-create :title node))))
(defun org-roam-node-read--completions () (defun org-roam-node-read--completions (&optional filter-fn sort-fn)
"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
is the `org-roam-node'. is the `org-roam-node'.
FILTER-FN is a function to filter out nodes: it takes an `org-roam-node',
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'." 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* ((template (org-roam-node--process-display-format org-roam-node-display-template))
(nodes (org-roam-node-list))) (nodes (org-roam-node-list))
(mapcar (lambda (node) (nodes (mapcar (lambda (node)
(org-roam-node-read--to-candidate node template)) nodes))) (org-roam-node-read--to-candidate node template)) nodes))
(nodes (if filter-fn
(cl-remove-if-not
(lambda (n) (funcall filter-fn (cdr n)))
nodes)
nodes))
(sort-fn (or sort-fn
(when org-roam-node-default-sort
(intern (concat "org-roam-node-read-sort-by-"
(symbol-name org-roam-node-default-sort))))))
(nodes (if sort-fn (seq-sort sort-fn nodes)
nodes)))
nodes))
(defun org-roam-node-read--to-candidate (node template) (defun org-roam-node-read--to-candidate (node template)
"Return a minibuffer completion candidate given NODE. "Return a minibuffer completion candidate given NODE.