From 5ef733b48809947cf58d9f10e8a3d058e44d71de Mon Sep 17 00:00:00 2001 From: Wetlize Date: Mon, 19 Jul 2021 00:53:07 +0300 Subject: [PATCH 1/7] lang/org: Add +roam2 flag for org-roam v2 --- modules/config/default/+emacs-bindings.el | 25 ++++- modules/config/default/+evil-bindings.el | 24 ++++ modules/lang/org/README.org | 57 +++++++++- modules/lang/org/autoload/contrib-roam2.el | 45 ++++++++ modules/lang/org/config.el | 2 +- modules/lang/org/contrib/roam2.el | 122 +++++++++++++++++++++ modules/lang/org/doctor.el | 3 +- modules/lang/org/packages.el | 9 +- 8 files changed, 278 insertions(+), 9 deletions(-) create mode 100644 modules/lang/org/autoload/contrib-roam2.el create mode 100644 modules/lang/org/contrib/roam2.el 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") From 9e1287377962b4e55fa1747f597b69f343ad07c9 Mon Sep 17 00:00:00 2001 From: Wetlize Date: Fri, 23 Jul 2021 00:40:49 +0300 Subject: [PATCH 2/7] Update handling of the database v2 reverted to using `emacsql-sqlite` instead of `emacsql-sqlite3`. It will now try to build the needed `sqlite3` executable by itself, using a C compiler that it can find, which is normally gcc or clang. Previously in v1 it would only check for `sqlite3` executable (using `executable-find`) and wouldn't do anything else. --- modules/lang/org/contrib/roam2.el | 32 +++++++++++++++++++++++++++---- modules/lang/org/doctor.el | 5 +++-- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/modules/lang/org/contrib/roam2.el b/modules/lang/org/contrib/roam2.el index c1ea3a3a8..b741693b1 100644 --- a/modules/lang/org/contrib/roam2.el +++ b/modules/lang/org/contrib/roam2.el @@ -24,7 +24,7 @@ of org-mode to properly utilize ID links.") :init (doom-load-packages-incrementally - '(ansi-color dash f rx seq magit-section)) + '(ansi-color dash f rx seq magit-section emacsql emacsql-sqlite)) (map! :after org :map org-mode-map @@ -65,17 +65,41 @@ of org-mode to properly utilize ID links.") ;; 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-location)) + (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-init-db-a (&rest _) - "Initialize org-roam database when it's first time queried to." + (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 - (advice-remove 'org-roam-db-query #'+org-roam-init-db-a) (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 diff --git a/modules/lang/org/doctor.el b/modules/lang/org/doctor.el index d8a5261f8..d96e1c721 100644 --- a/modules/lang/org/doctor.el +++ b/modules/lang/org/doctor.el @@ -5,10 +5,11 @@ (unless (executable-find "gnuplot") (warn! "Couldn't find gnuplot. org-plot/gnuplot will not work"))) +(when (featurep! +roam) + (unless (executable-find "sqlite3") + (warn! "Couldn't find the sqlite3 executable. org-roam will not work."))) (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") (warn! "Couldn't find the dot executable (from graphviz). org-roam will not be able to generate graph visualizations."))) From 9f7641d6c8616adb2b029b5de26d241271799cb6 Mon Sep 17 00:00:00 2001 From: Wetlize Date: Fri, 23 Jul 2021 02:53:51 +0300 Subject: [PATCH 3/7] Add evil bindings for org-roam-mode These are about the same as you would have them in `magit`. --- modules/lang/org/contrib/roam2.el | 93 +++++++++++++++++++------------ 1 file changed, 56 insertions(+), 37 deletions(-) diff --git a/modules/lang/org/contrib/roam2.el b/modules/lang/org/contrib/roam2.el index b741693b1..3f7e10d70 100644 --- a/modules/lang/org/contrib/roam2.el +++ b/modules/lang/org/contrib/roam2.el @@ -26,42 +26,6 @@ of org-mode to properly utilize ID links.") (doom-load-packages-incrementally '(ansi-color dash f rx seq magit-section emacsql emacsql-sqlite)) - (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) @@ -137,7 +101,62 @@ In case of failure, fail gracefully." ("^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)) + (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 + "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)) + (:map org-roam-mode-map + :when (featurep! :editor evil +everywhere) + :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))) ;; Since the org module lazy loads org-protocol (waits until an org URL is From ff331781c5429b1482b08b5e83ab03a917614645 Mon Sep 17 00:00:00 2001 From: Wetlize Date: Sat, 24 Jul 2021 01:17:14 +0300 Subject: [PATCH 4/7] Bump org-roam org-roam/org-roam@e997c01 -> org-roam/org-roam@028c95a --- modules/config/default/+emacs-bindings.el | 1 + modules/config/default/+evil-bindings.el | 1 + modules/lang/org/contrib/roam2.el | 4 ++-- modules/lang/org/packages.el | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/config/default/+emacs-bindings.el b/modules/config/default/+emacs-bindings.el index 5057e2087..95ab4ea5a 100644 --- a/modules/config/default/+emacs-bindings.el +++ b/modules/config/default/+emacs-bindings.el @@ -198,6 +198,7 @@ :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 diff --git a/modules/config/default/+evil-bindings.el b/modules/config/default/+evil-bindings.el index 34deb606a..3e0b5a8fb 100644 --- a/modules/config/default/+evil-bindings.el +++ b/modules/config/default/+evil-bindings.el @@ -545,6 +545,7 @@ :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 diff --git a/modules/lang/org/contrib/roam2.el b/modules/lang/org/contrib/roam2.el index 3f7e10d70..724827b2e 100644 --- a/modules/lang/org/contrib/roam2.el +++ b/modules/lang/org/contrib/roam2.el @@ -98,7 +98,7 @@ In case of failure, fail gracefully." (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 + ("^\\*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) @@ -113,7 +113,7 @@ In case of failure, fail gracefully." "i" #'org-roam-node-insert "I" #'org-id-get-create "m" #'org-roam-buffer-toggle - "M" #'org-roam-buffer + "M" #'org-roam-buffer-display-dedicated "n" #'org-roam-capture "r" #'org-roam-refile "R" #'org-roam-link-replace-all diff --git a/modules/lang/org/packages.el b/modules/lang/org/packages.el index 70a23d928..cc02eda5a 100644 --- a/modules/lang/org/packages.el +++ b/modules/lang/org/packages.el @@ -82,7 +82,7 @@ :recipe (:host github :repo "org-roam/org-roam-v1") :pin "946a879a4a18756a0508afba1e0b0fe070c6a8b4")) ((featurep! +roam2) - (package! org-roam :pin "e997c017deab234a0a067914d7bb6e81e3fa9d88"))) + (package! org-roam :pin "028c95a011395d01ff9b5217dc365f23187bc26c"))) ;;; Babel (package! ob-async :pin "9aac486073f5c356ada20e716571be33a350a982") From 13f0c4785e957cdfbed0370e03e101f788a88c8c Mon Sep 17 00:00:00 2001 From: Wetlize Date: Sat, 24 Jul 2021 16:24:11 +0300 Subject: [PATCH 5/7] Fix keymap precedence for evil users in the org-roam-buffer `org-roam-mode` based buffers use `magit-section` to render sections. The problem is that `magit-section` will layer keymaps for each section under a text property. In Emacs, text property based keymaps have a higher precedence for a lookup[0] than `emulation-mode-map-alists`, in which Evil and leader keymaps are stored in. [0]: https://www.gnu.org/software/emacs/manual/html_node/elisp/Searching-Keymaps.html --- modules/lang/org/contrib/roam2.el | 61 ++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 21 deletions(-) diff --git a/modules/lang/org/contrib/roam2.el b/modules/lang/org/contrib/roam2.el index 724827b2e..ff1af099a 100644 --- a/modules/lang/org/contrib/roam2.el +++ b/modules/lang/org/contrib/roam2.el @@ -136,27 +136,46 @@ In case of failure, fail gracefully." "t" #'org-roam-tag-add "T" #'org-roam-tag-remove "r" #'org-roam-ref-add - "R" #'org-roam-ref-remove)) - (:map org-roam-mode-map - :when (featurep! :editor evil +everywhere) - :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))) + "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 From c6e4ffb9295584e56c57e02789a58410f072b572 Mon Sep 17 00:00:00 2001 From: Wetlize Date: Sat, 24 Jul 2021 17:52:25 +0300 Subject: [PATCH 6/7] Improve display of custom templates in the minibuffer --- modules/lang/org/autoload/contrib-roam2.el | 37 +++++++++++++++------- modules/lang/org/contrib/roam2.el | 2 +- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/modules/lang/org/autoload/contrib-roam2.el b/modules/lang/org/autoload/contrib-roam2.el index e89dad3b5..72b6d3d9e 100644 --- a/modules/lang/org/autoload/contrib-roam2.el +++ b/modules/lang/org/autoload/contrib-roam2.el @@ -2,10 +2,10 @@ ;;;###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:\"." + "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))) @@ -13,25 +13,28 @@ ;;;###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." + "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))) - ;; TODO Add 'face based text properties for each type? + (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 filetitle " > " title)) + (1 (concat (propertize filetitle 'face '(shadow italic)) + separator title)) ;; node is a heading with an arbitrary outline path - (t (concat filetitle " > " (string-join olp " > ") " > " title))))) + (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 NODE's subdirectories, relative to `org-roam-directory'." + "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) @@ -41,5 +44,15 @@ duplicates from the hierarchy." ;;;###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)) + "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)))) diff --git a/modules/lang/org/contrib/roam2.el b/modules/lang/org/contrib/roam2.el index ff1af099a..fe98141b5 100644 --- a/modules/lang/org/contrib/roam2.el +++ b/modules/lang/org/contrib/roam2.el @@ -75,7 +75,7 @@ In case of failure, fail gracefully." (or org-roam-db-location (concat doom-etc-dir "org-roam.db")) org-roam-node-display-template - "${doom-hierarchy:*} ${doom-tags:35} ${doom-subdirs}" + "${doom-hierarchy:*} ${doom-tags:45}" org-roam-completion-everywhere t org-roam-mode-section-functions #'(org-roam-backlinks-section From 6330c57bce3756ce29b326afb2675d7b219cc109 Mon Sep 17 00:00:00 2001 From: Wetlize Date: Sat, 24 Jul 2021 18:59:46 +0300 Subject: [PATCH 7/7] Sniff for a different symbol in +org-roam-suppress-sqlite-build-a `org-roam-db-location` is redefined in the :preface section, so we need to rely on a different symbol to determine whether `org-roam` is loading or not. --- modules/lang/org/contrib/roam2.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/lang/org/contrib/roam2.el b/modules/lang/org/contrib/roam2.el index fe98141b5..3e4389ebd 100644 --- a/modules/lang/org/contrib/roam2.el +++ b/modules/lang/org/contrib/roam2.el @@ -35,7 +35,7 @@ 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-location)) + (if (not (boundp 'org-roam-db-version)) (apply orig-fn args) (advice-remove #'emacsql-sqlite-ensure-binary #'+org-roam-suppress-sqlite-build-a) nil))