1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-12-11 09:20:51 +00:00

Use global window hook for erc-keep-place-indicator

* lisp/erc/erc-goodies.el
(erc--keep-place-indicator-on-window-buffer-change): Expect a frame
instead of a window argument for the only parameter, which is now
ignored, and exit early when entering a minibuffer.
(erc--keep-place-indicator-setup): Remove function because local
modules don't need a separate setup function.
(erc-keep-place-indicator-mode): Add autoload cookie even though this
is a local module, since this particular one is intended for more
granular, interactive activation.  This is mostly a formality because
it only matters in the unlikely event `erc-modules' is missing all
other modules defined in `erc-goodies'.
(erc-keep-place-indicator-mode, erc-keep-place-indicator-enable,
erc-keep-place-indicator-disable): Move functionality from
`erc--keep-place-indicator-setup' into enable body.  Use global
instead of local members for `erc-keep-place-mode-hook' and
`window-buffer-change-functions'.
(erc--keep-place-indicator-on-global-module): Perform necessary action
in all ERC buffers, not just the current one, where the user has
ostensibly disabled `erc-keep-place-mode'.
* test/lisp/erc/erc-goodies-tests.el
(erc-goodies-tests--assert-kp-indicator-on,
erc-goodies-tests--assert-kp-indicator-off): Change expected hook
membership for dependencies from global to local.
(erc-goodies-tests--keep-place-indicator): Use new helpers from
the `erc-tests-common' library.  (Bug#59943)
This commit is contained in:
F. Jason Park 2024-01-01 23:18:54 -08:00
parent 74f022b279
commit fad2d1e2ac
2 changed files with 52 additions and 50 deletions

View File

@ -331,14 +331,15 @@ buffer than the window's start."
(defvar-local erc--keep-place-indicator-overlay nil
"Overlay for `erc-keep-place-indicator-mode'.")
(defun erc--keep-place-indicator-on-window-buffer-change (window)
(defun erc--keep-place-indicator-on-window-buffer-change (_)
"Maybe sync `erc--keep-place-indicator-overlay'.
Do so only when switching to a new buffer in the same window if
the replaced buffer is no longer visible in another window and
its `window-start' at the time of switching is strictly greater
than the indicator's position."
(when-let ((erc-keep-place-indicator-follow)
((eq window (selected-window)))
(window (selected-window))
((not (eq window (active-minibuffer-window))))
(old-buffer (window-old-buffer window))
((buffer-live-p old-buffer))
((not (eq old-buffer (current-buffer))))
@ -352,67 +353,70 @@ than the indicator's position."
(with-current-buffer old-buffer
(erc-keep-place-move old-start))))
(defun erc--keep-place-indicator-setup ()
"Initialize buffer for maintaining `erc--keep-place-indicator-overlay'."
(require 'fringe)
(erc--restore-initialize-priors erc-keep-place-indicator-mode
erc--keep-place-indicator-overlay (make-overlay 0 0))
(add-hook 'erc-keep-place-mode-hook
#'erc--keep-place-indicator-on-global-module nil t)
(add-hook 'window-buffer-change-functions
#'erc--keep-place-indicator-on-window-buffer-change 40 t)
(when-let* (((memq erc-keep-place-indicator-style '(t arrow)))
(ov-property (if (zerop (fringe-columns 'left))
'after-string
'before-string))
(display (if (zerop (fringe-columns 'left))
`((margin left-margin) ,overlay-arrow-string)
'(left-fringe right-triangle
erc-keep-place-indicator-arrow)))
(bef (propertize " " 'display display)))
(overlay-put erc--keep-place-indicator-overlay ov-property bef))
(when (memq erc-keep-place-indicator-style '(t face))
(overlay-put erc--keep-place-indicator-overlay 'face
'erc-keep-place-indicator-line)))
;;;###autoload(put 'keep-place-indicator 'erc--feature 'erc-goodies)
;;;###autoload(autoload 'erc-keep-place-indicator-mode "erc-goodies" nil t)
(define-erc-module keep-place-indicator nil
"Buffer-local `keep-place' with fringe arrow and/or highlighted face.
Play nice with global module `keep-place' but don't depend on it.
Expect that users may want different combinations of `keep-place'
and `keep-place-indicator' in different buffers. Unlike global
`keep-place', when `switch-to-buffer-preserve-window-point' is
enabled, don't forcibly sync point in all windows where buffer
has previously been shown because that defeats the purpose of
having a placeholder."
and `keep-place-indicator' in different buffers."
((cond (erc-keep-place-mode)
((memq 'keep-place erc-modules)
(erc-keep-place-mode +1))
;; Enable a local version of `keep-place-mode'.
(t (add-hook 'erc-insert-pre-hook #'erc-keep-place 65 t)))
(require 'fringe)
(add-hook 'window-buffer-change-functions
#'erc--keep-place-indicator-on-window-buffer-change 40)
(add-hook 'erc-keep-place-mode-hook
#'erc--keep-place-indicator-on-global-module 40)
(if (pcase erc-keep-place-indicator-buffer-type
('target erc--target)
('server (not erc--target))
('t t))
(erc--keep-place-indicator-setup)
(progn
(erc--restore-initialize-priors erc-keep-place-indicator-mode
erc--keep-place-indicator-overlay (make-overlay 0 0))
(when-let (((memq erc-keep-place-indicator-style '(t arrow)))
(ov-property (if (zerop (fringe-columns 'left))
'after-string
'before-string))
(display (if (zerop (fringe-columns 'left))
`((margin left-margin) ,overlay-arrow-string)
'(left-fringe right-triangle
erc-keep-place-indicator-arrow)))
(bef (propertize " " 'display display)))
(overlay-put erc--keep-place-indicator-overlay ov-property bef))
(when (memq erc-keep-place-indicator-style '(t face))
(overlay-put erc--keep-place-indicator-overlay 'face
'erc-keep-place-indicator-line)))
(erc-keep-place-indicator-mode -1)))
((when erc--keep-place-indicator-overlay
(delete-overlay erc--keep-place-indicator-overlay))
(remove-hook 'window-buffer-change-functions
#'erc--keep-place-indicator-on-window-buffer-change t)
(let ((buffer (current-buffer)))
;; Remove global hooks unless others exist with mode enabled.
(unless (erc-buffer-filter (lambda ()
(and (not (eq buffer (current-buffer)))
erc-keep-place-indicator-mode)))
(remove-hook 'erc-keep-place-mode-hook
#'erc--keep-place-indicator-on-global-module)
(remove-hook 'window-buffer-change-functions
#'erc--keep-place-indicator-on-window-buffer-change)))
(when (local-variable-p 'erc-insert-pre-hook)
(remove-hook 'erc-insert-pre-hook #'erc-keep-place t))
(remove-hook 'erc-keep-place-mode-hook
#'erc--keep-place-indicator-on-global-module t)
(remove-hook 'erc-insert-pre-hook #'erc-keep-place t)
(kill-local-variable 'erc--keep-place-indicator-overlay))
'local)
(defun erc--keep-place-indicator-on-global-module ()
"Ensure `keep-place-indicator' can cope with `erc-keep-place-mode'.
That is, ensure the local module can survive a user toggling the
global one."
(if erc-keep-place-mode
(remove-hook 'erc-insert-pre-hook #'erc-keep-place t)
(add-hook 'erc-insert-pre-hook #'erc-keep-place 65 t)))
"Ensure `keep-place-indicator' survives toggling `erc-keep-place-mode'.
Do this by simulating `keep-place' in all buffers where
`keep-place-indicator' is enabled."
(erc-with-all-buffers-of-server nil (lambda () erc-keep-place-indicator-mode)
(if erc-keep-place-mode
(remove-hook 'erc-insert-pre-hook #'erc-keep-place t)
(add-hook 'erc-insert-pre-hook #'erc-keep-place 65 t))))
(defun erc-keep-place-move (pos)
"Move keep-place indicator to current line or POS.

View File

@ -251,15 +251,16 @@
(defun erc-goodies-tests--assert-kp-indicator-on ()
(should erc--keep-place-indicator-overlay)
(should (local-variable-p 'window-buffer-change-functions))
(should window-configuration-change-hook)
(should (memq 'erc--keep-place-indicator-on-window-buffer-change
window-buffer-change-functions))
(should (memq 'erc-keep-place erc-insert-pre-hook))
(should (eq erc-keep-place-mode
(not (local-variable-p 'erc-insert-pre-hook)))))
(defun erc-goodies-tests--assert-kp-indicator-off ()
(should-not (local-variable-p 'erc-insert-pre-hook))
(should-not (local-variable-p 'window-buffer-change-functions))
(should-not (memq 'erc--keep-place-indicator-on-window-buffer-change
window-buffer-change-functions))
(should-not erc--keep-place-indicator-overlay))
(defun erc-goodies-tests--kp-indicator-populate ()
@ -272,12 +273,9 @@
(goto-char erc-input-marker))
(defun erc-goodies-tests--keep-place-indicator (test)
(with-current-buffer (get-buffer-create "*erc-keep-place-indicator-mode*")
(erc-mode)
(erc--initialize-markers (point) nil)
(setq erc-server-process
(start-process "sleep" (current-buffer) "sleep" "1"))
(set-process-query-on-exit-flag erc-server-process nil)
(erc-keep-place-mode -1)
(with-current-buffer (erc-tests-common-make-server-buf
"*erc-keep-place-indicator-mode*")
(let (erc-connect-pre-hook
erc-modules)
@ -294,7 +292,7 @@
(should-not (member 'erc-keep-place
(default-value 'erc-insert-pre-hook)))
(should-not (local-variable-p 'erc-insert-pre-hook))
(kill-buffer))))
(erc-tests-common-kill-buffers))))
(ert-deftest erc-keep-place-indicator-mode--no-global ()
(erc-goodies-tests--keep-place-indicator