branch: externals/doc-view-follow commit 94ce8aa3aa4b28f839e2679a0a5e8fb6625dbce7 Author: Paul Nelson <ultr...@gmail.com> Commit: Paul Nelson <ultr...@gmail.com>
Refactor page synchronization in doc-dual-view mode * doc-dual-view.el (doc-dual-view--sync-pages): Rewrite using when-let* for clearer logic and better error handling. Simplify the window iteration logic by using a straightforward loop with counter. (doc-dual-view--schedule-redisplay): Remove obsolete function as the timer management is now done directly in doc-dual-view--sync-pages. --- doc-dual-view.el | 116 +++++++++++++++++++++---------------------------------- 1 file changed, 44 insertions(+), 72 deletions(-) diff --git a/doc-dual-view.el b/doc-dual-view.el index 3c1314bffa..6910a7ba93 100644 --- a/doc-dual-view.el +++ b/doc-dual-view.el @@ -79,78 +79,50 @@ redisplay-func)." (defun doc-dual-view--sync-pages (&rest _args) "Sync pages between windows showing the same document." - (let* ((mode-funcs (assoc major-mode doc-dual-view-modes)) - (goto-funcs (nth 1 mode-funcs)) - (current-page-func (nth 2 mode-funcs)) - (max-page-func (nth 3 mode-funcs)) - (redisplay-func (nth 4 mode-funcs))) - (when mode-funcs - (let* ((windows (doc-dual-view--order-windows - (get-buffer-window-list nil nil nil))) - (current-window (selected-window)) - (window-index (cl-position current-window windows)) - (current-page (funcall current-page-func)) - (max-page (funcall max-page-func))) - - ;; Only proceed if we found our window in the list and have multiple windows - (when (and window-index (> (length windows) 1)) - ;; Temporarily remove advice to prevent recursion - (dolist (func goto-funcs) - (advice-remove func #'doc-dual-view--sync-pages)) - - (unwind-protect - (progn - ;; Create a list of target pages for all windows - (let ((target-pages - (cl-loop for i from 0 below (length windows) - collect (cond - ((< i window-index) - (max 1 (- current-page (- window-index i)))) - ((> i window-index) - (min max-page (+ current-page (- i window-index)))) - (t current-page))))) - - ;; Apply the target pages to each window - (cl-loop for win in windows - for target-page in target-pages - for i from 0 - when (and (not (eq win current-window)) - (window-live-p win)) - do (with-selected-window win - (let ((current (funcall current-page-func))) - (when (not (= current target-page)) - (funcall (car goto-funcs) target-page) - ;; Use a unique timer for each window - (let ((timer-sym (intern (format "doc-dual-view--redisplay-timer-%d" i)))) - (when (and (boundp timer-sym) - (timerp (symbol-value timer-sym))) - (cancel-timer (symbol-value timer-sym))) - (set timer-sym - (run-with-idle-timer - 0.001 nil - (lambda (w f p) - (when (window-live-p w) - (with-selected-window w - (funcall f p)))) - win redisplay-func target-page))))))))) - - ;; Re-add advice after execution - (dolist (func goto-funcs) - (advice-add func :after #'doc-dual-view--sync-pages)))))))) - -(defun doc-dual-view--schedule-redisplay (window redisplay-func page) - "Schedule a redisplay for WINDOW using REDISPLAY-FUNC to show PAGE." - (when doc-dual-view--redisplay-timer - (cancel-timer doc-dual-view--redisplay-timer)) - (setq doc-dual-view--redisplay-timer - (run-with-idle-timer - 0.001 nil - (lambda (win func pg) - (when (window-live-p win) - (with-selected-window win - (funcall func pg)))) - window redisplay-func page))) - + (when-let* ((mode-funcs (assoc major-mode doc-dual-view-modes)) + (windows (doc-dual-view--order-windows + (get-buffer-window-list nil nil nil))) + ((> (length windows) 1)) + (goto-funcs (nth 1 mode-funcs)) + (current-page-func (nth 2 mode-funcs)) + (max-page-func (nth 3 mode-funcs)) + (redisplay-func (nth 4 mode-funcs)) + (current-window (selected-window)) + (window-index (seq-position windows current-window)) + (current-page (funcall current-page-func)) + (max-page (funcall max-page-func))) + (dolist (func goto-funcs) + (advice-remove func #'doc-dual-view--sync-pages)) + (unwind-protect + (let ((i 0)) + (dolist (win windows) + (let ((target-page (cond + ((< i window-index) + (max 1 (- current-page (- window-index i)))) + ((> i window-index) + (min max-page (+ current-page (- i window-index)))) + (t current-page)))) + (when (and (not (eq win current-window)) + (window-live-p win)) + (with-selected-window win + (let ((current (funcall current-page-func))) + (when (not (= current target-page)) + (funcall (car goto-funcs) target-page) + (let ((timer-sym (intern (format "doc-dual-view--redisplay-timer-%d" i)))) + (when (and (boundp timer-sym) + (timerp (symbol-value timer-sym))) + (cancel-timer (symbol-value timer-sym))) + (set timer-sym + (run-with-idle-timer + 0.001 nil + (lambda (w f p) + (when (window-live-p w) + (with-selected-window w + (funcall f p)))) + win redisplay-func target-page)))))))) + (setq i (1+ i)))) + (dolist (func goto-funcs) + (advice-add func :after #'doc-dual-view--sync-pages))))) ;;;###autoload (define-minor-mode doc-dual-view-mode