This is a package for easily selecting notes via consult. It’s most basic use is
to integrate directories of files (notes) and to provide easy narrowing via
consult. But notes can be in principle added from any source that can be
integrated with consult.
consult-notes can be used with any directory (or directories) of note files and
is useful for note systems like zk or denote. It also provides first-class
integration with org-roam, where not only files but also org headings can count
as “nodes” or notes.
Consult-notes also provides annotations on note candidates in the minibuffer (currently directory, file size, last-modfied time, and, for org-roam, tags and number of backlinks. Consult-notes may be configured to act on selected candidates via embark (see below).
This package is available on MELPA. Or you can install the package from this repo. Installation with use-package and straight is pretty easy:
(use-package consult-notes
:straight (:type git :host github :repo "mclear-tools/consult-notes")
:commands (consult-notes
consult-notes-search-in-all-notes
consult-notes-org-roam-find-node
consult-notes-org-roam-find-node-relation)
:config
(setq consult-notes-sources '("Name" ?key "path/to/dir")) ;; Set notes dir(s), see below
(consult-notes-org-roam-mode)) ;; Set org-roam integrationSet notes directories via consult-notes-sources. This is a list that consists of
three elements: a title heading, a key (for narrowing), and a directory path.
For example:
(setq consult-notes-sources
'(("Org" ?o "~/Dropbox/org-files")
("Org Refile" ?r "~/Dropbox/Work/projects/notebook/org-refile")))consult-multi will take each of these sources and present them together in one
integrated consult completion buffer. To narrow to a particular source, use its
designated narrowing key.
NOTE: If you don’t use any sources beyond that of files in directories, then you
don’t need to set anything other than consult-notes-sources. Org-roam sources
are set by using the minor-mode consult-notes-org-roam-mode (see below). On the
other hand, if you do want to integrate other different kinds of sources (e.g.
bookmarks or buffers) into consult-notes then please see the instructions for
adding multiple sources with consult. To add an additional non-directory source
one should do so by means of add-to-list in one’s config, e.g.
(with-eval-after-load 'consult-notes
(add-to-list 'consult-notes--all-sources 'my-notes--additional-source 'append))You may customize narrowing keys, separator names and annotations used. Please
see customize-group RET 'consult-notes' RET (or the relevant `.el’ files) for
details. The faces used by consult-notes are all similarly customizable.
Though consult-notes by default searches only for names of files (or if using
org-roam, the names of nodes), you may also easily search the contents of all
notes in consult-notes-sources using the function
consult-notes-search-in-all-notes. This uses consult-grep or consult-ripgrep as
its basis (see the consult-notes-use-rg variable). You can set the arguments for
the grep or ripgrep search with the variables consult-notes-grep-args and
consult-notes-ripgrep-args respectively.
Org-roam may be used in conjunction with consult-notes but two things should be kept in mind. First, org-roam works primarily with the concept of a ‘node’, which can be either a file or a headline within a file. This means we need to add org-roam sources differently from that of standard directory sources. Second, org-roam provides its own completing read interface, which needs to be integrated with consult-notes.
So, if you want to integrate consult-notes with org-roam, be sure to call the
minor-mode integration via the function (consult-notes-org-roam-mode). This sets
up a minor that provides some useful functions to integrate search of org-roam
nodes and of org-roam references with the consult-notes search and display
functions. It also sets the org-roam display interface to look like that of the
consult-notes interface when used apart from consult (e.g. in calling
org-roam-node-find). It adds all your org-roam nodes (whether files or
headlines) to the consult-notes interface (you don’t need to do anything
additional for this – it simply reads off of your org-roam settings), and it
adds your org-roam directory to the list of directories on which
consult-notes-search-in-all-notes runs. More functionality may be added in the
future.
If you use embark you can integrate consult-notes actions with embark like so:
(defun consult-notes-open-dired (cand)
"Open notes directory dired with point on file CAND."
(interactive "fNote: ")
;; dired-jump is in dired-x.el but is moved to dired in Emacs 28
(dired-jump nil cand))
(defun consult-notes-marked (cand)
"Open a notes file CAND in Marked 2.
Marked 2 is a mac app that renders markdown."
(interactive "fNote: ")
(call-process-shell-command (format "open -a \"Marked 2\" \"%s\"" (expand-file-name cand))))
(defun consult-notes-grep (cand)
"Run grep in directory of notes file CAND."
(interactive "fNote: ")
(consult-grep (file-name-directory cand)))
(embark-define-keymap consult-notes-map
"Keymap for Embark notes actions."
:parent embark-file-map
("d" consult-notes-dired)
("g" consult-notes-grep)
("m" consult-notes-marked))
(add-to-list 'embark-keymap-alist `(,consult-notes-category . consult-notes-map))
;; make embark-export use dired for notes
(setf (alist-get consult-notes-category embark-exporters-alist) #'embark-export-dired)If you use citar you can integrate support with consult-notes and org-roam as follows:
;; Search org-roam notes for citations (depends on citar)
(defun consult-notes-org-roam-cited (reference)
"Return a list of notes that cite the REFERENCE."
(interactive (list (citar-select-ref
:rebuild-cache current-prefix-arg
:filter (citar-has-note))))
(let* ((ids
(org-roam-db-query [:select * :from citations
:where (= cite-key $s1)]
(car reference)))
(anodes
(mapcar (lambda (id)
(org-roam-node-from-id (car id)))
ids))
(template
(org-roam-node--process-display-format org-roam-node-display-template))
(bnodes
(mapcar (lambda (node)
(org-roam-node-read--to-candidate node template)) anodes))
(node (completing-read
"Node: "
(lambda (string pred action)
(if (eq action 'metadata)
`(metadata
;; get title using annotation function
(annotation-function
. ,(lambda (title)
(funcall org-roam-node-annotation-function
(get-text-property 0 'node title))))
(category . org-roam-node))
(complete-with-action action bnodes string pred)))))
(fnode
(cdr (assoc node bnodes))))
(if ids
;; Open node in other window
(org-roam-node-open fnode)
(message "No notes cite this reference."))))- Consult-org-roam offers consult-completion/narrowing functionality related strictly to org-roam.
- Deft provides dedicated buffer notes search/filtering
- Denote provides simple note creation with an efficient file-naming scheme
- Emacs-zettelkasten provides a basis for a zettelkasten type notetaking system
- Zk offers a dead-simple, feature-rich Zettelkasten implementation for Emacs
Thanks to Daniel Mendler for consult and advice about the consult-grep function,
the good work of Howard Melman, whose original notes function provided the initial
basis for this package, and both Protesilaos Stavrou and Bruce D’Arcus for helpful discussion and advice.

