diff options
Diffstat (limited to 'lisp/erc/erc-common.el')
-rw-r--r-- | lisp/erc/erc-common.el | 82 |
1 files changed, 68 insertions, 14 deletions
diff --git a/lisp/erc/erc-common.el b/lisp/erc/erc-common.el index 23a19337986..a4046ba9b39 100644 --- a/lisp/erc/erc-common.el +++ b/lisp/erc/erc-common.el @@ -88,6 +88,65 @@ (contents "" :type string) (tags '() :type list)) +;; TODO move goodies modules here after 29 is released. +(defconst erc--features-to-modules + '((erc-pcomplete completion pcomplete) + (erc-capab capab-identify) + (erc-join autojoin) + (erc-page page ctcp-page) + (erc-sound sound ctcp-sound) + (erc-stamp stamp timestamp) + (erc-services services nickserv)) + "Migration alist mapping a library feature to module names. +Keys need not be unique: a library may define more than one +module. Sometimes a module's downcased alias will be its +canonical name.") + +(defconst erc--modules-to-features + (let (pairs) + (pcase-dolist (`(,feature . ,names) erc--features-to-modules) + (dolist (name names) + (push (cons name feature) pairs))) + (nreverse pairs)) + "Migration alist mapping a module's name to its home library feature.") + +(defconst erc--module-name-migrations + (let (pairs) + (pcase-dolist (`(,_ ,canonical . ,rest) erc--features-to-modules) + (dolist (obsolete rest) + (push (cons obsolete canonical) pairs))) + pairs) + "Association list of obsolete module names to canonical names.") + +(defun erc--normalize-module-symbol (symbol) + "Return preferred SYMBOL for `erc-modules'." + (setq symbol (intern (downcase (symbol-name symbol)))) + (or (cdr (assq symbol erc--module-name-migrations)) symbol)) + +(defun erc--assemble-toggle (localp name ablsym mode val body) + (let ((arg (make-symbol "arg"))) + `(defun ,ablsym ,(if localp `(&optional ,arg) '()) + ,(concat + (if val "Enable" "Disable") + " ERC " (symbol-name name) " mode." + (when localp + "\nWith ARG, do so in all buffers for the current connection.")) + (interactive ,@(when localp '("p"))) + ,@(if localp + `((when (derived-mode-p 'erc-mode) + (if ,arg + (erc-with-all-buffers-of-server erc-server-process nil + (,ablsym)) + (setq ,mode ,val) + ,@body))) + `(,(if val + `(cl-pushnew ',(erc--normalize-module-symbol name) + erc-modules) + `(setq erc-modules (delq ',(erc--normalize-module-symbol name) + erc-modules))) + (setq ,mode ,val) + ,@body))))) + (defmacro define-erc-module (name alias doc enable-body disable-body &optional local-p) "Define a new minor mode using ERC conventions. @@ -103,6 +162,13 @@ This will define a minor mode called erc-NAME-mode, possibly an alias erc-ALIAS-mode, as well as the helper functions erc-NAME-enable, and erc-NAME-disable. +With LOCAL-P, these helpers take on an optional argument that, +when non-nil, causes them to act on all buffers of a connection. +This feature is mainly intended for interactive use and does not +carry over to their respective minor-mode toggles. Beware that +for global modules, these helpers and toggles all mutate +`erc-modules'. + Example: ;;;###autoload(autoload \\='erc-replace-mode \"erc-replace\") @@ -133,20 +199,8 @@ if ARG is omitted or nil. (if ,mode (,enable) (,disable))) - (defun ,enable () - ,(format "Enable ERC %S mode." - name) - (interactive) - (add-to-list 'erc-modules (quote ,name)) - (setq ,mode t) - ,@enable-body) - (defun ,disable () - ,(format "Disable ERC %S mode." - name) - (interactive) - (setq erc-modules (delq (quote ,name) erc-modules)) - (setq ,mode nil) - ,@disable-body) + ,(erc--assemble-toggle local-p name enable mode t enable-body) + ,(erc--assemble-toggle local-p name disable mode nil disable-body) ,(when (and alias (not (eq name alias))) `(defalias ',(intern |