diff options
| author | F. Jason Park | 2023-01-14 19:05:59 -0800 |
|---|---|---|
| committer | F. Jason Park | 2023-04-08 14:23:51 -0700 |
| commit | 0d3ccdbde441a0eed5d80d64aea429bc9a6457a3 (patch) | |
| tree | 1d21e0fa19796fa886668f64832779835b76a930 | |
| parent | 2d876a4ca94d7c74339eb18ca98528d017cab2a8 (diff) | |
| download | emacs-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.el | 1 | ||||
| -rw-r--r-- | lisp/erc/erc-common.el | 38 | ||||
| -rw-r--r-- | test/lisp/erc/erc-tests.el | 37 |
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, | |||
| 163 | and disable it otherwise. If called from Lisp, enable the mode | 193 | and disable it otherwise. If called from Lisp, enable the mode |
| 164 | if ARG is omitted or nil. | 194 | if 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 | |||
| 1453 | if ARG is omitted or nil. | 1486 | if ARG is omitted or nil. |
| 1454 | Some docstring" | 1487 | Some 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 | |||
| 1499 | if ARG is omitted or nil. | 1532 | if ARG is omitted or nil. |
| 1500 | Some docstring" | 1533 | Some 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))) |