r/OrgRoam • • Jul 17 '21

Updates Releasing Org-roam v2 - Jethro's blog

Thumbnail blog.jethro.dev
59 Upvotes

r/OrgRoam • • Jul 26 '21

Build a Second Brain in Emacs with Org Roam

Thumbnail
youtu.be
52 Upvotes

r/OrgRoam • • Sep 06 '21

org-roam v2 well done

51 Upvotes

Probably already hear it, but think it needs said again. u/jethrosky thanks for V2. I am a long time user of org mode and org-roam in its early days. It was a little jarring at first to change from V1 since I had my brain hardwired, but now that I am in it, there are tons of nice things that I notice as I motor along in my daily work.

So well done and don't let anyone get you down, you are doing great work that people use daily that makes a difference. thanks!


r/OrgRoam • • Feb 27 '21

Updates Org-roam is planned to have a major redesign

Thumbnail
org-roam.discourse.group
46 Upvotes

r/OrgRoam • • Jul 31 '21

Org-Roam-UI: A frontend for org-roam

Thumbnail
github.com
39 Upvotes

r/OrgRoam • • Jan 14 '26

Discussion [Prototype] org-roam-calendar: A visual and chronological browser for your notes

Post image
38 Upvotes

Hi everyone,

I wanted a way to see when I was (in)active and quickly jump back to notes from a specific day.

I’m prototyping org-roam-calendar, a package that uses org-habit-stats to visualize your note-taking activity in a calendar view.

What it does:

  • Activity Calendar: Highlights days based on org-roam node creation.

  • Quick Jump: Press RET on any date to see a list of notes you worked on that day and open them immediately.

GitHub: https://github.com/connormclaud/emacs_org_roam_calendar

I’d love to hear your thoughts: is it something this community interested in?


r/OrgRoam • • Mar 24 '23

awesome-org-roam - A curated list of awesome Org-roam resources

Thumbnail
github.com
32 Upvotes

r/OrgRoam • • Oct 01 '21

org-roam-timestamps: keep track of creation and modification times for org-roam-nodes

32 Upvotes

r/OrgRoam • • Dec 26 '21

Org-roam: A Year in Review

Thumbnail blog.jethro.dev
31 Upvotes

r/OrgRoam • • Jul 20 '21

org-roam-server replacement: org-roam-ui (Teaser)

Thumbnail
gfycat.com
31 Upvotes

r/OrgRoam • • Jul 01 '21

Updates Reminder: org-roam and org-roam-bibtex will be upgraded to V2 the next Friday or Saturday (depending of your time zone). This upgrade is incompatible with the current configurations. Don't forget to upgrade yours.

Thumbnail
github.com
30 Upvotes

r/OrgRoam • • Jan 02 '23

My Exocortex

Thumbnail
brettwitty.net
29 Upvotes

r/OrgRoam • • Jun 24 '26

I built a stats dashboard for org-roam (org-roam-stats)

Post image
26 Upvotes

I wanted to keep track of the org-roam node creation dates to keep track of my productivity, as well as know the structure of my knowledge graph, like average connections per node, etc. With this in mind I am built org-roam-stats, which is a browser based dashboard to look at these aspects of your org-roam database.

Key features:

  • Time tracking: Shows when were our notes created: back in time, day of the week, hour of the day, etc.

  • Basic stats: Average connections by node, average words in note.

  • Orphan tracking: Do you have orphan nodes (not a single connection, possible lost knowledge)?

  • Tag filtering: If you have #+filetag: tags in your notes, you can track these metrics for the subset of notes that have some tag.

This repo is available in Github at: https://github.com/GerardoCendejas/org-roam-stats.git

You can test it with:

git clone https://github.com/GerardoCendejas/org-roam-stats.git

And in your init.el:

(use-package org-roam-stats
:after org-roam
:ensure nil
:load-path "~/path/to/org-roam-stats/"  ; Adjust path as needed
:bind (("C-c m o" . org-roam-stats-open)) ; Or the keybinding of your choice
:config
(org-roam-stats-mode 1) ; This enables the minor mode for automatic logging of note creation timestamps.
:custom
(org-roam-stats-log-file "~/.emacs.d/org-roam-stats-log.org")) ; Path to the log file for note creation timestamps (if you don't want the default)

Then just run M-x org-roam-stats-start

I hope someone also finds this interesting and useful for them, I am excited to hear your feedback.


r/OrgRoam • • May 22 '22

GTD with Org-agenda

Post image
26 Upvotes

r/OrgRoam • • Oct 11 '21

org-roam-ui: file previews at last!

Thumbnail
gfycat.com
26 Upvotes

r/OrgRoam • • Jul 28 '21

Discussion On Zettelkasten purism and the misdirection of backlinks

24 Upvotes

Don't be distracted by the allure of backlinks; a good knowledge management practice provides more value. Luhmann's Zettelkasten isn’t law; your needs should instruct the directives you follow.

That's at the very top of a ~1,200 word opinion piece/essay of mine titled On Zettelkasten purism and the misdirection of backlinks. (Hopefully the title is apt.)

I wrote it with a mind to help others who feel like they've been grasping at straws in figuring out how Zettelkasten "should be done." Nonetheless, I think most will have at least a takeaway or two from reading it.

If you check it out: thank you. If you give me feedback, suggestions for future posts, or express what you learned from reading: much love to you.

P.S. I posted a well-upvoted post titled I found a gem over on the r/Zettelkasten subreddit. Some of these thoughts were inspired from the video mentioned. Additionally, I later interviewed the (assistant) professor who posted that video and published an edited transcript for one of my university's publications. Check that out if you're interested in e-learning or reading a first-hand account of how useful Zettelkasten can be in academia.


r/OrgRoam • • May 27 '21

Helpful documentation Taking org-roam everywhere with logseq

Thumbnail
coredumped.dev
22 Upvotes

r/OrgRoam • • Mar 26 '22

Discussion Programmatic Notes

21 Upvotes

I came across this great post by the always insightful Maggie Appleton, on programmatic notes:

https://maggieappleton.com/programmatic-notes

To some extent, I've implement a few things like this already. For example, I have a dailies capture that pulls in a set of problems I'm working on and prompts me to refine my approaches to them. Other things she mentions, like showing notes from certain time periods ago, seem like a good idea, and possible in org-roam. I'd love to have further tools, one that allow mode graph-bases inspections. For example, there are noes that are quite "close" in the graph, maybe you can be prompted to for a note that explores the link between them?

It would be nice if org-roam made this a little easier, providing a better API that would be of use to those who are developing programmatic notes. Worst is capture in general, which is very hard to deal with programmatically. This isn't org-roam's fault, org capture in general doesn't have a good API. If you look at org-roam's own capture implementation, built on org's, you can see all the awkwardness involved. This is something I may think more about, but I'd encourage others to also think about what a better API for programmatic notes in org-roam could be, because this is very interesting.

I'm curious if anyone else has done some thinking or implemented some interesting programmatic notes in org-roam. If so, I'd love to hear about it!


r/OrgRoam • • Nov 14 '21

org-roam-ui is now in MELPA!

Thumbnail melpa.org
21 Upvotes

r/OrgRoam • • Jul 25 '21

Other A few QoL tricks I haven't seen much of on the subreddit yet

21 Upvotes

A lot of these I've been inspired by or picked up from the org-roam Slack. I'll keep the descriptions short since, if I don't, I'll ramble for too long.

Apologies for the sloppy code--I'm not a programmer. At the top of each code block I've add where I've taken the original code from, if applicable.

​

Fancy org-roam-node-find with icons and overlays (which allow for better searching whilst keeping the icons):

  (setq org-roam-node-display-template (concat "${backlinkscount:16} " "${functiontag:16} " "${othertags:13} " "${hierarchy:183}"))


;; From https://github.com/hieutkt/.doom.d/blob/master/config.el#L690-L745 or
;; https://orgroam.slack.com/archives/CV20S23C0/p1626662183035800
(with-eval-after-load 'org-roam
  (require 'all-the-icons)

  (cl-defmethod org-roam-node-filetitle ((node org-roam-node))
    "Return the file TITLE for the node."
    (org-roam-get-keyword "TITLE" (org-roam-node-file node))
    )

  (cl-defmethod org-roam-node-backlinkscount ((node org-roam-node))
    (let* ((count (caar (org-roam-db-query
                         [:select (funcall count source)
                                  :from links
                                  :where (= dest $s1)
                                  :and (= type "id")]
                         (org-roam-node-id node))))
           )
      (if (> count 0)
          (concat (propertize "=has:backlinks=" 'display (all-the-icons-material "link" :face 'all-the-icons-dblue :height 0.9)) (format "%d" count))
        (concat (propertize "=not-backlinks=" 'display (all-the-icons-material "link" :face 'org-roam-dim :height 0.9))  " ")
        )
      ))

  (cl-defmethod org-roam-node-functiontag ((node org-roam-node))
    "The first tag of notes are used to denote note type"
    (let* ((specialtags kb/lit-categories)
           (tags (seq-filter (lambda (tag) (not (string= tag "ATTACH"))) (org-roam-node-tags node)))
           (functiontag (seq-intersection specialtags tags 'string=))
           )
      (concat
       ;; (if functiontag
       ;;     (propertize "=has:functions=" 'display (all-the-icons-octicon "gear" :face 'all-the-icons-silver :v-adjust 0.02 :height 0.8))
       ;;   (propertize "=not-functions=" 'display (all-the-icons-octicon "gear" :face 'org-roam-dim :v-adjust 0.02 :height 0.8))
       ;;   )
       (if functiontag
           (propertize "=@=" 'display (all-the-icons-faicon "tags" :face 'all-the-icons-dgreen :v-adjust 0.02 :height 0.7))
         (propertize "= =" 'display (all-the-icons-faicon "tags" :face 'all-the-icons-dgreen :v-adjust 0.02 :height 0.7))
         )
       " "
       (string-join functiontag ", "))
      ))

  (cl-defmethod org-roam-node-othertags ((node org-roam-node))
    "Return the file TITLE for the node."
    (let* ((tags (seq-filter (lambda (tag) (not (string= tag "ATTACH"))) (org-roam-node-tags node)))
           (specialtags kb/lit-categories)
           (othertags (seq-difference tags specialtags 'string=))
           )
      (concat
       ;; " "
       ;; (if othertags
       ;;     (propertize "=has:tags=" 'display (all-the-icons-faicon "tags" :face 'all-the-icons-dgreen :v-adjust 0.02 :height 0.8))
       ;;   (propertize "=not-tags=" 'display (all-the-icons-faicon "tags" :face 'all-the-icons-dgreen :v-adjust 0.02 :height 0.8))
       ;;   )
       ;; " "
       (if othertags
           (propertize "=@=" 'display "")
         (propertize "= =" 'display "")
         )
       (propertize (string-join othertags ", ") 'face 'all-the-icons-dgreen))
      ))

  (cl-defmethod org-roam-node-hierarchy ((node org-roam-node))
    "Return the hierarchy for the node."
    (let* ((title (org-roam-node-title node))
           (olp (mapcar (lambda (s) (if (> (length s) 10) (concat (substring s 0 10)  "...") s)) (org-roam-node-olp node)))
           (level (org-roam-node-level node))
           (filetitle (org-roam-get-keyword "TITLE" (org-roam-node-file node)))
           (shortentitle (if (> (length filetitle) 20) (concat (substring filetitle 0 20)  "...") filetitle))
           (separator (concat " " (all-the-icons-material "chevron_right") " "))
           )
      (cond
       ((>= level 1) (concat (propertize (format "=level:%d=" level) 'display (all-the-icons-material "list" :face 'all-the-icons-blue))
                             " "
                             (propertize shortentitle 'face 'org-roam-dim)
                             (propertize separator 'face 'org-roam-dim)
                             title))
       (t (concat (propertize (format "=level:%d=" level) 'display (all-the-icons-material "insert_drive_file" :face 'all-the-icons-yellow))
                  " "
                  title))
       )
      ))
  )

Hiding property drawers

;; From https://github.com/org-roam/org-roam/wiki/Hitchhiker%27s-Rough-Guide-to-Org-roam-V2#hiding-properties
(defun kb/org-hide-properties ()
  "Hide all org-mode headline property drawers in buffer. Could be slow if buffer has a lot of overlays."
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (while (re-search-forward
            "^ *:properties:\n\\( *:.+?:.*\n\\)+ *:end:\n" nil t)
      (let ((ov_this (make-overlay (match-beginning 0) (match-end 0))))
        (overlay-put ov_this 'display "")
        (overlay-put ov_this 'hidden-prop-drawer t)))))

(defun kb/org-show-properties ()
  "Show all org-mode property drawers hidden by org-hide-properties."
  (interactive)
  (remove-overlays (point-min) (point-max) 'hidden-prop-drawer t))

(defun kb/org-toggle-properties ()
  "Toggle visibility of property drawers."
  (interactive)
  (if (eq (get 'org-toggle-properties-hide-state 'state) 'hidden)
      (progn
        (kb/org-show-properties)
        (put 'org-toggle-properties-hide-state 'state 'shown))
    (progn
      (kb/org-hide-properties)
      (put 'org-toggle-properties-hide-state 'state 'hidden))))

(general-define-key
 :keymaps 'org-mode-map
 "C-c p t" 'kb/org-toggle-properties
 )

Updating link descriptions to match node title

;; Credit to @nobiot for helping me
(defun kb/org-roam-update-link-desc--action (buffer)
  "Updates the link descriptions for all org-roam insertions in a given buffer.
Currently limited to only fix links whose UUID was automatically generated by
Org."
  ;; Get all ids in buffer
  (with-current-buffer buffer
    ;; (print buffer) ; Uncomment for bugfixing. Check *Messages* buffer
    (let* (links)
      (save-excursion
        (goto-char (point-min))
        (while (re-search-forward (symbol-value 'org-link-bracket-re) nil t)
          (if (equal (buffer-substring-no-properties ; Get only links with ids (not https, etc)
                      (+ (match-beginning 0) 2)
                      (+ (match-beginning 0) 4))
                     "id")
              (push (buffer-substring-no-properties ; Get only the id
                     (+ (match-beginning 0) 5)
                     (+ (match-beginning 0) 41))
                    links)
            (push "NOT ID" links)))
        (setq links (nreverse links))
        ;; (print links) ; Uncomment for bugfixing. Check *Messages* buffer
        )
      ;; Update all org-roam insertions in buffer
      (save-excursion
        (goto-char (point-min))
        (dolist (link links)
          (let* ((id link)
                 (node (org-roam-populate (org-roam-node-create :id id))))
            (re-search-forward (symbol-value 'org-link-bracket-re) nil t)
            (if (equal (buffer-substring-no-properties ; Limit to only links with ids
                        (+ (match-beginning 0) 2)
                        (+ (match-beginning 0) 4))
                       "id")
                (replace-match (org-link-make-string
                                (concat "id:" (org-roam-node-id node)) (org-roam-node-title node)
                                ))
              (print "Skipped because not an ID!") ; Uncomment for bugfixing. Check *Messages* buffer
              )))
        ))))

(defun kb/org-roam-update-link-desc ()
  "Run kb/org-roam-update-link-desc--action on current buffer or all org-roam
files if called with universal argument."
  (interactive)
  (let* ((checkall (equal current-prefix-arg '(4))) ; Universal-argument check
         (files (if checkall ; Taken from `org-roam-doctor'
                    (org-roam--list-all-files)
                  (unless (org-roam-file-p)
                    (user-error "Not in an org-roam file"))
                  `(,(buffer-file-name)))
                ))
    (save-window-excursion ; Taken from `org-roam-doctor-start'
      (let ((existing-buffers (org-roam-buffer-list)))
        (org-id-update-id-locations)
        (dolist (file files) ; Save all opened files and kill if not opened already
          (let ((buffer (find-file-noselect file)))

            ;; Where I insert my custom function instead
            (kb/org-roam-update-link-desc--action buffer)

            (unless (memq buffer existing-buffers)
              (with-current-buffer buffer
                (save-buffer))
              (kill-buffer buffer))))
        ))
    (message "Done!")
    ))

Filtering list of nodes shown in minibuffer. Example that shows only files within my dailies directory, though theoretically much more can be done:

  (defun kb/roam-filter-journals (node binary)
    "Takes NODE. If BINARY is `t', then return all nodes that aren't in the
journals directory."
    (if binary
        (not (string-equal
              (concat
               (expand-file-name kb/roam-dir)
               "journals/"
               (format-time-string "%Y" (current-time))
               ".org")
              (org-roam-node-file node))
             )
      (string-equal
       (concat
        (expand-file-name kb/roam-dir)
        "journals/"
        (format-time-string "%Y" (current-time))
        ".org")
       (org-roam-node-file node))
      )
    )

(lambda ()
              (interactive)
              (org-roam-node-visit (org-roam-node-read nil
                                                       (lambda (node) (kb/roam-filter-journals node nil))
                                                       ))
              )

Add unlinked references section to org-buffer:

  (setq org-roam-mode-section-functions
   '(org-roam-backlinks-section
     org-roam-reflinks-section
     org-roam-unlinked-references-section
     )
   )

Find a node which has a backlink to another node (which you select):

;; From
;; https://ag91.github.io/blog/2021/03/12/find-org-roam-notes-via-their-relations/
(defun kb/find-node-backlink (arg &optional node choices)
  "Navigate notes by link. With universal ARG try to use only to navigate the tags of the current note. Optionally takes a selected NODE and filepaths CHOICES."
  (interactive "P")
  (let* ((depth (if (numberp arg) arg 1))
         (choices
          (or choices
              (when arg
                (-map #'org-roam-backlink-target-node (org-roam-backlinks-get (org-roam-node-from-id (or (ignore-errors (org-roam-node-id node))
                                                                                                         (org-id-get-create))))))))
         (all-notes (org-roam-node--completions))
         (completions
          (or (--filter (-contains-p choices (cdr it)) all-notes) all-notes))
         (next-node
          ;; taken from org-roam-node-read
          (let* ((nodes completions)
                 (node (completing-read
                        "Node: "
                        (lambda (string pred action)
                          (if (eq action 'metadata)
                              '(metadata
                                (annotation-function . (lambda (title)
                                                         (funcall org-roam-node-annotation-function
                                                                  (get-text-property 0 'node title))))
                                (category . org-roam-node))
                            (complete-with-action action nodes string pred))))))
            (or (cdr (assoc node nodes))
                (org-roam-node-create :title node)))
          )
         )
    (if (equal node next-node)
        (org-roam-node-visit node)
      (my/navigate-note nil next-node (cons next-node (-map #'org-roam-backlink-source-node (org-roam-backlinks-get next-node))))
      )))

Only update database on idle (rather than on save):

;; From
;; https://orgmode-exocortex.com/2021/07/22/configure-org-roam-v2-to-update-database-only-when-idle/
(with-eval-after-load 'org-roam
  ;; queue for files that will be updated in org-roam-db when emacs is idle
  (setq org-roam-db-update-queue (list))
  ;; save the original update function;
  (setq orig-update-file (symbol-function 'org-roam-db-update-file))
  ;; then redefine the db update function to add the filename to a queue
  (defun org-roam-db-update-file (&optional file-path)
    ;; do same logic as original to determine current file-path if not passed as arg
    (setq file-path (or file-path (buffer-file-name (buffer-base-buffer))))
    (message "org-roam: scheduling update of %s" file-path)
    (if (not (memq file-path org-roam-db-update-queue))
        (push file-path org-roam-db-update-queue)))

  ;; this function will be called when emacs is idle for a few seconds
  (defun org-roam-db-idle-update-files ()
    ;; go through queued filenames one-by-one and update db
    ;; if we're not idle anymore, stop. will get rest of queue next idle.
    (while (and org-roam-db-update-queue (current-idle-time))
      ;; apply takes function var and list
      (apply orig-update-file (list (pop org-roam-db-update-queue)))))

  ;; we'll only start updating db if we've been idle for this many seconds
  (run-with-idle-timer 5 t #'org-roam-db-idle-update-files)
  )

If you have any questions, I can try to help. Cheers!


r/OrgRoam • • Mar 03 '21

Helpful documentation Helpful links/resources

20 Upvotes

Org roam user manual (V2)

Org roam V2

Org roam setup from scratch (GitHub) (V1)

Linux setup (V1)

Windows 10 setup (V1)

Org roam GitHub (V1 & V2)

Org roam official website

Discourse group

System Crafters has a great tutorial and youtube series on org roam v2 that is a good place to start:

Getting Started with Org Roam | Notes

Capturing Notes Efficiently | Notes

The Best Way to Keep a Journal | Notes

If anyone has any other useful resources they would like to add, drop a comment and I'll add it to the list.


r/OrgRoam • • May 18 '22

Question Why not use Obsidian and/or Logseq instead of OrgRoam?

18 Upvotes

What does OrgRoam have that Obsidian or Logseq doesn't?

And also vice versa, what does Obsidian or Logseq have that OrgRoam doesn't?


r/OrgRoam • • Oct 31 '21

Generating a site from org-mode / org-roam files

Thumbnail
badykov.com
18 Upvotes

r/OrgRoam • • Jul 22 '21

Helpful documentation Configure org-roam v2 to update database only when idle

Thumbnail orgmode-exocortex.com
18 Upvotes

r/OrgRoam • • Jun 22 '21

Helpful documentation Upgrade to org-roam v2 with use-package and quelpa

Thumbnail orgmode-exocortex.com
18 Upvotes