Skip to content

Configuring node sequences

Martin Edström edited this page Jan 10, 2025 · 5 revisions

Here's a few ways to define a node sequence!

Remember to do M-x org-node-reset after evalling a new definition.

Convenience wrappers

Three high-level wrappers are shipped for now, examples follow.

  1. org-node-seq-def-on-any-sort-by-property
  2. org-node-seq-def-on-tags-sort-by-property
  3. org-node-seq-def-on-filepath-sort-by-basename
(setq org-node-seq-defs
      (list
       ;; All notes in creation order, 
       ;; according to the timestamps in their :CREATED: property.
       (org-node-seq-def-on-any-sort-by-property
        "a" "All notes by property :CREATED:" "CREATED")

       ;; Same as above, but only the nodes that have tag :pub:.
       (org-node-seq-def-on-tags-sort-by-property
        "w" "My publishable notes" "pub" "CREATED")

       ;; My day-notes, a.k.a. journal/diary.  Currently I still
       ;; structure them like org-roam-dailies expects: confined to a
       ;; subdirectory, with filenames such as "2024-11-18.org".
       ;; This is actually a sequence of files, not sequence of ID-nodes.
       (org-node-seq-def-on-filepath-sort-by-basename
        "d" "Dailies" "~/org/daily/" nil t)))

Manually

Old default setting

(setq org-node-seq-defs
  (list
   '("d" :name "Daily-files"
     :version 2
     :classifier (lambda (node)
                   (let ((path (org-node-get-file-path node)))
                     (when (string-search "/YOUR/DAILIES/" path)
                       (let ((ymd (org-node-seq-filename->ymd path)))
                         (when ymd
                           (cons ymd path))))))
     :whereami (lambda ()
                 (org-node-seq-filename->ymd buffer-file-name))
     :prompter (lambda (key)
                 (let ((org-node-seq-that-marks-calendar key))
                   (org-read-date)))
     :try-goto (lambda (item)
                 (org-node-seq-try-visit-file (cdr item)))
     :creator (lambda (sortstr key)
                (let ((org-node-datestamp-format "")
                      (org-node-ask-directory "/YOUR/DAILIES/"))
                  (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-properties 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 ((seq (cdr (assoc key org-node-seqs))))
                   (completing-read "Go to: " (plist-get seq :sorted-items))))
     :try-goto (lambda (item)
                 (when (org-node-seq-try-goto-id (cdr item))
                   t))
     :creator (lambda (sortstr key)
                (org-node-create sortstr (org-id-new) key))))

Amendment: custom titles

Even though my dailies are named "2024-09-26.org" I like the #+title: to say something custom like "2024-Sep-26".

To do that, amend the "d" series above, changing the :creator lambda into this.

:creator (lambda (sortstr key)
           (let ((org-node-datestamp-format "")
                 (org-node-slug-fn (lambda (&rest _) sortstr))
                 (org-node-ask-directory "/YOUR/DAILIES/"))
             (org-node-create (format-time-string
                               "%Y-%b-%d" ;; your custom format
                               (org-time-string-to-time sortstr))
                              (org-id-new)
                              key)))

Roam dailies (i.e. reuse some Roam internals)

Quick start for simple cases

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.

   '("r" :name "Dailies, using Roam internals"
     :version 2
     :classifier (lambda (node)
                   (if (and (require 'org-roam-dailies nil t)
                            (require 'org-node-fakeroam nil t))
                       (let ((path (org-node-get-file-path node)))
                         (when (string-search org-node-fakeroam-daily-dir path)
                           (let ((ymd (org-node-seq-filename->ymd path)))
                             (when ymd
                               (cons ymd path)))))
                     (error "Not installed: org-node-fakeroam")))
     :whereami (lambda ()
                 (org-node-seq-filename->ymd buffer-file-name))
     :prompter (lambda (key)
                 (let ((org-node-seq-that-marks-calendar key))
                   (org-read-date)))
     :try-goto (lambda (item)
                 (org-node-seq-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"))))

Rethinking

Interfacing with org-roam-dailies is possible, but you have to ask why. Get some idea of what it will bring you.

Let's recap the architecture of org-roam-dailies:

  1. Everything under a "daily/" dir is potentially a daily. Nothing outside can be.
  2. 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.
  3. 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".
  4. 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-fakeroam#tip-on-very-slow-filesystems.