1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-27 07:37:33 +00:00

Make some module toggles more resilient in ERC

* lisp/erc/erc-goodies.el (erc-scrolltobottom-mode,
erc-scrolltobottom-enable, erc-move-to-prompt-mode,
erc-move-to-prompt-enable): Guard setup procedure behind
`erc--updating-modules-p'.
* lisp/erc/erc-imenu.el (erc-imenu-mode, erc-imenu-enable,
erc-imenu-disable): Don't run setup when `erc--updating-modules-p' is
non-nil.  Also, don't restrict teardown to buffers of the same
process.
* lisp/erc/erc-match.el (erc-match-mode, erc-match-enable): Run
major-mode hook member immediately outside of `erc-update-modules' in
`erc-open'.
* lisp/erc/erc-spelling.el (erc-spelling-mode, erc-spelling-enable):
Only conditionally run setup immediately.
* lisp/erc/erc-stamp.el (erc-stamp-mode, erc-stamp-enable,
erc-stamp-disable): Run setup hook immediately.  Don't forget to
kill local vars in all ERC buffers during teardown.
* lisp/erc/erc.el (erc--updating-modules-p): New variable that global
modules can use to provide their `erc-mode-hook'-deferred code on
demand while shielding it from running during early ERC buffer
initialization.
(erc-open): Make `erc--updating-modules-p' non-nil while activating
global modules.  (Bug#60936)
This commit is contained in:
F. Jason Park 2023-05-07 19:43:57 -07:00
parent 75a412d78b
commit 867b104010
6 changed files with 42 additions and 13 deletions

View File

@ -53,9 +53,8 @@ argument to `recenter'."
"This mode causes the prompt to stay at the end of the window."
((add-hook 'erc-mode-hook #'erc-add-scroll-to-bottom)
(add-hook 'erc-insert-done-hook #'erc-possibly-scroll-to-bottom)
(dolist (buffer (erc-buffer-list))
(with-current-buffer buffer
(erc-add-scroll-to-bottom))))
(unless erc--updating-modules-p
(erc-buffer-filter #'erc-add-scroll-to-bottom)))
((remove-hook 'erc-mode-hook #'erc-add-scroll-to-bottom)
(remove-hook 'erc-insert-done-hook #'erc-possibly-scroll-to-bottom)
(dolist (buffer (erc-buffer-list))
@ -120,9 +119,8 @@ Put this function on `erc-insert-post-hook' and/or `erc-send-post-hook'."
(define-erc-module move-to-prompt nil
"This mode causes the point to be moved to the prompt when typing text."
((add-hook 'erc-mode-hook #'erc-move-to-prompt-setup)
(dolist (buffer (erc-buffer-list))
(with-current-buffer buffer
(erc-move-to-prompt-setup))))
(unless erc--updating-modules-p
(erc-buffer-filter #'erc-move-to-prompt-setup)))
((remove-hook 'erc-mode-hook #'erc-move-to-prompt-setup)
(dolist (buffer (erc-buffer-list))
(with-current-buffer buffer

View File

@ -138,9 +138,10 @@ Don't rely on this function, read it first!"
;;;###autoload(autoload 'erc-imenu-mode "erc-imenu" nil t)
(define-erc-module imenu nil
"Simple Imenu integration for ERC."
((add-hook 'erc-mode-hook #'erc-imenu-setup))
((add-hook 'erc-mode-hook #'erc-imenu-setup)
(unless erc--updating-modules-p (erc-buffer-filter #'erc-imenu-setup)))
((remove-hook 'erc-mode-hook #'erc-imenu-setup)
(erc-with-all-buffers-of-server erc-server-process nil
(erc-with-all-buffers-of-server nil nil
(when erc-imenu--create-index-function
(setq imenu-create-index-function erc-imenu--create-index-function)
(kill-local-variable 'erc-imenu--create-index-function)))))

View File

@ -54,6 +54,8 @@ you can decide whether the entire message or only the sending nick is
highlighted."
((add-hook 'erc-insert-modify-hook #'erc-match-message 'append)
(add-hook 'erc-mode-hook #'erc-match--modify-invisibility-spec)
(unless erc--updating-modules-p
(erc-buffer-filter #'erc-match--modify-invisibility-spec))
(erc--modify-local-map t "C-c C-k" #'erc-go-to-log-matches-buffer))
((remove-hook 'erc-insert-modify-hook #'erc-match-message)
(remove-hook 'erc-mode-hook #'erc-match--modify-invisibility-spec)

View File

@ -39,8 +39,9 @@
;; Use erc-connect-pre-hook instead of erc-mode-hook as pre-hook is
;; called AFTER the server buffer is initialized.
((add-hook 'erc-connect-pre-hook #'erc-spelling-init)
(dolist (buffer (erc-buffer-list))
(erc-spelling-init buffer)))
(unless erc--updating-modules-p
(erc-with-all-buffers-of-server nil nil
(erc-spelling-init (current-buffer)))))
((remove-hook 'erc-connect-pre-hook #'erc-spelling-init)
(dolist (buffer (erc-buffer-list))
(with-current-buffer buffer (flyspell-mode 0)))))

View File

@ -165,11 +165,17 @@ from entering them and instead jump over them."
((add-hook 'erc-mode-hook #'erc-munge-invisibility-spec)
(add-hook 'erc-insert-modify-hook #'erc-add-timestamp t)
(add-hook 'erc-send-modify-hook #'erc-add-timestamp t)
(add-hook 'erc-mode-hook #'erc-stamp--recover-on-reconnect))
(add-hook 'erc-mode-hook #'erc-stamp--recover-on-reconnect)
(unless erc--updating-modules-p
(erc-buffer-filter #'erc-munge-invisibility-spec)))
((remove-hook 'erc-mode-hook #'erc-munge-invisibility-spec)
(remove-hook 'erc-insert-modify-hook #'erc-add-timestamp)
(remove-hook 'erc-send-modify-hook #'erc-add-timestamp)
(remove-hook 'erc-mode-hook #'erc-stamp--recover-on-reconnect)))
(remove-hook 'erc-mode-hook #'erc-stamp--recover-on-reconnect)
(erc-with-all-buffers-of-server nil nil
(kill-local-variable 'erc-timestamp-last-inserted)
(kill-local-variable 'erc-timestamp-last-inserted-left)
(kill-local-variable 'erc-timestamp-last-inserted-right))))
(defun erc-stamp--recover-on-reconnect ()
(when-let ((priors (or erc--server-reconnecting erc--target-priors)))

View File

@ -2084,6 +2084,26 @@ Except ignore all local modules, which were introduced in ERC 5.5."
(push mode local-modes))
(error "`%s' is not a known ERC module" module)))))
(defvar erc--updating-modules-p nil
"Non-nil when running `erc--update-modules' in `erc-open'.
This allows global modules with known or likely dependents (or
some other reason for activating after session initialization) to
conditionally run setup code traditionally reserved for
`erc-mode-hook' in the setup portion of their mode toggle. Note
that being \"global\", they'll likely want to do so in all ERC
buffers and ensure the code is idempotent. For example:
(add-hook \\='erc-mode-hook #\\='erc-foo-setup-fn)
(unless erc--updating-modules-p
(erc-with-all-buffers-of-server nil
(lambda () some-condition-p)
(erc-foo-setup-fn)))
This means that when a dependent module is initializing and
realizes it's missing some required module \"foo\", it can
confidently call (erc-foo-mode 1) without having to learn
anything about the dependency's implementation.")
(defun erc--setup-buffer-first-window (frame a b)
(catch 'found
(walk-window-tree
@ -2243,7 +2263,8 @@ Returns the buffer for the given server or channel."
(set-buffer buffer)
(setq old-point (point))
(setq delayed-modules
(erc--merge-local-modes (erc--update-modules)
(erc--merge-local-modes (let ((erc--updating-modules-p t))
(erc--update-modules))
(or erc--server-reconnecting
erc--target-priors)))