Subject: bug#77173: [PATCH] Instruct users to use customize or setopt for user options that have :set-er

From: Visuwesh <[email-masked]>
Date: Sun, 23 Mar 2025 11:28:53 +0530

[Saturday March 22, 2025] Eli Zaretskii wrote:

>> > What does this do when the setter is an anonymous function?  We have
>> > quite a lot of these when a defcustom needs a :set function.
>> 
>> It currently does nothing, thanks for catching this.  I forgot to
>> consider lambdas when I wrote the patch earlier.  I think we can leave
>> out the "or call XXX" part if :set is a function?
>
> I don't see any reasonable alternative.

Thanks, now done in the attached.  I hope symbolp is good enough to test
if :set is a named function.

[Saturday March 22, 2025] Stefan Kangas wrote:

> Visuwesh <[email-masked]> writes:
>
>> [Saturday March 22, 2025] Stefan Kangas wrote:
>>
>>> Thanks.  Are you on a current master?
>>
>> I haven't pulled for a few weeks now.  Should I rework the patch on top
>> of yours?  I think adding this bit to help-fns--customize-variable would
>> be cleaner, but happy to change the function you wrote instead.
>
> Yes, please.  Feel free to suggest something cleaner.
>
> Thanks.

Thanks, I moved the setopt suggestion to help-fns--customize-variable to
keep related code in the same function.  In this process, I removed the
top TODO comment, should we keep it around?

>From e619d54ee3cf5b49a5ac4348e85e2ab40085bb38 Mon Sep 17 00:00:00 2001
From: Visuwesh <[email-masked]>
Date: Sun, 23 Mar 2025 11:28:16 +0530
Subject: [PATCH] Improve formatting of 'setopt' suggestion in *Help* buffer

* lisp/help-fns.el (help--recommend-setopt): Remove function,
and...
(help-fns--customize-variable): ... move the relevant code here
to keep related code in the same place.  Change the formatting
to also include the :set function if it is set to a named
function.  (Bug#77173)
---
 lisp/help-fns.el | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index fabdda521dc..fe37a954409 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -868,20 +868,6 @@ help-fns--disabled
              (function-get function 'disabled))
     (insert "  This function is disabled.\n")))
 
-(add-hook 'help-fns-describe-variable-functions #'help--recommend-setopt)
-(defun help--recommend-setopt (symbol)
-  ;; TODO: This would be better if added to the docstring itself, but I
-  ;;       ran into `byte-compile-dynamic-docstring' and gave up.
-  (when (and (get symbol 'custom-set)
-             ;; Don't override manually written documentation.
-             (not (string-match (rx word-start "setopt" word-end)
-                                (documentation-property
-                                 symbol 'variable-documentation))))
-    ;; FIXME: `princ` removes text properties added by s-c-k.
-    (princ (substitute-command-keys "\
-Setting this variable with `setq' has no effect; use either `setopt'
-or \\[customize-option] to change its value.\n\n"))))
-
 (defun help-fns--first-release-regexp (symbol)
   (let* ((name (symbol-name symbol))
          (quoted (regexp-quote name)))
@@ -1593,12 +1579,26 @@ help-fns--run-describe-functions
 (defun help-fns--customize-variable (variable &optional text)
   ;; Make a link to customize if this variable can be customized.
   (when (custom-variable-p variable)
-    (let ((customize-label "customize"))
+    (let ((customize-label "customize")
+          (custom-set (get variable 'custom-set)))
       (princ (concat "  You can " customize-label (or text " this variable.")))
+      (when (and custom-set
+                 ;; Don't override manually written documentation.
+                 (not (string-match (rx word-start "setopt" word-end)
+                                    (documentation-property
+                                     variable 'variable-documentation))))
+        (princ (substitute-quotes
+                (concat "\n  Setting this variable directly with `setq' will not usually take effect;"
+                        "\n  use either customize or `setopt'"
+                        ;; Skip text if `custom-set' property is an
+                        ;; anonymous function.
+                        (when (symbolp custom-set)
+                          (concat ", or call `" (symbol-name custom-set) "'"))
+                        "."))))
       (with-current-buffer standard-output
 	(save-excursion
-          (re-search-backward (concat "\\(" customize-label "\\)"))
-	  (help-xref-button 1 'help-customize-variable variable)))
+          (while (re-search-backward (concat "\\(" customize-label "\\)") nil t)
+	    (help-xref-button 1 'help-customize-variable variable))))
       (terpri))))
 
 (add-hook 'help-fns-describe-variable-functions
-- 
2.47.2