From e62cf7f8aa9031c8e485eec92782c1d14702c173 Mon Sep 17 00:00:00 2001 From: Jethro Kuan Date: Thu, 25 Mar 2021 20:33:18 +0800 Subject: [PATCH] add persistent org-roam-buffer --- org-roam-completion.el | 7 +++++ org-roam-db.el | 7 +++++ org-roam-mode.el | 67 +++++++++++++++++++++++++++++++++++++++--- org-roam.el | 17 +++++------ 4 files changed, 85 insertions(+), 13 deletions(-) diff --git a/org-roam-completion.el b/org-roam-completion.el index f8af741..f95c9e1 100644 --- a/org-roam-completion.el +++ b/org-roam-completion.el @@ -112,6 +112,13 @@ This is a `completion-at-point' function, and is active when str)) (forward-char 2))))))) +(defun org-roam--register-completion-functions () + "." + (dolist (fn org-roam-completion-functions) + (add-hook 'completion-at-point-functions fn nil t))) + +(add-hook 'org-roam-find-file-hook #'org-roam--register-completion-functions) + (provide 'org-roam-completion) ;;; org-roam-completion.el ends here diff --git a/org-roam-db.el b/org-roam-db.el index 954cc3f..02cf7fc 100644 --- a/org-roam-db.el +++ b/org-roam-db.el @@ -44,6 +44,7 @@ (require 'org-roam-structs) (defvar org-roam-directory) +(defvar org-roam-find-file-hook) (defvar org-roam-verbose) (defvar org-agenda-files) @@ -463,6 +464,12 @@ If the file exists, update the cache with information." (org-roam-db-map-links (list #'org-roam-db-insert-link))))))) +(defun org-roam-db--update-on-save-h () + "." + (add-hook 'after-save-hook #'org-roam-db-update-file nil t)) + +(add-to-list 'org-roam-find-file-hook #'org-roam-db--update-on-save-h) + ;; Diagnostic Interactives (defun org-roam-db-diagnose-node () "Print information about node at point." diff --git a/org-roam-mode.el b/org-roam-mode.el index 65fc8b9..f1c6e1f 100644 --- a/org-roam-mode.el +++ b/org-roam-mode.el @@ -35,6 +35,7 @@ (require 'org-roam-utils) (defvar org-roam-directory) +(defvar org-roam-find-file-hook) (declare-function org-roam--org-file-p "org-roam") (declare-function org-roam-node-at-point "org-roam-node") @@ -120,10 +121,6 @@ and `:slant'." :group 'org-roam-faces) ;;; Variables -;; TODO: make defcustom -(defvar org-roam-last-window nil - "Last window `org-roam' was called from.") - (defvar org-roam-mode-sections nil "List of functions that insert sections for Org-roam.") @@ -169,5 +166,67 @@ which visits the thing at point." (switch-to-buffer-other-window buffer))) (user-error "No node at point"))) +;;; Persistent buffer +(defvar org-roam-current-node nil + "The current node at point.") + +(defvar org-roam-buffer "*org-roam*" + "The persistent Org-roam buffer name.") + +(defun org-roam-buffer--post-command-h () + "Reconstructs `org-roam-buffer'. +This needs to be quick or infrequent, because this is run at +`post-command-hook'. If REDISPLAY, force an update of +`org-roam-buffer'." + (when (get-buffer-window org-roam-buffer) + (when-let ((node (org-roam-node-at-point))) + (unless (equal node org-roam-current-node) + (setq org-roam-current-node node) + (org-roam-buffer-persistent-redisplay))))) + +(define-inline org-roam-buffer--visibility () + "Return whether the current visibility state of the org-roam buffer. +Valid states are 'visible, 'exists and 'none." + (declare (side-effect-free t)) + (inline-quote + (cond + ((get-buffer-window org-roam-buffer) 'visible) + ((get-buffer org-roam-buffer) 'exists) + (t 'none)))) + +(defun org-roam-buffer-toggle () + "Toggle display of the `org-roam-buffer'." + (interactive) + (pcase (org-roam-buffer--visibility) + ('visible + (progn + (delete-window (get-buffer-window org-roam-buffer)) + (remove-hook 'post-command-hook #'org-roam-buffer--post-command-h))) + ((or 'exists 'none) + (progn + (display-buffer (get-buffer-create org-roam-buffer)) + (setq org-roam-current-node (org-roam-node-at-point)) + (org-roam-buffer-persistent-redisplay))))) + +(defun org-roam-buffer-persistent-redisplay () + "Recompute contents of the persistent Org-roam buffer. +Has no effect when `org-roam-current-node' is nil." + (when org-roam-current-node + (with-current-buffer (get-buffer-create org-roam-buffer) + (let ((inhibit-read-only t)) + (erase-buffer) + (org-roam-mode) + (org-roam-set-header-line-format (org-roam-node-title org-roam-current-node)) + (magit-insert-section (org-roam) + (magit-insert-heading) + (dolist (fn org-roam-mode-sections) + (funcall fn org-roam-current-node))))))) + +(defun org-roam-buffer--redisplay () + "." + (add-hook 'post-command-hook #'org-roam-buffer--post-command-h nil t)) + +(add-hook 'org-roam-find-file-hook #'org-roam-buffer--redisplay) + (provide 'org-roam-mode) ;;; org-roam-mode.el ends here diff --git a/org-roam.el b/org-roam.el index 5a0028d..5931e57 100644 --- a/org-roam.el +++ b/org-roam.el @@ -372,6 +372,9 @@ Use external shell commands if defined in `org-roam-list-files-commands'." completions)) ;;; Org-roam setup and teardown +(defvar org-roam-find-file-hook nil + "Hook run when an Org-roam file is visited.") + (defun org-roam-setup () "Setup Org-roam." (interactive) @@ -381,7 +384,7 @@ Use external shell commands if defined in `org-roam-list-files-commands'." (lwarn '(org-roam) :error "Cannot find executable 'sqlite3'. \ Ensure it is installed and can be found within `exec-path'. \ M-x info for more information at Org-roam > Installation > Post-Installation Tasks.")) - (add-hook 'find-file-hook #'org-roam--find-file-hook-function) + (add-hook 'find-file-hook #'org-roam--file-setup) (add-hook 'kill-emacs-hook #'org-roam-db--close-all) (advice-add 'rename-file :after #'org-roam--rename-file-advice) (advice-add 'delete-file :before #'org-roam--delete-file-advice) @@ -390,7 +393,7 @@ M-x info for more information at Org-roam > Installation > Post-Installation Tas (defun org-roam-teardown () "Teardown Org-roam." (interactive) - (remove-hook 'find-file-hook #'org-roam--find-file-hook-function) + (remove-hook 'find-file-hook #'org-roam--file-setup) (remove-hook 'kill-emacs-hook #'org-roam-db--close-all) (advice-remove 'rename-file #'org-roam--rename-file-advice) (advice-remove 'delete-file #'org-roam--delete-file-advice) @@ -401,14 +404,10 @@ M-x info for more information at Org-roam > Installation > Post-Installation Tas (remove-hook 'after-save-hook #'org-roam-db-update-file t)))) ;;; Hooks and advices -(defun org-roam--find-file-hook-function () - "Setup automatic database update." +(defun org-roam--file-setup () + "Setup an Org-roam file." (when (org-roam--org-roam-file-p) - (setq org-roam-last-window (get-buffer-window)) - (run-hooks 'org-roam-file-setup-hook) ; Run user hooks - (add-hook 'after-save-hook #'org-roam-db-update-file nil t) - (dolist (fn org-roam-completion-functions) - (add-hook 'completion-at-point-functions fn nil t)))) + (run-hooks 'org-roam-find-file-hook))) (defun org-roam--delete-file-advice (file &optional _trash) "Maintain cache consistency when file deletes.