From: "J.P." <jp@neverwas.me>
To: 60935@debbugs.gnu.org
Cc: emacs-erc@gnu.org
Subject: bug#60935: 30.0.50; ERC >5.5: Improve ERC's treatment of customization groups
Date: Tue, 07 Feb 2023 07:23:04 -0800 [thread overview]
Message-ID: <87sffh8ppj.fsf__16167.6958364964$1675783468$gmane$org@neverwas.me> (raw)
In-Reply-To: <87v8l3aod4.fsf@neverwas.me> (J. P.'s message of "Wed, 18 Jan 2023 06:50:15 -0800")
[-- Attachment #1: Type: text/plain, Size: 105 bytes --]
v2. Use autoloads for resolving groups in corner cases. Don't change
decades-old preferred module name.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0000-v1-v2.diff --]
[-- Type: text/x-patch, Size: 6867 bytes --]
From e4e270a4bf556ce238bc42c8549d4c443f3a969a Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Tue, 7 Feb 2023 00:08:34 -0800
Subject: [PATCH 0/3] *** NOT A PATCH ***
*** BLURB HERE ***
F. Jason Park (3):
[5.6] Don't associate ERC modules with undefined groups
[5.6] Warn when setting minor-mode vars for ERC modules
[5.6] Fill doc strings for ERC modules.
lisp/erc/erc-capab.el | 1 +
lisp/erc/erc-common.el | 136 +++++++++++++++++++++++++++++++++----
lisp/erc/erc.el | 3 +-
test/lisp/erc/erc-tests.el | 78 ++++++++++++++++-----
4 files changed, 187 insertions(+), 31 deletions(-)
Interdiff:
diff --git a/lisp/erc/erc-capab.el b/lisp/erc/erc-capab.el
index 25cdea9e777..bb0921da7f0 100644
--- a/lisp/erc/erc-capab.el
+++ b/lisp/erc/erc-capab.el
@@ -89,7 +89,8 @@ erc-capab-identify-unidentified
;;; Define module:
;;;###autoload(autoload 'erc-capab-identify-mode "erc-capab" nil t)
-(define-erc-module capab-identify capab
+(put 'capab-identify 'erc-group 'erc-capab)
+(define-erc-module capab-identify nil
"Handle dancer-ircd's CAPAB IDENTIFY-MSG and IDENTIFY-CTCP."
;; append so that `erc-server-parameters' is already set by `erc-server-005'
((add-hook 'erc-server-005-functions #'erc-capab-identify-setup t)
diff --git a/lisp/erc/erc-common.el b/lisp/erc/erc-common.el
index f488244ef9c..cc278428d5d 100644
--- a/lisp/erc/erc-common.el
+++ b/lisp/erc/erc-common.el
@@ -97,7 +97,7 @@ erc--target
;; TODO move goodies modules here after 29 is released.
(defconst erc--features-to-modules
'((erc-pcomplete completion pcomplete)
- (erc-capab capab capab-identify)
+ (erc-capab capab-identify)
(erc-join autojoin)
(erc-page page ctcp-page)
(erc-sound sound ctcp-sound)
@@ -173,23 +173,27 @@ erc--assemble-toggle
;; For corner cases where this fails and where the catch-all of `erc'
;; is inappropriate, (global) modules can declare a top-level
;;
-;; (custom-add-to-group 'erc-foo 'erc-bar-mode 'custom-variable)
+;; (put 'foo 'erc-group 'erc-bar)
;;
-;; *before* the module's definition. If `define-erc-module' ever
-;; accepts arbitrary keywords, passing an explicit `:group' will
+;; where `erc-bar' is the group and `foo' is the normalized module.
+;; Do this *before* the module's definition. If `define-erc-module'
+;; ever accepts arbitrary keywords, passing an explicit `:group' will
;; obviously be preferable.
(defun erc--find-group (&rest symbols)
(catch 'found
- (while symbols
- (when-let* ((s (pop symbols))
- (downed (concat "erc-" (downcase (symbol-name s))))
- (known (intern-soft downed)))
- (when-let ((found (custom-group-of-mode known)))
- (throw 'found found))
- (when (or (get known 'group-documentation)
- (rassq known custom-current-group-alist))
- (throw 'found known))))
+ (dolist (s symbols)
+ (let* ((downed (downcase (symbol-name s)))
+ (known (intern-soft (concat "erc-" downed))))
+ (when (and known
+ (or (get known 'group-documentation)
+ (rassq known custom-current-group-alist)))
+ (throw 'found known))
+ (when (setq known (intern-soft (concat "erc-" downed "-mode")))
+ (when-let ((found (custom-group-of-mode known)))
+ (throw 'found found))))
+ (when-let ((found (get (erc--normalize-module-symbol s) 'erc-group)))
+ (throw 'found found)))
'erc))
(defun erc--custom-set-minor-mode (variable value)
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index 70ba82fd4bf..5e971f15f5d 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -1854,9 +1854,10 @@ erc-modules
(const :tag "autojoin: Join channels automatically" autojoin)
(const :tag "button: Buttonize URLs, nicknames, and other text" button)
(const :tag "capab: Mark unidentified users on servers supporting CAPAB"
- capab)
+ capab-identify)
(const :tag "completion: Complete nicknames and commands (programmable)"
completion)
+ (const :tag "hecomplete: Complete nicknames and commands (obsolete, use \"completion\")" hecomplete)
(const :tag "dcc: Provide Direct Client-to-Client support" dcc)
(const :tag "fill: Wrap long lines" fill)
(const :tag "identd: Launch an identd server on port 8113" identd)
diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el
index 703b26dcea0..e5db78ef2e1 100644
--- a/test/lisp/erc/erc-tests.el
+++ b/test/lisp/erc/erc-tests.el
@@ -1214,29 +1214,33 @@ erc--find-group
(should (eq (erc--find-group 'keep-place nil) 'erc))
(should (eq (erc--find-group 'networks nil) 'erc-networks))
;; These are fake
- (cl-letf (((get 'erc-bar 'group-documentation) ""))
+ (cl-letf (((get 'erc-bar 'group-documentation) "")
+ ((get 'baz 'erc-group) 'erc-foo))
(should (eq (erc--find-group 'foo 'bar) 'erc-bar))
(should (eq (erc--find-group 'bar 'foo) 'erc-bar))
(should (eq (erc--find-group 'bar nil) 'erc-bar))
- (should (eq (erc--find-group 'foo nil) 'erc))))
+ (should (eq (erc--find-group 'foo nil) 'erc))
+ (should (eq (erc--find-group 'fake 'baz) 'erc-foo))))
(ert-deftest erc--find-group--real ()
:tags '(:unstable)
- (let (out)
- (pcase-dolist (`(,feat . ,syms) erc--features-to-modules)
- (require feat)
- (push (cons syms (apply #'erc--find-group syms)) out))
- ;; Remove local modules, which are mapped to the catch-all
- (while (and-let* ((m (rassq 'erc out))) ; while-let
- (setq out (remq m out))))
- (should (equal out
- '(((services nickserv) . erc-services)
- ((stamp timestamp) . erc-stamp)
- ((sound ctcp-sound) . erc-sound)
- ((page ctcp-page) . erc-page)
- ((autojoin) . erc-autojoin)
- ((capab capab-identify) . erc-capab)
- ((completion pcomplete) . erc-pcomplete))))))
+ (require 'erc-services)
+ (require 'erc-stamp)
+ (require 'erc-sound)
+ (require 'erc-page)
+ (require 'erc-join)
+ (require 'erc-capab)
+ (require 'erc-pcomplete)
+ (should (eq (erc--find-group 'services 'nickserv) 'erc-services))
+ (should (eq (erc--find-group 'stamp 'timestamp) 'erc-stamp))
+ (should (eq (erc--find-group 'sound 'ctcp-sound) 'erc-sound))
+ (should (eq (erc--find-group 'page 'ctcp-page) 'erc-page))
+ (should (eq (erc--find-group 'autojoin) 'erc-autojoin))
+ (should (eq (erc--find-group 'pcomplete 'Completion) 'erc-pcomplete))
+ (should (eq (erc--find-group 'capab-identify) 'erc-capab))
+ ;; No group specified.
+ (should (eq (erc--find-group 'smiley nil) 'erc))
+ (should (eq (erc--find-group 'unmorse nil) 'erc)))
(ert-deftest erc--update-modules ()
(let (calls
--
2.39.1
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0001-5.6-Don-t-associate-ERC-modules-with-undefined-group.patch --]
[-- Type: text/x-patch, Size: 7148 bytes --]
From 380ea8edc391aa75be9b7c7019bfc8c3db57e4f4 Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Sat, 14 Jan 2023 19:05:59 -0800
Subject: [PATCH 1/3] [5.6] 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 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' group 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.)
---
lisp/erc/erc-capab.el | 1 +
lisp/erc/erc-common.el | 38 +++++++++++++++++++++++++++++++++-----
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 @@ erc-capab-identify-unidentified
;;; Define module:
;;;###autoload(autoload 'erc-capab-identify-mode "erc-capab" nil t)
+(put 'capab-identify 'erc-group 'erc-capab)
(define-erc-module capab-identify nil
"Handle dancer-ircd's CAPAB IDENTIFY-MSG and IDENTIFY-CTCP."
;; 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 994555acecf..bf3bce74cfd 100644
--- a/lisp/erc/erc-common.el
+++ b/lisp/erc/erc-common.el
@@ -148,6 +148,37 @@ erc--assemble-toggle
(setq ,mode ,val)
,@body)))))
+;; This is a migration helper that determines a module's `:group'
+;; keyword argument from its name or alias. A (global) module's minor
+;; mode variable will appear under the group's Custom menu. Like
+;; `erc--normalize-module-symbol', it must run when the module's
+;; definition (rather than that of `define-erc-module') is expanded.
+;; For corner cases where this fails and where the catch-all of `erc'
+;; is inappropriate, (global) modules can declare a top-level
+;;
+;; (put 'foo 'erc-group 'erc-bar)
+;;
+;; where `erc-bar' is the group and `foo' is the normalized module.
+;; Do this *before* the module's definition. If `define-erc-module'
+;; ever accepts arbitrary keywords, passing an explicit `:group' will
+;; obviously be preferable.
+
+(defun erc--find-group (&rest symbols)
+ (catch 'found
+ (dolist (s symbols)
+ (let* ((downed (downcase (symbol-name s)))
+ (known (intern-soft (concat "erc-" downed))))
+ (when (and known
+ (or (get known 'group-documentation)
+ (rassq known custom-current-group-alist)))
+ (throw 'found known))
+ (when (setq known (intern-soft (concat "erc-" downed "-mode")))
+ (when-let ((found (custom-group-of-mode known)))
+ (throw 'found found))))
+ (when-let ((found (get (erc--normalize-module-symbol s) 'erc-group)))
+ (throw 'found found)))
+ 'erc))
+
(defmacro define-erc-module (name alias doc enable-body disable-body
&optional local-p)
"Define a new minor mode using ERC conventions.
@@ -182,7 +213,6 @@ define-erc-module
(declare (doc-string 3) (indent defun))
(let* ((sn (symbol-name name))
(mode (intern (format "erc-%s-mode" (downcase sn))))
- (group (intern (format "erc-%s" (downcase sn))))
(enable (intern (format "erc-%s-enable" (downcase sn))))
(disable (intern (format "erc-%s-disable" (downcase sn)))))
`(progn
@@ -193,10 +223,8 @@ define-erc-module
and disable it otherwise. If called from Lisp, enable the mode
if ARG is omitted or nil.
%s" name name doc)
- ;; FIXME: We don't know if this group exists, so this `:group' may
- ;; actually just silence a valid warning about the fact that the var
- ;; is not associated with any group.
- :global ,(not local-p) :group (quote ,group)
+ :global ,(not local-p)
+ :group (erc--find-group ',name ,(and alias (list 'quote alias)))
(if ,mode
(,enable)
(,disable)))
diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el
index 40a2d2de657..24a4f9d0639 100644
--- a/test/lisp/erc/erc-tests.el
+++ b/test/lisp/erc/erc-tests.el
@@ -1209,6 +1209,39 @@ erc-migrate-modules
;; Default unchanged
(should (equal (erc-migrate-modules erc-modules) erc-modules)))
+(ert-deftest erc--find-group ()
+ ;; These two are loaded by default
+ (should (eq (erc--find-group 'keep-place nil) 'erc))
+ (should (eq (erc--find-group 'networks nil) 'erc-networks))
+ ;; These are fake
+ (cl-letf (((get 'erc-bar 'group-documentation) "")
+ ((get 'baz 'erc-group) 'erc-foo))
+ (should (eq (erc--find-group 'foo 'bar) 'erc-bar))
+ (should (eq (erc--find-group 'bar 'foo) 'erc-bar))
+ (should (eq (erc--find-group 'bar nil) 'erc-bar))
+ (should (eq (erc--find-group 'foo nil) 'erc))
+ (should (eq (erc--find-group 'fake 'baz) 'erc-foo))))
+
+(ert-deftest erc--find-group--real ()
+ :tags '(:unstable)
+ (require 'erc-services)
+ (require 'erc-stamp)
+ (require 'erc-sound)
+ (require 'erc-page)
+ (require 'erc-join)
+ (require 'erc-capab)
+ (require 'erc-pcomplete)
+ (should (eq (erc--find-group 'services 'nickserv) 'erc-services))
+ (should (eq (erc--find-group 'stamp 'timestamp) 'erc-stamp))
+ (should (eq (erc--find-group 'sound 'ctcp-sound) 'erc-sound))
+ (should (eq (erc--find-group 'page 'ctcp-page) 'erc-page))
+ (should (eq (erc--find-group 'autojoin) 'erc-autojoin))
+ (should (eq (erc--find-group 'pcomplete 'Completion) 'erc-pcomplete))
+ (should (eq (erc--find-group 'capab-identify) 'erc-capab))
+ ;; No group specified.
+ (should (eq (erc--find-group 'smiley nil) 'erc))
+ (should (eq (erc--find-group 'unmorse nil) 'erc)))
+
(ert-deftest erc--update-modules ()
(let (calls
erc-modules
@@ -1290,7 +1323,7 @@ define-erc-module--global
if ARG is omitted or nil.
Some docstring"
:global t
- :group 'erc-mname
+ :group (erc--find-group 'mname 'malias)
(if erc-mname-mode
(erc-mname-enable)
(erc-mname-disable)))
@@ -1336,7 +1369,7 @@ define-erc-module--local
if ARG is omitted or nil.
Some docstring"
:global nil
- :group 'erc-mname
+ :group (erc--find-group 'mname nil)
(if erc-mname-mode
(erc-mname-enable)
(erc-mname-disable)))
--
2.39.1
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0002-5.6-Warn-when-setting-minor-mode-vars-for-ERC-module.patch --]
[-- Type: text/x-patch, Size: 9563 bytes --]
From 84bdae341ec2e19ba45c6dd9547dc3a5db43cbea Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Sat, 14 Jan 2023 19:08:11 -0800
Subject: [PATCH 2/3] [5.6] Warn when setting minor-mode vars for ERC modules
(erc--inside-mode-toggle-p): Add global var to inhibit mode toggles
from being run by `erc-update-modules'. It must be non-nil inside
custom-set functions for mode toggles created by `define-erc-module'.
(erc--assemble-toggle): Don't modify `erc-modules' when run from
custom-set function.
(erc--custom-set-minor-mode): Add new custom-set function for module
minor modes. Update `erc-modules' before calling a minor-mode toggle
via `custom-set-minor-mode'.
(erc--tick-module-checkbox): Add helper to toggle the appropriate
checkbox in the `erc-modules' widget when a user interactively toggles
a minor-mode state variable.
(erc--prepare-custom-module-type): Create spec for minor-mode custom
`:type', deferring various aspects until module-definition time.
(define-erc-module): Add `:set' and `:type' keywords for global
modules.
* lisp/erc/erc.el (erc-modules): Inhibit `erc-update-modules' when run
from a minor-mode toggle's custom-set function.
* test/lisp/erc/erc-tests.el
(define-erc-module--global, define-erc-module--local): Update
`erc-modules' mutations with `erc--inside-mode-toggle-p' guard
conditions. (Bug#60935.)
---
lisp/erc/erc-common.el | 78 +++++++++++++++++++++++++++++++++++---
lisp/erc/erc.el | 3 +-
test/lisp/erc/erc-tests.el | 13 +++++--
3 files changed, 85 insertions(+), 9 deletions(-)
diff --git a/lisp/erc/erc-common.el b/lisp/erc/erc-common.el
index bf3bce74cfd..ec3a7cf9e85 100644
--- a/lisp/erc/erc-common.el
+++ b/lisp/erc/erc-common.el
@@ -29,6 +29,7 @@
(defvar erc--casemapping-rfc1459)
(defvar erc--casemapping-rfc1459-strict)
(defvar erc-channel-users)
+(defvar erc-modules)
(defvar erc-dbuf)
(defvar erc-log-p)
(defvar erc-server-users)
@@ -37,6 +38,11 @@ erc-session-server
(declare-function erc--get-isupport-entry "erc-backend" (key &optional single))
(declare-function erc-get-buffer "erc" (target &optional proc))
(declare-function erc-server-buffer "erc" nil)
+(declare-function widget-apply-action "wid-edit" (widget &optional event))
+(declare-function widget-at "wid-edit" (&optional pos))
+(declare-function widget-get-sibling "wid-edit" (widget))
+(declare-function widget-move "wid-edit" (arg &optional suppress-echo))
+(declare-function widget-type "wid-edit" (widget))
(cl-defstruct erc-input
string insertp sendp)
@@ -123,6 +129,15 @@ erc--normalize-module-symbol
(setq symbol (intern (downcase (symbol-name symbol))))
(or (cdr (assq symbol erc--module-name-migrations)) symbol))
+(defvar erc--inside-mode-toggle-p nil
+ "Non-nil when a mode toggle is updating module membership.
+This serves as a flag to inhibit the mutual recursion that
+otherwise occurs between an ERC-defined minor-mode function, such
+as `erc-services-mode', and the custom-set function for
+`erc-modules'. For historical reasons, the latter calls
+`erc-update-modules', which, in turn, enables the minor-mode
+functions for all member modules.")
+
(defun erc--assemble-toggle (localp name ablsym mode val body)
(let ((arg (make-symbol "arg")))
`(defun ,ablsym ,(if localp `(&optional ,arg) '())
@@ -140,11 +155,13 @@ erc--assemble-toggle
(,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)))
+ `((unless erc--inside-mode-toggle-p
+ ,(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)))))
@@ -179,6 +196,55 @@ erc--find-group
(throw 'found found)))
'erc))
+(defun erc--custom-set-minor-mode (variable value)
+ (let ((name (get variable 'erc-module))
+ (erc--inside-mode-toggle-p t))
+ (customize-set-variable
+ 'erc-modules
+ (if value (cl-pushnew name erc-modules) (delq name erc-modules)))
+ (custom-set-minor-mode variable value)))
+
+;; This exists as a separate, top-level function to prevent the byte
+;; compiler from warning about widget-related dependencies not being
+;; loaded at runtime.
+
+(defun erc--tick-module-checkbox (name &rest _) ; `name' must be normalized
+ (customize-variable-other-window 'erc-modules)
+ ;; Move to `erc-modules' section.
+ (while (not (eq (widget-type (widget-at)) 'checkbox))
+ (widget-move 1 t))
+ ;; This search for a checkbox can fail when `name' refers to a
+ ;; third-party module that modifies `erc-modules' (improperly) on
+ ;; load.
+ (let (w)
+ (while (and (eq (widget-type (widget-at)) 'checkbox)
+ (not (and (setq w (widget-get-sibling (widget-at)))
+ (eq (widget-value w) name))))
+ (setq w nil)
+ (widget-move 1 t)) ; the `suppress-echo' arg exists in 27.2
+ (if w
+ (progn (widget-apply-action (widget-at))
+ (message "Hit %s to apply or %s to apply and save."
+ (substitute-command-keys "\\[Custom-set]")
+ (substitute-command-keys "\\[Custom-save]")))
+ (error "Failed to find %s in `erc-modules' checklist" name))))
+
+(defun erc--prepare-custom-module-type (name)
+ `(let* ((name (erc--normalize-module-symbol ',name))
+ (fmtd (format " `%s' " name)))
+ `(boolean
+ :button-face '(error custom-button)
+ :format "%{%t%}: %[Deprecated Toggle%] \n%d\n"
+ :doc ,(concat "Setting a module's minor-mode variable is "
+ (propertize "ineffective" 'face 'error) ".\nPlease add"
+ fmtd "directly to `erc-modules' instead.\nYou can do so"
+ " now by clicking the scary button above.")
+ :help-echo ,(lambda (_)
+ (let ((hasp (memq name erc-modules)))
+ (concat (if hasp "Remove" "Add") fmtd
+ (if hasp "from" "to") " `erc-modules'.")))
+ :action ,(apply-partially #'erc--tick-module-checkbox name))))
+
(defmacro define-erc-module (name alias doc enable-body disable-body
&optional local-p)
"Define a new minor mode using ERC conventions.
@@ -225,6 +291,8 @@ define-erc-module
%s" name name doc)
:global ,(not local-p)
:group (erc--find-group ',name ,(and alias (list 'quote alias)))
+ ,@(unless local-p '(:set #'erc--custom-set-minor-mode))
+ ,@(unless local-p `(:type ,(erc--prepare-custom-module-type name)))
(if ,mode
(,enable)
(,disable)))
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index ff1820cfaf2..5e971f15f5d 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -1845,7 +1845,8 @@ erc-modules
(set sym val)
;; this test is for the case where erc hasn't been loaded yet
(when (fboundp 'erc-update-modules)
- (erc-update-modules)))
+ (unless erc--inside-mode-toggle-p
+ (erc-update-modules))))
:type
'(set
:greedy t
diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el
index 24a4f9d0639..e254b00454b 100644
--- a/test/lisp/erc/erc-tests.el
+++ b/test/lisp/erc/erc-tests.el
@@ -1313,7 +1313,10 @@ define-erc-module--global
((ignore a) (ignore b))
((ignore c) (ignore d)))))
- (should (equal (macroexpand global-module)
+ (should (equal (cl-letf (((symbol-function
+ 'erc--prepare-custom-module-type)
+ #'symbol-name))
+ (macroexpand global-module))
`(progn
(define-minor-mode erc-mname-mode
@@ -1324,6 +1327,8 @@ define-erc-module--global
Some docstring"
:global t
:group (erc--find-group 'mname 'malias)
+ :set #'erc--custom-set-minor-mode
+ :type "mname"
(if erc-mname-mode
(erc-mname-enable)
(erc-mname-disable)))
@@ -1331,14 +1336,16 @@ define-erc-module--global
(defun erc-mname-enable ()
"Enable ERC mname mode."
(interactive)
- (cl-pushnew 'mname erc-modules)
+ (unless erc--inside-mode-toggle-p
+ (cl-pushnew 'mname erc-modules))
(setq erc-mname-mode t)
(ignore a) (ignore b))
(defun erc-mname-disable ()
"Disable ERC mname mode."
(interactive)
- (setq erc-modules (delq 'mname erc-modules))
+ (unless erc--inside-mode-toggle-p
+ (setq erc-modules (delq 'mname erc-modules)))
(setq erc-mname-mode nil)
(ignore c) (ignore d))
--
2.39.1
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: 0003-5.6-Fill-doc-strings-for-ERC-modules.patch --]
[-- Type: text/x-patch, Size: 5781 bytes --]
From e4e270a4bf556ce238bc42c8549d4c443f3a969a Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Mon, 16 Jan 2023 20:18:32 -0800
Subject: [PATCH 3/3] [5.6] Fill doc strings for ERC modules.
* lisp/erc/erc-common.el (erc--fill-module-docstring): Add helper to
fill doc strings.
(erc--assemble-toggle, define-erc-module): Use helper to fill doc
string.
* test/lisp/erc/erc-tests.el (define-minor-mode--global,
define-minor-mode--local): Adjust expected output for generated doc
strings. (Bug#60935.)
---
lisp/erc/erc-common.el | 20 +++++++++++++++++---
test/lisp/erc/erc-tests.el | 28 ++++++++++++++++------------
2 files changed, 33 insertions(+), 15 deletions(-)
diff --git a/lisp/erc/erc-common.el b/lisp/erc/erc-common.el
index ec3a7cf9e85..cc278428d5d 100644
--- a/lisp/erc/erc-common.el
+++ b/lisp/erc/erc-common.el
@@ -141,7 +141,7 @@ erc--inside-mode-toggle-p
(defun erc--assemble-toggle (localp name ablsym mode val body)
(let ((arg (make-symbol "arg")))
`(defun ,ablsym ,(if localp `(&optional ,arg) '())
- ,(concat
+ ,(erc--fill-module-docstring
(if val "Enable" "Disable")
" ERC " (symbol-name name) " mode."
(when localp
@@ -245,6 +245,20 @@ erc--prepare-custom-module-type
(if hasp "from" "to") " `erc-modules'.")))
:action ,(apply-partially #'erc--tick-module-checkbox name))))
+(defun erc--fill-module-docstring (&rest strings)
+ (with-temp-buffer
+ (emacs-lisp-mode)
+ (insert "(defun foo ()\n"
+ (format "%S" (apply #'concat strings))
+ "\n(ignore))")
+ (goto-char (point-min))
+ (forward-line 2)
+ (let ((emacs-lisp-docstring-fill-column 65)
+ (sentence-end-double-space t))
+ (fill-paragraph))
+ (goto-char (point-min))
+ (nth 3 (read (current-buffer)))))
+
(defmacro define-erc-module (name alias doc enable-body disable-body
&optional local-p)
"Define a new minor mode using ERC conventions.
@@ -284,11 +298,11 @@ define-erc-module
`(progn
(define-minor-mode
,mode
- ,(format "Toggle ERC %S mode.
+ ,(erc--fill-module-docstring (format "Toggle ERC %s mode.
With a prefix argument ARG, enable %s if ARG is positive,
and disable it otherwise. If called from Lisp, enable the mode
if ARG is omitted or nil.
-%s" name name doc)
+\n%s" name name doc))
:global ,(not local-p)
:group (erc--find-group ',name ,(and alias (list 'quote alias)))
,@(unless local-p '(:set #'erc--custom-set-minor-mode))
diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el
index e254b00454b..e5db78ef2e1 100644
--- a/test/lisp/erc/erc-tests.el
+++ b/test/lisp/erc/erc-tests.el
@@ -1309,7 +1309,7 @@ erc--merge-local-modes
(ert-deftest define-erc-module--global ()
(let ((global-module '(define-erc-module mname malias
- "Some docstring"
+ "Some docstring."
((ignore a) (ignore b))
((ignore c) (ignore d)))))
@@ -1321,10 +1321,11 @@ define-erc-module--global
(define-minor-mode erc-mname-mode
"Toggle ERC mname mode.
-With a prefix argument ARG, enable mname if ARG is positive,
-and disable it otherwise. If called from Lisp, enable the mode
-if ARG is omitted or nil.
-Some docstring"
+With a prefix argument ARG, enable mname if ARG is positive, and
+disable it otherwise. If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Some docstring."
:global t
:group (erc--find-group 'mname 'malias)
:set #'erc--custom-set-minor-mode
@@ -1359,7 +1360,7 @@ define-erc-module--global
(ert-deftest define-erc-module--local ()
(let* ((global-module '(define-erc-module mname nil ; no alias
- "Some docstring"
+ "Some docstring."
((ignore a) (ignore b))
((ignore c) (ignore d))
'local))
@@ -1371,10 +1372,11 @@ define-erc-module--local
`(progn
(define-minor-mode erc-mname-mode
"Toggle ERC mname mode.
-With a prefix argument ARG, enable mname if ARG is positive,
-and disable it otherwise. If called from Lisp, enable the mode
-if ARG is omitted or nil.
-Some docstring"
+With a prefix argument ARG, enable mname if ARG is positive, and
+disable it otherwise. If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Some docstring."
:global nil
:group (erc--find-group 'mname nil)
(if erc-mname-mode
@@ -1383,7 +1385,8 @@ define-erc-module--local
(defun erc-mname-enable (&optional ,arg-en)
"Enable ERC mname mode.
-When called interactively, do so in all buffers for the current connection."
+When called interactively, do so in all buffers for the current
+connection."
(interactive "p")
(when (derived-mode-p 'erc-mode)
(if ,arg-en
@@ -1395,7 +1398,8 @@ define-erc-module--local
(defun erc-mname-disable (&optional ,arg-dis)
"Disable ERC mname mode.
-When called interactively, do so in all buffers for the current connection."
+When called interactively, do so in all buffers for the current
+connection."
(interactive "p")
(when (derived-mode-p 'erc-mode)
(if ,arg-dis
--
2.39.1
next prev parent reply other threads:[~2023-02-07 15:23 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-18 14:50 bug#60935: 30.0.50; ERC >5.5: Improve ERC's treatment of customization groups J.P.
2023-02-07 15:23 ` J.P. [this message]
2023-02-19 15:03 ` J.P.
2023-03-14 13:43 ` J.P.
2023-03-15 14:05 ` J.P.
[not found] ` <87edpqglf1.fsf@neverwas.me>
2023-04-14 14:03 ` J.P.
[not found] ` <87a5zay31h.fsf@neverwas.me>
2023-05-06 0:54 ` J.P.
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='87sffh8ppj.fsf__16167.6958364964$1675783468$gmane$org@neverwas.me' \
--to=jp@neverwas.me \
--cc=60935@debbugs.gnu.org \
--cc=emacs-erc@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).