aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorF. Jason Park2023-01-14 19:05:59 -0800
committerF. Jason Park2023-04-08 14:23:51 -0700
commit0d3ccdbde441a0eed5d80d64aea429bc9a6457a3 (patch)
tree1d21e0fa19796fa886668f64832779835b76a930
parent2d876a4ca94d7c74339eb18ca98528d017cab2a8 (diff)
downloademacs-0d3ccdbde441a0eed5d80d64aea429bc9a6457a3.tar.gz
emacs-0d3ccdbde441a0eed5d80d64aea429bc9a6457a3.zip
Don't associate ERC modules with undefined groups
* lisp/erc/erc-capab.el: Add property crutch to help ERC find module's Custom group. * lisp/erc/erc-common.el (erc--find-group): Add new function, a helper for finding an existing ERC module's Custom group based on `define-erc-module' params. Prefer `group-documentation' as a sentinel over symbol properties owned by Customize because they might not be present if the group isn't yet associated with any custom variables. (define-erc-module): Set `:group' keyword value more accurately, falling back to `erc' when no associated group has been defined. * test/lisp/erc/erc-tests.el (erc--find-group, erc--find-group--real): New tests. (define-erc-module--global, define-erc-module--local): Expect the `:group' keyword to be the unevaluated `erc--find-group' form. (Bug#60935.)
-rw-r--r--lisp/erc/erc-capab.el1
-rw-r--r--lisp/erc/erc-common.el38
-rw-r--r--test/lisp/erc/erc-tests.el37
3 files changed, 69 insertions, 7 deletions
diff --git a/lisp/erc/erc-capab.el b/lisp/erc/erc-capab.el
index 650c5fa84ac..bb0921da7f0 100644
--- a/lisp/erc/erc-capab.el
+++ b/lisp/erc/erc-capab.el
@@ -89,6 +89,7 @@ character not found in IRC nicknames to avoid confusion."
89;;; Define module: 89;;; Define module:
90 90
91;;;###autoload(autoload 'erc-capab-identify-mode "erc-capab" nil t) 91;;;###autoload(autoload 'erc-capab-identify-mode "erc-capab" nil t)
92(put 'capab-identify 'erc-group 'erc-capab)
92(define-erc-module capab-identify nil 93(define-erc-module capab-identify nil
93 "Handle dancer-ircd's CAPAB IDENTIFY-MSG and IDENTIFY-CTCP." 94 "Handle dancer-ircd's CAPAB IDENTIFY-MSG and IDENTIFY-CTCP."
94 ;; append so that `erc-server-parameters' is already set by `erc-server-005' 95 ;; append so that `erc-server-parameters' is already set by `erc-server-005'
diff --git a/lisp/erc/erc-common.el b/lisp/erc/erc-common.el
index b8f6a06b76c..91ddce8fbd9 100644
--- a/lisp/erc/erc-common.el
+++ b/lisp/erc/erc-common.el
@@ -118,6 +118,37 @@
118 (setq ,mode ,val) 118 (setq ,mode ,val)
119 ,@body))))) 119 ,@body)))))
120 120
121;; This is a migration helper that determines a module's `:group'
122;; keyword argument from its name or alias. A (global) module's minor
123;; mode variable appears under the group's Custom menu. Like
124;; `erc--normalize-module-symbol', it must run when the module's
125;; definition (rather than that of `define-erc-module') is expanded.
126;; For corner cases in which this fails or the catch-all of `erc' is
127;; more inappropriate, (global) modules can declare a top-level
128;;
129;; (put 'foo 'erc-group 'erc-bar)
130;;
131;; where `erc-bar' is the group and `foo' is the normalized module.
132;; Do this *before* the module's definition. If `define-erc-module'
133;; ever accepts arbitrary keywords, passing an explicit `:group' will
134;; obviously be preferable.
135
136(defun erc--find-group (&rest symbols)
137 (catch 'found
138 (dolist (s symbols)
139 (let* ((downed (downcase (symbol-name s)))
140 (known (intern-soft (concat "erc-" downed))))
141 (when (and known
142 (or (get known 'group-documentation)
143 (rassq known custom-current-group-alist)))
144 (throw 'found known))
145 (when (setq known (intern-soft (concat "erc-" downed "-mode")))
146 (when-let ((found (custom-group-of-mode known)))
147 (throw 'found found))))
148 (when-let ((found (get (erc--normalize-module-symbol s) 'erc-group)))
149 (throw 'found found)))
150 'erc))
151
121(defmacro define-erc-module (name alias doc enable-body disable-body 152(defmacro define-erc-module (name alias doc enable-body disable-body
122 &optional local-p) 153 &optional local-p)
123 "Define a new minor mode using ERC conventions. 154 "Define a new minor mode using ERC conventions.
@@ -152,7 +183,6 @@ Example:
152 (declare (doc-string 3) (indent defun)) 183 (declare (doc-string 3) (indent defun))
153 (let* ((sn (symbol-name name)) 184 (let* ((sn (symbol-name name))
154 (mode (intern (format "erc-%s-mode" (downcase sn)))) 185 (mode (intern (format "erc-%s-mode" (downcase sn))))
155 (group (intern (format "erc-%s" (downcase sn))))
156 (enable (intern (format "erc-%s-enable" (downcase sn)))) 186 (enable (intern (format "erc-%s-enable" (downcase sn))))
157 (disable (intern (format "erc-%s-disable" (downcase sn))))) 187 (disable (intern (format "erc-%s-disable" (downcase sn)))))
158 `(progn 188 `(progn
@@ -163,10 +193,8 @@ With a prefix argument ARG, enable %s if ARG is positive,
163and disable it otherwise. If called from Lisp, enable the mode 193and disable it otherwise. If called from Lisp, enable the mode
164if ARG is omitted or nil. 194if ARG is omitted or nil.
165%s" name name doc) 195%s" name name doc)
166 ;; FIXME: We don't know if this group exists, so this `:group' may 196 :global ,(not local-p)
167 ;; actually just silence a valid warning about the fact that the var 197 :group (erc--find-group ',name ,(and alias (list 'quote alias)))
168 ;; is not associated with any group.
169 :global ,(not local-p) :group (quote ,group)
170 (if ,mode 198 (if ,mode
171 (,enable) 199 (,enable)
172 (,disable))) 200 (,disable)))
diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el
index acd470a1e17..45d8cae5125 100644
--- a/test/lisp/erc/erc-tests.el
+++ b/test/lisp/erc/erc-tests.el
@@ -1353,6 +1353,39 @@
1353 ;; Default unchanged 1353 ;; Default unchanged
1354 (should (equal (erc-migrate-modules erc-modules) erc-modules))) 1354 (should (equal (erc-migrate-modules erc-modules) erc-modules)))
1355 1355
1356(ert-deftest erc--find-group ()
1357 ;; These two are loaded by default
1358 (should (eq (erc--find-group 'keep-place nil) 'erc))
1359 (should (eq (erc--find-group 'networks nil) 'erc-networks))
1360 ;; These are fake
1361 (cl-letf (((get 'erc-bar 'group-documentation) "")
1362 ((get 'baz 'erc-group) 'erc-foo))
1363 (should (eq (erc--find-group 'foo 'bar) 'erc-bar))
1364 (should (eq (erc--find-group 'bar 'foo) 'erc-bar))
1365 (should (eq (erc--find-group 'bar nil) 'erc-bar))
1366 (should (eq (erc--find-group 'foo nil) 'erc))
1367 (should (eq (erc--find-group 'fake 'baz) 'erc-foo))))
1368
1369(ert-deftest erc--find-group--real ()
1370 :tags '(:unstable)
1371 (require 'erc-services)
1372 (require 'erc-stamp)
1373 (require 'erc-sound)
1374 (require 'erc-page)
1375 (require 'erc-join)
1376 (require 'erc-capab)
1377 (require 'erc-pcomplete)
1378 (should (eq (erc--find-group 'services 'nickserv) 'erc-services))
1379 (should (eq (erc--find-group 'stamp 'timestamp) 'erc-stamp))
1380 (should (eq (erc--find-group 'sound 'ctcp-sound) 'erc-sound))
1381 (should (eq (erc--find-group 'page 'ctcp-page) 'erc-page))
1382 (should (eq (erc--find-group 'autojoin) 'erc-autojoin))
1383 (should (eq (erc--find-group 'pcomplete 'Completion) 'erc-pcomplete))
1384 (should (eq (erc--find-group 'capab-identify) 'erc-capab))
1385 ;; No group specified.
1386 (should (eq (erc--find-group 'smiley nil) 'erc))
1387 (should (eq (erc--find-group 'unmorse nil) 'erc)))
1388
1356(ert-deftest erc--update-modules () 1389(ert-deftest erc--update-modules ()
1357 (let (calls 1390 (let (calls
1358 erc-modules 1391 erc-modules
@@ -1453,7 +1486,7 @@ and disable it otherwise. If called from Lisp, enable the mode
1453if ARG is omitted or nil. 1486if ARG is omitted or nil.
1454Some docstring" 1487Some docstring"
1455 :global t 1488 :global t
1456 :group 'erc-mname 1489 :group (erc--find-group 'mname 'malias)
1457 (if erc-mname-mode 1490 (if erc-mname-mode
1458 (erc-mname-enable) 1491 (erc-mname-enable)
1459 (erc-mname-disable))) 1492 (erc-mname-disable)))
@@ -1499,7 +1532,7 @@ and disable it otherwise. If called from Lisp, enable the mode
1499if ARG is omitted or nil. 1532if ARG is omitted or nil.
1500Some docstring" 1533Some docstring"
1501 :global nil 1534 :global nil
1502 :group 'erc-mname 1535 :group (erc--find-group 'mname nil)
1503 (if erc-mname-mode 1536 (if erc-mname-mode
1504 (erc-mname-enable) 1537 (erc-mname-enable)
1505 (erc-mname-disable))) 1538 (erc-mname-disable)))