Subject: bug#10754: define-minor-mode and doc of derived mode

From: John Shahid <[email-masked]>
Date: Sun, 17 Jun 2018 19:45:42 +0000

Stefan Monnier <[email-masked]> writes:

>> I just thought of an alternative approach.  Instead of interpolating the
>> docstring we could append the extra argument description to the
>> docstring ?
>
> FWIW, it's the approach I would have taken.

Great. I changed the patch to append to the docstring instead of
interpolate it. I like this approach better, it is cleaner imho.

>
>> We can add an optional arg to `define-minor-mode'.
>
> I'd rather avoid it if I can.

I meant a keyword argument when I was saying optional. I forgot that
`define-minor-mode' takes actual optional arguments.

I attached the new patch, below. If this looks good, I will amend the
patch to include other minor modes.

>From d0e79015e211b5389c08c39f8fbe3044ab3a7de3 Mon Sep 17 00:00:00 2001
From: John Shahid <[email-masked]>
Date: Tue, 5 Jun 2018 19:56:12 -0400
Subject: [PATCH] optionally include argument description in minor mode DOC

* easy-mmode.el (define-minor-mode): add a new option
  `append-arg-docstring' to append DOC with documentation of the mode
  argument
* linum.el (linum-mode): set append-arg-docstring to t
---
 lisp/emacs-lisp/easy-mmode.el | 32 +++++++++++++++++++++++++-------
 lisp/linum.el                 |  4 +---
 2 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el
index a81b6fefb2..7701842a94 100644
--- a/lisp/emacs-lisp/easy-mmode.el
+++ b/lisp/emacs-lisp/easy-mmode.el
@@ -81,6 +81,25 @@ easy-mmode-pretty-mode-name
       ;; space.)
       (replace-regexp-in-string (regexp-quote lighter) lighter name t t))))
 
+(defconst easy-mmode-arg-docstring
+  "If called interactively, enable %s if ARG is positive, and
+disable it otherwise.  If called from Lisp, enable the mode if
+ARG is omitted or nil, and toggle it if ARG is `toggle'. Disable
+the mode otherwise")
+
+(defun easy-mmode-mode-docstring (doc mode-pretty-name keymap-sym append-arg-docstring)
+  (unless doc
+    (setq append-arg-docstring t)
+    (setq doc (format "Toggle %s on or off.
+\\{%s}" mode-pretty-name keymap-sym)))
+  (if append-arg-docstring
+      (concat doc
+              "\n\n"
+                              (format easy-mmode-arg-docstring
+                                      mode-pretty-name
+                      mode-pretty-name))
+    doc))
+
 ;;;###autoload
 (defalias 'easy-mmode-define-minor-mode 'define-minor-mode)
 ;;;###autoload
@@ -101,7 +120,9 @@ define-minor-mode
 if the argument is omitted or nil or a positive integer).
 
 If DOC is nil, give the mode command a basic doc-string
-documenting what its argument does.
+documenting what its argument does. All occurences of the string
+\"%{arg}\" in DOC will be replaced by a docstring explaining
+usages of the mode argument.
 
 Optional INIT-VALUE is the initial value of the mode's variable.
 Optional LIGHTER is displayed in the mode line when the mode is on.
@@ -179,6 +200,7 @@ define-minor-mode
 	 (group nil)
 	 (type nil)
 	 (extra-args nil)
+         (append-arg-docstring nil)
 	 (extra-keywords nil)
          (variable nil)          ;The PLACE where the state is stored.
          (setter `(setq ,mode))  ;The beginning of the exp to set the mode var.
@@ -201,6 +223,7 @@ define-minor-mode
          (when (and globalp (symbolp mode))
            (setq setter `(setq-default ,mode))
            (setq getter `(default-value ',mode))))
+        (`:append-arg-docstring (setq append-arg-docstring t))
 	(`:extra-args (setq extra-args (pop body)))
 	(`:set (setq set (list :set (pop body))))
 	(`:initialize (setq initialize (list :initialize (pop body))))
@@ -270,12 +293,7 @@ define-minor-mode
 
        ;; The actual function.
        (defun ,modefun (&optional arg ,@extra-args)
-	 ,(or doc
-	      (format (concat "Toggle %s on or off.
-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, and toggle it if ARG is `toggle'.
-\\{%s}") pretty-name pretty-name keymap-sym))
+         ,(easy-mmode-mode-docstring doc pretty-name keymap-sym append-arg-docstring)
 	 ;; Use `toggle' rather than (if ,mode 0 1) so that using
 	 ;; repeat-command still does the toggling correctly.
 	 (interactive (list (or current-prefix-arg 'toggle)))
diff --git a/lisp/linum.el b/lisp/linum.el
index 9df0c5d023..6e673e58b0 100644
--- a/lisp/linum.el
+++ b/lisp/linum.el
@@ -75,12 +75,10 @@ linum-delay
 ;;;###autoload
 (define-minor-mode linum-mode
   "Toggle display of line numbers in the left margin (Linum mode).
-With a prefix argument ARG, enable Linum mode if ARG is positive,
-and disable it otherwise.  If called from Lisp, enable the mode
-if ARG is omitted or nil.
 
 Linum mode is a buffer-local minor mode."
   :lighter ""                           ; for desktop.el
+  :append-arg-docstring t
   (if linum-mode
       (progn
         (if linum-eager
-- 
2.17.1