branch: externals/doc-view-follow
commit eb1f6f0ed75a99aae037eeff1a640532fcb585b4
Author: Paul Nelson <ultr...@gmail.com>
Commit: Paul Nelson <ultr...@gmail.com>

    Improve advice management
    
    * doc-dual-view.el (doc-dual-view--sync-pages): Only run
    synchronization when mode is active.
    (doc-dual-view--manage-advice): New function to centralize adding and
    removing advice for all functions in doc-dual-view-modes.
    (doc-dual-view--some-buffer-active-p): New function to check if any
    buffer has the mode enabled.
    (doc-dual-view-mode): Refactor to use the new helper functions and
    only remove advice when no buffers are using the mode.
---
 doc-dual-view.el | 31 ++++++++++++++++++++++---------
 1 file changed, 22 insertions(+), 9 deletions(-)

diff --git a/doc-dual-view.el b/doc-dual-view.el
index e78c07a02d..31183118f9 100644
--- a/doc-dual-view.el
+++ b/doc-dual-view.el
@@ -87,7 +87,8 @@ by adding entries to this list.")
 
 (defun doc-dual-view--sync-pages (&rest _args)
   "Sync pages between windows showing the same document."
-  (unless doc-dual-view--sync-in-progress
+  (when (and doc-dual-view-mode
+             (not doc-dual-view--sync-in-progress))
     (let ((doc-dual-view--sync-in-progress t))
       (when-let*
           ((cfg (cdr (assoc major-mode doc-dual-view-modes)))
@@ -107,18 +108,30 @@ by adding entries to this list.")
                  (doc-dual-view--call-func cfg :goto target-page))))
            windows))))))
 
+(defun doc-dual-view--manage-advice (add-or-remove)
+  "Add or remove advice for all functions in `doc-dual-view-modes`.
+ADD-OR-REMOVE should be either 'add or 'remove."
+  (dolist (mode-entry doc-dual-view-modes)
+    (dolist (action '(:goto :next :prev))
+      (when-let ((func (plist-get (cdr mode-entry) action)))
+        (if (eq add-or-remove 'add)
+            (advice-add func :after #'doc-dual-view--sync-pages)
+          (advice-remove func #'doc-dual-view--sync-pages))))))
+
+(defun doc-dual-view--some-buffer-active-p ()
+  "Return non-nil if some buffer has `doc-dual-view-mode' active."
+  (seq-some (lambda (buf)
+              (buffer-local-value 'doc-dual-view-mode buf))
+            (buffer-list)))
+
 ;;;###autoload
 (define-minor-mode doc-dual-view-mode
   "Minor mode to sync pages between two windows showing the same document."
   :global nil
-  (dolist (mode-entry doc-dual-view-modes)
-    (let* ((mode (car mode-entry))
-           (mode-config (cdr mode-entry)))
-      (dolist (action '(:goto :next :prev))
-        (let ((func (plist-get mode-config action)))
-          (if doc-dual-view-mode
-              (advice-add func :after #'doc-dual-view--sync-pages)
-            (advice-remove func #'doc-dual-view--sync-pages)))))))
+  (if doc-dual-view-mode
+      (doc-dual-view--manage-advice 'add)
+    (unless (doc-dual-view--some-buffer-active-p)
+      (doc-dual-view--manage-advice 'remove))))
 
 (defun doc-dual-view--maybe-enable ()
   "Enable `doc-dual-view-mode' if appropriate for this buffer."

Reply via email to