emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 867b1040107 3/3: Make some module toggles more resilient in ERC


From: F. Jason Park
Subject: master 867b1040107 3/3: Make some module toggles more resilient in ERC
Date: Sat, 13 May 2023 10:08:39 -0400 (EDT)

branch: master
commit 867b104010760c4b7cd700078884cc774a01860a
Author: F. Jason Park <jp@neverwas.me>
Commit: F. Jason Park <jp@neverwas.me>

    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)
---
 lisp/erc/erc-goodies.el  | 10 ++++------
 lisp/erc/erc-imenu.el    |  5 +++--
 lisp/erc/erc-match.el    |  2 ++
 lisp/erc/erc-spelling.el |  5 +++--
 lisp/erc/erc-stamp.el    | 10 ++++++++--
 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)))
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]