diff options
author | F. Jason Park <jp@neverwas.me> | 2023-05-07 19:43:57 -0700 |
---|---|---|
committer | F. Jason Park <jp@neverwas.me> | 2023-05-13 07:05:22 -0700 |
commit | 867b104010760c4b7cd700078884cc774a01860a (patch) | |
tree | 60e980b56bfb33169d792422ebf985c89bd8680e | |
parent | 75a412d78b6f4b4b68a7c649047cd28320110c09 (diff) | |
download | emacs-867b104010760c4b7cd700078884cc774a01860a.tar.gz |
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)
-rw-r--r-- | lisp/erc/erc-goodies.el | 10 | ||||
-rw-r--r-- | lisp/erc/erc-imenu.el | 5 | ||||
-rw-r--r-- | lisp/erc/erc-match.el | 2 | ||||
-rw-r--r-- | lisp/erc/erc-spelling.el | 5 | ||||
-rw-r--r-- | lisp/erc/erc-stamp.el | 10 | ||||
-rw-r--r-- | lisp/erc/erc.el | 23 |
6 files changed, 42 insertions, 13 deletions
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el index 4558ff7c076..01eae4b63c5 100644 --- a/lisp/erc/erc-goodies.el +++ b/lisp/erc/erc-goodies.el @@ -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 diff --git a/lisp/erc/erc-imenu.el b/lisp/erc/erc-imenu.el index 526afd32249..9864d7c4042 100644 --- a/lisp/erc/erc-imenu.el +++ b/lisp/erc/erc-imenu.el @@ -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))))) diff --git a/lisp/erc/erc-match.el b/lisp/erc/erc-match.el index c08a640260c..86883260413 100644 --- a/lisp/erc/erc-match.el +++ b/lisp/erc/erc-match.el @@ -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) diff --git a/lisp/erc/erc-spelling.el b/lisp/erc/erc-spelling.el index 8fce2508ceb..8e5424f4162 100644 --- a/lisp/erc/erc-spelling.el +++ b/lisp/erc/erc-spelling.el @@ -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))))) diff --git a/lisp/erc/erc-stamp.el b/lisp/erc/erc-stamp.el index f90a8fc50b1..9191bbe5a2a 100644 --- a/lisp/erc/erc-stamp.el +++ b/lisp/erc/erc-stamp.el @@ -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))) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 5738ee92578..a104d7ad542 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -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))) |