Merge pull request #5271 from Wetlize/add-roam2

lang/org: Add `+roam2` flag for org-roam v2
This commit is contained in:
Henrik Lissner 2021-07-25 04:13:03 -04:00 committed by GitHub
commit 4ac5332a1d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 356 additions and 9 deletions

View file

@ -199,7 +199,31 @@
:desc "Arbitrary date" "d" #'org-roam-dailies-find-date :desc "Arbitrary date" "d" #'org-roam-dailies-find-date
:desc "Today" "t" #'org-roam-dailies-find-today :desc "Today" "t" #'org-roam-dailies-find-today
:desc "Tomorrow" "m" #'org-roam-dailies-find-tomorrow :desc "Tomorrow" "m" #'org-roam-dailies-find-tomorrow
:desc "Yesterday" "y" #'org-roam-dailies-find-yesterday)))) :desc "Yesterday" "y" #'org-roam-dailies-find-yesterday)))
(:when (featurep! :lang org +roam2)
(:prefix ("r" . "roam")
:desc "Open random node" "a" #'org-roam-node-random
:desc "Find node" "f" #'org-roam-node-find
:desc "Find ref" "F" #'org-roam-ref-find
:desc "Show graph" "g" #'org-roam-graph
:desc "Insert node" "i" #'org-roam-node-insert
:desc "Capture to node" "n" #'org-roam-capture
:desc "Toggle roam buffer" "r" #'org-roam-buffer-toggle
:desc "Launch roam buffer" "R" #'org-roam-buffer-display-dedicated
:desc "Sync database" "s" #'org-roam-db-sync
(:prefix ("d" . "by date")
:desc "Goto previous note" "b" #'org-roam-dailies-goto-previous-note
:desc "Goto date" "d" #'org-roam-dailies-goto-date
:desc "Capture date" "D" #'org-roam-dailies-capture-date
:desc "Goto next note" "f" #'org-roam-dailies-goto-next-note
:desc "Goto tomorrow" "m" #'org-roam-dailies-goto-tomorrow
:desc "Capture tomorrow" "M" #'org-roam-dailies-capture-tomorrow
:desc "Capture today" "n" #'org-roam-dailies-capture-today
:desc "Goto today" "t" #'org-roam-dailies-goto-today
:desc "Capture today" "T" #'org-roam-dailies-capture-today
:desc "Goto yesterday" "y" #'org-roam-dailies-goto-yesterday
:desc "Capture yesterday" "Y" #'org-roam-dailies-capture-yesterday
:desc "Find directory" "-" #'org-roam-dailies-find-directory))))
;;; <leader> o --- open ;;; <leader> o --- open
"o" nil ; we need to unbind it first as Org claims this prefix "o" nil ; we need to unbind it first as Org claims this prefix

View file

@ -555,6 +555,31 @@
:desc "Tomorrow" "m" #'org-roam-dailies-find-tomorrow :desc "Tomorrow" "m" #'org-roam-dailies-find-tomorrow
:desc "Yesterday" "y" #'org-roam-dailies-find-yesterday))) :desc "Yesterday" "y" #'org-roam-dailies-find-yesterday)))
(:when (featurep! :lang org +roam2)
(:prefix ("r" . "roam")
:desc "Open random node" "a" #'org-roam-node-random
:desc "Find node" "f" #'org-roam-node-find
:desc "Find ref" "F" #'org-roam-ref-find
:desc "Show graph" "g" #'org-roam-graph
:desc "Insert node" "i" #'org-roam-node-insert
:desc "Capture to node" "n" #'org-roam-capture
:desc "Toggle roam buffer" "r" #'org-roam-buffer-toggle
:desc "Launch roam buffer" "R" #'org-roam-buffer-display-dedicated
:desc "Sync database" "s" #'org-roam-db-sync
(:prefix ("d" . "by date")
:desc "Goto previous note" "b" #'org-roam-dailies-goto-previous-note
:desc "Goto date" "d" #'org-roam-dailies-goto-date
:desc "Capture date" "D" #'org-roam-dailies-capture-date
:desc "Goto next note" "f" #'org-roam-dailies-goto-next-note
:desc "Goto tomorrow" "m" #'org-roam-dailies-goto-tomorrow
:desc "Capture tomorrow" "M" #'org-roam-dailies-capture-tomorrow
:desc "Capture today" "n" #'org-roam-dailies-capture-today
:desc "Goto today" "t" #'org-roam-dailies-goto-today
:desc "Capture today" "T" #'org-roam-dailies-capture-today
:desc "Goto yesterday" "y" #'org-roam-dailies-goto-yesterday
:desc "Capture yesterday" "Y" #'org-roam-dailies-capture-yesterday
:desc "Find directory" "-" #'org-roam-dailies-find-directory)))
(:when (featurep! :lang org +journal) (:when (featurep! :lang org +journal)
(:prefix ("j" . "journal") (:prefix ("j" . "journal")
:desc "New Entry" "j" #'org-journal-new-entry :desc "New Entry" "j" #'org-journal-new-entry

View file

@ -19,6 +19,10 @@
- [[#configuration][Configuration]] - [[#configuration][Configuration]]
- [[#changing-org-directory][Changing ~org-directory~]] - [[#changing-org-directory][Changing ~org-directory~]]
- [[#changing-org-noter-notes-search-path][Changing ~org-noter-notes-search-path~]] - [[#changing-org-noter-notes-search-path][Changing ~org-noter-notes-search-path~]]
- [[#troubleshooting][Troubleshooting]]
- [[#org-roam][=org-roam=]]
- [[#should-i-go-with-roam-v1-or-roam2-v2][Should I go with =+roam= (v1) or =+roam2= (v2)?]]
- [[#migrating-your-existing-files-from-v1-roam-to-v2-roam2][Migrating your existing files from v1 (=+roam=) to v2 (=+roam2=)]]
* Description * Description
This module adds org-mode support to Doom Emacs, along with a number of This module adds org-mode support to Doom Emacs, along with a number of
@ -73,8 +77,10 @@ https://www.mfoot.com/blog/2015/11/22/literate-emacs-configuration-with-org-mode
+ =+pretty= Enables pretty unicode symbols for bullets and priorities, and + =+pretty= Enables pretty unicode symbols for bullets and priorities, and
better syntax highlighting for latex. Keep in mind: this can be expensive. If better syntax highlighting for latex. Keep in mind: this can be expensive. If
org becomes too slow, it'd be wise to disable this flag. org becomes too slow, it'd be wise to disable this flag.
+ =+roam= Enables org-roam integration. This requires ~sqlite3~ to be installed + =+roam= Enables integration with [[https://github.com/org-roam/org-roam-v1][org-roam v1]]. This requires ~sqlite3~ to be
on your system. installed on your system. Incompatible with =+roam2=.
+ =+roam2= Enables integration with [[https://github.com/org-roam/org-roam][org-roam v2]]. This requires ~sqlite3~ to be
installed on your system. Incompatible with =+roam=.
** Plugins ** Plugins
+ [[https://github.com/hniksic/emacs-htmlize][htmlize]] + [[https://github.com/hniksic/emacs-htmlize][htmlize]]
@ -128,7 +134,9 @@ https://www.mfoot.com/blog/2015/11/22/literate-emacs-configuration-with-org-mode
+ [[https://github.com/integral-dw/org-superstar-mode][org-superstar]] + [[https://github.com/integral-dw/org-superstar-mode][org-superstar]]
+ [[https://github.com/harrybournis/org-fancy-priorities][org-fancy-priorities]] + [[https://github.com/harrybournis/org-fancy-priorities][org-fancy-priorities]]
+ =+roam= + =+roam=
+ [[https://github.com/org-roam/org-roam][org-roam]] + [[https://github.com/org-roam/org-roam-v1][org-roam]] (v1)
+ =+roam2=
- [[https://github.com/org-roam/org-roam/tree/v2][org-roam]] (v2)
+ =+noter= + =+noter=
+ [[https://github.com/weirdNox/org-noter][org-noter]] + [[https://github.com/weirdNox/org-noter][org-noter]]
@ -180,7 +188,7 @@ esoteric features:
its dependencies are met, e.g. install the =ruby= executable for ruby support. its dependencies are met, e.g. install the =ruby= executable for ruby support.
To use ~jupyter kernels~ you need the =+jupyter= flag, the associated kernel as To use ~jupyter kernels~ you need the =+jupyter= flag, the associated kernel as
well as the ~jupyter~ program. well as the ~jupyter~ program.
+ =org-roam= (with the =+roam= flag) requires =sqlite3= to be installed. + =org-roam= (with =+roam= or =+roam2= flag) requires =sqlite3= to be installed.
** MacOS ** MacOS
#+BEGIN_SRC sh #+BEGIN_SRC sh
@ -253,3 +261,44 @@ To modify ~org-noter-notes-search-path~ set:
;; ~/.doom.d/config.el ;; ~/.doom.d/config.el
(setq org-noter-notes-search-path '("~/notes/path/")) (setq org-noter-notes-search-path '("~/notes/path/"))
#+END_SRC #+END_SRC
* Troubleshooting
** =org-roam=
*** Should I go with =+roam= (v1) or =+roam2= (v2)?
Long story short: if you're new to =org-roam= and haven't used it, then you
should go with =+roam2=; if you already have an ~org-roam-directory~ with the v1
files in it, then you can keep use =+roam= for a time being.
V1 isn't actively maintained anymore and is now basically EOL. This means that
the feature disparity between the both will continue to grow, while its existing
bugs and problems won't be addressed, at least by the main maintainers. V2 can
be considered as a complete rewrite of the package so it comes with a lot of
breaking changes.
While v1 won't be actively maintained anymore, it still will be available in
Doom for a while, at least until there will be a reliable tool that will migrate
your data from v1 to v2.
To learn more about v2 you can use the next resources:
- [[https://github.com/org-roam/org-roam/blob/master/doc/org-roam.org][Org-roam v2 Official Manual]]
- [[https://github.com/org-roam/org-roam/wiki/Hitchhiker's-Rough-Guide-to-Org-roam-V2][Hitchhiker's Rough Guide to Org roam V2]]
- [[https://blog.jethro.dev/posts/org_roam_v2/][Releasing Org-roam v2 - Jethro Kuan's blog]]
- [[https://org-roam.discourse.group/t/org-roam-major-redesign/1198][Thread about the redesign from Org-Roam Discourse]]
*** Migrating your existing files from v1 (=+roam=) to v2 (=+roam2=)
V2 comes with a migration wizard for v1 users. It's new, which means issues can
appear during the migration process. Because of that, *don't forget to backup*
your ~org-roam-directory~ before attempting to migrate.
In order to migrate from v1 to v2 using Doom follow the next steps:
1. Enable =+roam2= flag (and disable =+roam= if it was previously enabled) in
your =init.el=.
2. Ensure your ~org-roam-directory~ points to a directory with your v1 files.
3. Run =doom sync -u= in your shell.
4. Restart Emacs (if it was previously opened) and run ~org-roam-migrate-wizard~
command (=M-x org-roam-migrate-wizard RET=). The wizard will automatically
attempt to backup your previous ~org-roam-directory~ to =org-roam.bak=, but
just in case backup it yourself too.
4. After the wizard is done you should be good to go. Verify the integrity of
your data and whether it did everything as expected. In case of failure
[[https://github.com/org-roam/org-roam/issues][report]] your issue.

View file

@ -0,0 +1,58 @@
;;; lang/org/autoload/contrib-roam2.el -*- lexical-binding: t; -*-
;;;###if (featurep! +roam2)
;;; Custom node accessors
;;;###autoload (autoload 'org-roam-node-doom-filetitle "lang/org/autoload/contrib-roam2" nil t)
(cl-defmethod org-roam-node-doom-filetitle ((node org-roam-node))
"Return the value of \"#+title:\" (if any) from file that NODE resides in.
If there's no file-level title in the file, return empty string."
(or (if (= (org-roam-node-level node) 0)
(org-roam-node-title node)
(org-roam-get-keyword "TITLE" (org-roam-node-file node)))
""))
;;;###autoload (autoload 'org-roam-node-doom-hierarchy "lang/org/autoload/contrib-roam2" nil t)
(cl-defmethod org-roam-node-doom-hierarchy ((node org-roam-node))
"Return hierarchy for NODE, constructed of its file title, OLP and direct title.
If some elements are missing, they will be stripped out."
(let ((title (org-roam-node-title node))
(olp (org-roam-node-olp node))
(level (org-roam-node-level node))
(filetitle (org-roam-node-doom-filetitle node))
(separator (propertize " > " 'face 'shadow)))
(cl-case level
;; node is a top-level file
(0 filetitle)
;; node is a level 1 heading
(1 (concat (propertize filetitle 'face '(shadow italic))
separator title))
;; node is a heading with an arbitrary outline path
(t (concat (propertize filetitle 'face '(shadow italic))
separator (propertize (string-join olp " > ") 'face '(shadow italic))
separator title)))))
;;;###autoload (autoload 'org-roam-node-doom-subdirs "lang/org/autoload/contrib-roam2" nil t)
(cl-defmethod org-roam-node-doom-subdirs ((node org-roam-node))
"Return subdirectories of `org-roam-directory' in which NODE resides in.
If there's none, return an empty string."
(if-let ((dirs (thread-first node
(org-roam-node-file)
(file-relative-name org-roam-directory)
(file-name-directory))))
dirs
""))
;;;###autoload (autoload 'org-roam-node-doom-tags "lang/org/autoload/contrib-roam2" nil t)
(cl-defmethod org-roam-node-doom-tags ((node org-roam-node))
"Return tags formatted in the same way how they appear in org files.
Treat subdirectories as tags too. If there's no elements to build
the tags of, return an empty string."
(let ((tags (org-roam-node-tags node))
(subdirs (org-roam-node-doom-subdirs node)))
(when tags
(setq tags (propertize (concat (mapconcat (lambda (s) (concat ":" s)) tags nil) ":")
'face 'shadow)))
(unless (string-empty-p subdirs)
(setq subdirs (propertize (concat ":" (replace-regexp-in-string "/\\|\\\\" ":" subdirs))
'face '(shadow italic))))
(replace-regexp-in-string ":+" (propertize ":" 'face 'shadow) (concat subdirs tags))))

View file

@ -732,7 +732,7 @@ between the two."
"f" #'org-footnote-new "f" #'org-footnote-new
"h" #'org-toggle-heading "h" #'org-toggle-heading
"i" #'org-toggle-item "i" #'org-toggle-item
"I" #'org-toggle-inline-images "I" #'org-id-get-create
"n" #'org-store-link "n" #'org-store-link
"o" #'org-set-property "o" #'org-set-property
"q" #'org-set-tags-command "q" #'org-set-tags-command

View file

@ -0,0 +1,184 @@
;;; lang/org/contrib/roam2.el -*- lexical-binding: t; -*-
;;;###if (featurep! +roam2)
(defvar +org-roam-open-buffer-on-find-file t
"If non-nil, open the org-roam buffer when opening an org roam file.")
(defvar +org-roam-link-to-org-use-id 'create-if-interactive
"`org-roam-directory' local value for `org-id-link-to-org-use-id'.
It's not recommended to set this to nil in order for other parts
of org-mode to properly utilize ID links.")
;;
;;; Packages
(use-package! org-roam
:hook (org-load . +org-init-roam-h)
:preface
;; Set this to nil so we can later detect if the user has set custom values
;; for these variables. If not, default values will be set in the :config
;; section.
(defvar org-roam-directory nil)
(defvar org-roam-db-location nil)
:init
(doom-load-packages-incrementally
'(ansi-color dash f rx seq magit-section emacsql emacsql-sqlite))
;; Don't display warning message dedicated for v1 users. Need to be set early.
(setq org-roam-v2-ack t)
(defadvice! +org-roam-suppress-sqlite-build-a (orig-fn &rest args)
"Suppress automatic building of sqlite3 binary when loading `org-roam'.
This is a blocking operation that can take a while to complete
and better be deferred when there will be an actual demand for
the database. See `+org-init-roam-h' for the launch process."
:around #'emacsql-sqlite-ensure-binary
(if (not (boundp 'org-roam-db-version))
(apply orig-fn args)
(advice-remove #'emacsql-sqlite-ensure-binary #'+org-roam-suppress-sqlite-build-a)
nil))
:config
(defun +org-init-roam-h ()
"Setup `org-roam' but don't immediately initialize its database.
Instead, initialize it when it will be actually needed."
(letf! ((#'org-roam-db-sync #'ignore))
(org-roam-setup))
(defadvice! +org-roam-try-init-db-a (&rest _)
"Try to initialize org-roam database at the last possible safe moment.
In case of failure, fail gracefully."
:before #'org-roam-db-query
(message "Initializing org-roam database...")
(let ((run-cleanup-p t))
(unwind-protect
;; Try to build the binary if it doesn't exist. In case of failure
;; this will error, run the cleanup and exit, and in case of success
;; this will return nil and sync the database.
(setq run-cleanup-p (emacsql-sqlite-ensure-binary))
(when run-cleanup-p
(setq org-roam--sqlite-available-p nil)
(org-roam-teardown)
(message (concat "EmacSQL failied to build SQLite binary for org-roam; "
"see *Compile-Log* buffer for details.\n"
"To try reinitialize org-roam, run \"M-x org-roam-setup\"")))))
(advice-remove 'org-roam-db-query #'+org-roam-try-init-db-a)
(org-roam-db-sync)))
(setq org-roam-directory
(thread-first (or org-roam-directory "roam")
(expand-file-name org-directory)
(file-truename)
(file-name-as-directory))
org-roam-db-location
(or org-roam-db-location
(concat doom-etc-dir "org-roam.db"))
org-roam-node-display-template
"${doom-hierarchy:*} ${doom-tags:45}"
org-roam-completion-everywhere t
org-roam-mode-section-functions
#'(org-roam-backlinks-section
org-roam-reflinks-section))
(setq-hook! 'org-roam-find-file-hook
org-id-link-to-org-use-id +org-roam-link-to-org-use-id)
;; Normally, the org-roam buffer doesn't open until you explicitly call
;; `org-roam'. If `+org-roam-open-buffer-on-find-file' is non-nil, the
;; org-roam buffer will be opened for you whenever you visit a file in
;; `org-roam-directory'.
(add-hook! 'org-roam-find-file-hook :append
(defun +org-roam-open-with-buffer-maybe-h ()
(and +org-roam-open-buffer-on-find-file
(not org-roam-capture--node) ; don't proc for capture buffers
(not (eq 'visible (org-roam-buffer--visibility)))
(org-roam-buffer-toggle))))
(set-popup-rules!
`((,(regexp-quote org-roam-buffer) ; persistent org-roam buffer
:side right :width .33 :height .5 :ttl nil :modeline nil :quit nil :slot 1)
("^\\*org-roam: " ; node dedicated org-roam buffer
:side right :width .33 :height .5 :ttl nil :modeline nil :quit nil :slot 2)))
(add-hook 'org-roam-mode-hook #'turn-on-visual-line-mode)
(map! (:map org-mode-map
:localleader
:prefix ("m" . "org-roam")
"D" #'org-roam-demote-entire-buffer
"f" #'org-roam-node-find
"F" #'org-roam-ref-find
"g" #'org-roam-graph
"i" #'org-roam-node-insert
"I" #'org-id-get-create
"m" #'org-roam-buffer-toggle
"M" #'org-roam-buffer-display-dedicated
"n" #'org-roam-capture
"r" #'org-roam-refile
"R" #'org-roam-link-replace-all
(:prefix ("d" . "by date")
:desc "Goto previous note" "b" #'org-roam-dailies-goto-previous-note
:desc "Goto date" "d" #'org-roam-dailies-goto-date
:desc "Capture date" "D" #'org-roam-dailies-capture-date
:desc "Goto next note" "f" #'org-roam-dailies-goto-next-note
:desc "Goto tomorrow" "m" #'org-roam-dailies-goto-tomorrow
:desc "Capture tomorrow" "M" #'org-roam-dailies-capture-tomorrow
:desc "Capture today" "n" #'org-roam-dailies-capture-today
:desc "Goto today" "t" #'org-roam-dailies-goto-today
:desc "Capture today" "T" #'org-roam-dailies-capture-today
:desc "Goto yesterday" "y" #'org-roam-dailies-goto-yesterday
:desc "Capture yesterday" "Y" #'org-roam-dailies-capture-yesterday
:desc "Find directory" "-" #'org-roam-dailies-find-directory)
(:prefix ("o" . "node properties")
"a" #'org-roam-alias-add
"A" #'org-roam-alias-remove
"t" #'org-roam-tag-add
"T" #'org-roam-tag-remove
"r" #'org-roam-ref-add
"R" #'org-roam-ref-remove)))
(when (featurep! :editor evil +everywhere)
(add-hook! 'org-roam-mode-hook
(defun +org-roam-detach-magit-section-mode-map-h ()
"Detach `magit-section-mode-map' from `org-roam-mode-map'.
Inheriting its keymaps introduces a lot of conflicts in
`org-roam-mode' based buffers, where Evil and leader keybindings
will become completely overridden. This is because `magit-section'
uses 'keymap text-property to attach section-unique keymaps, which
has a higher level of precedence than `emulation-mode-map-alists'.
Note: We do this each time through the hook, because otherwise
sections seems to ignore the detachment."
(set-keymap-parent org-roam-mode-map nil)))
(map! :map org-roam-mode-map
:nv "]" #'magit-section-forward-sibling
:nv "[" #'magit-section-backward-sibling
:nv "gj" #'magit-section-forward-sibling
:nv "gk" #'magit-section-backward-sibling
:nv "gr" #'revert-buffer
:nv "gR" #'revert-buffer
:nv "z1" #'magit-section-show-level-1
:nv "z2" #'magit-section-show-level-2
:nv "z3" #'magit-section-show-level-3
:nv "z4" #'magit-section-show-level-4
:nv "za" #'magit-section-toggle
:nv "zc" #'magit-section-hide
:nv "zC" #'magit-section-hide-children
:nv "zo" #'magit-section-show
:nv "zO" #'magit-section-show-children
:nv "zr" #'magit-section-show-level-4-all
:nv "C-j" #'magit-section-forward
:nv "C-k" #'magit-section-backward
:g "M-p" #'magit-section-backward-sibling
:g "M-n" #'magit-section-forward-sibling
:g [tab] #'magit-section-toggle
:g [C-tab] #'magit-section-cycle
:g [backtab] #'magit-section-cycle-global)))
;; Since the org module lazy loads org-protocol (waits until an org URL is
;; detected), we can safely chain `org-roam-protocol' to it.
(use-package! org-roam-protocol
:after org-protocol)

View file

@ -7,7 +7,9 @@
(when (featurep! +roam) (when (featurep! +roam)
(unless (executable-find "sqlite3") (unless (executable-find "sqlite3")
(warn! "Couldn't find the sqlite3 executable. org-roam will not work.")) (warn! "Couldn't find the sqlite3 executable. org-roam will not work.")))
(when (or (featurep! +roam)
(featurep! +roam2))
(unless (executable-find "dot") (unless (executable-find "dot")
(warn! "Couldn't find the dot executable (from graphviz). org-roam will not be able to generate graph visualizations."))) (warn! "Couldn't find the dot executable (from graphviz). org-roam will not be able to generate graph visualizations.")))

View file

@ -76,8 +76,13 @@
:recipe (:host github :repo "hakimel/reveal.js" :recipe (:host github :repo "hakimel/reveal.js"
:files ("css" "dist" "js" "plugin")) :files ("css" "dist" "js" "plugin"))
:pin "b18f12d964ef80bd9ffb061aae48ff4c15fb43ad")) :pin "b18f12d964ef80bd9ffb061aae48ff4c15fb43ad"))
(when (featurep! +roam) (cond
(package! org-roam :pin "756f6215b672e267f986a3d6e494f5309825b91a")) ((featurep! +roam)
(package! org-roam
:recipe (:host github :repo "org-roam/org-roam-v1")
:pin "946a879a4a18756a0508afba1e0b0fe070c6a8b4"))
((featurep! +roam2)
(package! org-roam :pin "028c95a011395d01ff9b5217dc365f23187bc26c")))
;;; Babel ;;; Babel
(package! ob-async :pin "9aac486073f5c356ada20e716571be33a350a982") (package! ob-async :pin "9aac486073f5c356ada20e716571be33a350a982")