-
Notifications
You must be signed in to change notification settings - Fork 5
Configuring series
Here's a few premade series definitions.
They are examples only; the idea is that you override them completely, not use add-to-list
or the like.
After evalling a new definition, remember to type M-x org-node-reset RET
.
(setq org-node-series-defs
(list
'("d" :name "Daily-files"
:version 2
:classifier (lambda (node)
(let ((path (org-node-get-file-path node)))
(when (string-search (org-node--guess-daily-dir) path)
(let ((ymd (org-node-helper-filename->ymd path)))
(when ymd
(cons ymd path))))))
:whereami (lambda ()
(org-node-helper-filename->ymd buffer-file-name))
:prompter (lambda (key)
(let ((org-node-series-that-marks-calendar key))
(org-read-date)))
:try-goto (lambda (item)
(org-node-helper-try-visit-file (cdr item)))
:creator (lambda (sortstr key)
(let ((org-node-datestamp-format "")
(org-node-ask-directory (org-node--guess-daily-dir)))
(org-node-create sortstr (org-id-new) key))))
;; Obviously, this series works best if you have `org-node-put-created' on
;; `org-node-creation-hook'.
'("a" :name "All ID-nodes by property :CREATED:"
:version 2
:capture "n"
:classifier (lambda (node)
(let ((time (cdr (assoc "CREATED" (org-node-get-props node)))))
(when (and time (not (string-blank-p time)))
(cons time (org-node-get-id node)))))
:whereami (lambda ()
(let ((time (org-entry-get nil "CREATED" t)))
(and time (not (string-blank-p time)) time)))
:prompter (lambda (key)
(let ((series (cdr (assoc key org-node--series))))
(completing-read "Go to: " (plist-get series :sorted-items))))
:try-goto (lambda (item)
(when (org-node-helper-try-goto-id (cdr item))
t))
:creator (lambda (sortstr key)
(org-node-create sortstr (org-id-new) key))))
For the "d" series above, change the :creator to:
:creator (lambda (sortstr key)
(let ((org-node-datestamp-format "")
(org-node-slug-fn (lambda (&rest _) sortstr))
(org-node-ask-directory (org-node--guess-daily-dir)))
(org-node-create (format-time-string
"%Y-%b-%d" ;; your custom format
(org-time-string-to-time sortstr))
(org-id-new)
key)))
'("f" :name "All files by file-name datestamp"
:version 2
:capture "n"
:classifier (lambda (node)
(let ((path (org-node-get-file-path node)))
(when (org-node-extract-file-name-datestamp path)
(cons (file-name-nondirectory path) path))))
:whereami (lambda ()
(when (org-node-extract-file-name-datestamp buffer-file-name)
(cons (file-name-nondirectory buffer-file-name)
buffer-file-name)))
:prompter (lambda (key)
(let ((series (cdr (assoc key org-node--series))))
(completing-read "Go to: " (plist-get series :sorted-items))))
:try-goto (lambda (item)
(org-node-helper-try-goto-id (cdr item)))
:creator (lambda (sortstr key)
(org-node-create sortstr (org-id-new) key)))
If you always had just one daily capture template, then this definition should work as a drop-in.
It is not perfect, e.g. the :capture
key cannot be useful, but it will use your actual org-roam-dailies-capture-templates
to create new nodes, giving you time to port your way of doing things.
'("d" :name "Dailies, using Roam internals"
:version 2
:classifier (lambda (node)
(if (boundp 'org-roam-dailies-directory)
(let ((path (org-node-get-file-path node)))
(when (string-search org-roam-dailies-directory path)
(let ((ymd (org-node-helper-filename->ymd path)))
(when ymd
(cons ymd path)))))
(error "Not installed: org-roam")))
:whereami (lambda ()
(org-node-helper-filename->ymd buffer-file-name))
:prompter (lambda (key)
(let ((org-node-series-that-marks-calendar key))
(org-read-date)))
:try-goto (lambda (item)
(org-node-helper-try-visit-file (cdr item)))
:creator (lambda (sortstr key)
(if (fboundp 'org-node-fakeroam-daily-create)
(org-node-fakeroam-daily-create sortstr key t)
(error "Not installed: org-node-fakeroam"))))
Interfacing with org-roam-dailies is possible, but it's a bit odd to do so and you have to ask why. Get some idea of what it will bring you.
Let's recap the architecture of org-roam-dailies:
- Everything under a "daily/" dir is potentially a daily. Nothing outside can be.
- A daily is both created or navigated-to using the corresponding capture template.
- If you have just a single capture template, then several commands actually autoselect that one.
- You can have multiple files for the same day, so long as they are created using different capture templates, which place them in different sub-directories. Like, you could have a file "./daily/work/2024-04-15.org" as well as a file "./daily/self-reviews/2024-04-15.org".
- How the items are ordered in sequence is a matter of how the filenames sort. So there is no possibility of nesting them in a datetree file. (correct me on this)
If you like all of that, just stay with org-roam-dailies. If it's slow, see https://github.com/meedstrom/org-node#tip-on-very-slow-filesystems.
We do not ship built-in commands for the equivalents of "goto today", "goto next" or "goto previous". The series dispatch is the only command.
Here are some commands that hardcode a specific series keyed on "d".
(defun my-goto-date ()
(interactive)
(org-node--series-jump "d"))
(defun my-goto-today ()
(interactive)
(let* ((series (cdr (assoc "d" org-node--series)))
(item (assoc (format-time-string "%F")
(plist-get series :sorted-items))))
(when (or (null item)
(not (funcall (plist-get series :try-goto) item)))
(funcall (plist-get series :creator)
(format-time-string "%F")
(plist-get series :key)))))
(defun my-goto-next-day ()
(interactive nil org-mode)
(org-node--series-goto-next "d"))
(defun my-goto-prev-day ()
(interactive nil org-mode)
(org-node--series-goto-previous "d"))