diff --git a/modules/config/default/+emacs-bindings.el b/modules/config/default/+emacs-bindings.el index 4b2caa8fd..5057e2087 100644 --- a/modules/config/default/+emacs-bindings.el +++ b/modules/config/default/+emacs-bindings.el @@ -188,7 +188,30 @@ :desc "Arbitrary date" "d" #'org-roam-dailies-find-date :desc "Today" "t" #'org-roam-dailies-find-today :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 "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)))) ;;; o --- open "o" nil ; we need to unbind it first as Org claims this prefix diff --git a/modules/config/default/+evil-bindings.el b/modules/config/default/+evil-bindings.el index fb7dedcc4..34deb606a 100644 --- a/modules/config/default/+evil-bindings.el +++ b/modules/config/default/+evil-bindings.el @@ -536,6 +536,30 @@ :desc "Tomorrow" "m" #'org-roam-dailies-find-tomorrow :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 "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) (:prefix ("j" . "journal") :desc "New Entry" "j" #'org-journal-new-entry diff --git a/modules/lang/org/README.org b/modules/lang/org/README.org index ace6d4bb2..dd5823444 100644 --- a/modules/lang/org/README.org +++ b/modules/lang/org/README.org @@ -19,6 +19,10 @@ - [[#configuration][Configuration]] - [[#changing-org-directory][Changing ~org-directory~]] - [[#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 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 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. -+ =+roam= Enables org-roam integration. This requires ~sqlite3~ to be installed - on your system. ++ =+roam= Enables integration with [[https://github.com/org-roam/org-roam-v1][org-roam v1]]. This requires ~sqlite3~ to be + 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 + [[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/harrybournis/org-fancy-priorities][org-fancy-priorities]] + =+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= + [[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. To use ~jupyter kernels~ you need the =+jupyter= flag, the associated kernel as 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 #+BEGIN_SRC sh @@ -253,3 +261,44 @@ To modify ~org-noter-notes-search-path~ set: ;; ~/.doom.d/config.el (setq org-noter-notes-search-path '("~/notes/path/")) #+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. diff --git a/modules/lang/org/autoload/contrib-roam2.el b/modules/lang/org/autoload/contrib-roam2.el new file mode 100644 index 000000000..e89dad3b5 --- /dev/null +++ b/modules/lang/org/autoload/contrib-roam2.el @@ -0,0 +1,45 @@ +;;; 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 NODE's file level \"#+title:\"." + (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 NODE's hierarchy, constructed of its file-title, OLP and title. +This will automatically strip out any missing elements or +duplicates from the hierarchy." + (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))) + ;; TODO Add 'face based text properties for each type? + (cl-case level + ;; node is a top-level file + (0 filetitle) + ;; node is a level 1 heading + (1 (concat filetitle " > " title)) + ;; node is a heading with an arbitrary outline path + (t (concat filetitle " > " (string-join olp " > ") " > " 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 NODE's subdirectories, relative to `org-roam-directory'." + (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." + (mapconcat (lambda (s) (concat ":" s)) (org-roam-node-tags node) nil)) diff --git a/modules/lang/org/config.el b/modules/lang/org/config.el index 8c43f2d62..8701cda26 100644 --- a/modules/lang/org/config.el +++ b/modules/lang/org/config.el @@ -724,7 +724,7 @@ between the two." "f" #'org-footnote-new "h" #'org-toggle-heading "i" #'org-toggle-item - "I" #'org-toggle-inline-images + "I" #'org-id-get-create "n" #'org-store-link "o" #'org-set-property "q" #'org-set-tags-command diff --git a/modules/lang/org/contrib/roam2.el b/modules/lang/org/contrib/roam2.el new file mode 100644 index 000000000..c1ea3a3a8 --- /dev/null +++ b/modules/lang/org/contrib/roam2.el @@ -0,0 +1,122 @@ +;;; 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)) + + (map! :after org + :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 + "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)) + + ;; Don't display warning message dedicated for v1 users. Need to be set early. + (setq org-roam-v2-ack t) + + :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-init-db-a (&rest _) + "Initialize org-roam database when it's first time queried to." + :before #'org-roam-db-query + (advice-remove 'org-roam-db-query #'+org-roam-init-db-a) + (message "Initializing org-roam database...") + (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:35} ${doom-subdirs}" + 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)) + + +;; 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) diff --git a/modules/lang/org/doctor.el b/modules/lang/org/doctor.el index c4c672d24..d8a5261f8 100644 --- a/modules/lang/org/doctor.el +++ b/modules/lang/org/doctor.el @@ -5,7 +5,8 @@ (unless (executable-find "gnuplot") (warn! "Couldn't find gnuplot. org-plot/gnuplot will not work"))) -(when (featurep! +roam) +(when (or (featurep! +roam) + (featurep! +roam2)) (unless (executable-find "sqlite3") (warn! "Couldn't find the sqlite3 executable. org-roam will not work.")) (unless (executable-find "dot") diff --git a/modules/lang/org/packages.el b/modules/lang/org/packages.el index 5da2374f5..70a23d928 100644 --- a/modules/lang/org/packages.el +++ b/modules/lang/org/packages.el @@ -76,8 +76,13 @@ :recipe (:host github :repo "hakimel/reveal.js" :files ("css" "dist" "js" "plugin")) :pin "b18f12d964ef80bd9ffb061aae48ff4c15fb43ad")) -(when (featurep! +roam) - (package! org-roam :pin "756f6215b672e267f986a3d6e494f5309825b91a")) +(cond + ((featurep! +roam) + (package! org-roam + :recipe (:host github :repo "org-roam/org-roam-v1") + :pin "946a879a4a18756a0508afba1e0b0fe070c6a8b4")) + ((featurep! +roam2) + (package! org-roam :pin "e997c017deab234a0a067914d7bb6e81e3fa9d88"))) ;;; Babel (package! ob-async :pin "9aac486073f5c356ada20e716571be33a350a982")