From 1f81ad6c12e4494c3a6434b55923a6e4be3b38fb Mon Sep 17 00:00:00 2001 From: Gregory Heytings Date: Sun, 12 Sep 2021 21:10:08 +0000 Subject: [PATCH] Warn when custom variable is wrongly set. * src/eval.c (Fsetq): Display warning when a custom variable with a :set property is set with setq. Warnings are displayed only for custom variables whose files have been loaded and that have a :set property. No warnings are displayed for custom variables whose files have merely been preloaded, for custom variables that do not have a :set property, and for non-custom variables. See bug#21695. (syms_of_eval): Three new symbols. * etc/NEWS: Document the warning. * doc/emacs/custom.texi: Mention the warning. --- doc/emacs/custom.texi | 3 ++- etc/NEWS | 6 ++++++ src/eval.c | 13 ++++++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi index 9220a2078f..1b7e7d9361 100644 --- a/doc/emacs/custom.texi +++ b/doc/emacs/custom.texi @@ -2378,7 +2378,8 @@ Init Syntax command. Finally, a few customizable user options are initialized in complex ways, and these have to be set either via the customize interface (@pxref{Customization}) or by using -@code{customize-set-variable} (@pxref{Examining}). +@code{customize-set-variable} (@pxref{Examining}). If such options +are inadvertently set with @code{setq}, a warning is displayed. The second argument to @code{setq} is an expression for the new value of the variable. This can be a constant, a variable, or a diff --git a/etc/NEWS b/etc/NEWS index ca269aabaa..dfdd925ec5 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -3401,6 +3401,12 @@ truncating precision field, such as "%.2a". Such mixes are always signs that the outer lexical binding was an error and should have used dynamic binding instead. +-- +** 'setq' displays a warning when 'customize-set-variable' should have been used. +Some custom variables need to be set with 'customize-set-variable', because +they were designed to be set through the Customization interface and have a +:set lambda form which does other things after they have been set. + --- ** New variable 'inhibit-mouse-event-check'. If bound to non-nil, a command with '(interactive "e")' doesn't signal diff --git a/src/eval.c b/src/eval.c index 48104bd0f4..a81001749d 100644 --- a/src/eval.c +++ b/src/eval.c @@ -525,8 +525,16 @@ DEFUN ("setq", Fsetq, Ssetq, 0, UNEVALLED, 0, : Qnil); if (!NILP (lex_binding)) XSETCDR (lex_binding, val); /* SYM is lexically bound. */ - else + else { + Lisp_Object plist = XSYMBOL (sym)->u.s.plist; + if (!EQ (plist, Qnil) && !NILP (Fplist_get (plist, Qcustom_set))) + safe_call2 (Qdisplay_warning, Qsetq, + CALLN (Fformat, + build_string + ("`%s' should be set with `customize-set-variable'"), + sym)); Fset (sym, val); /* SYM is dynamically bound. */ + } } return val; @@ -4556,4 +4564,7 @@ syms_of_eval (void) defsubr (&Sbacktrace__locals); defsubr (&Sspecial_variable_p); defsubr (&Sfunctionp); + DEFSYM (Qcustom_set, "custom-set"); + DEFSYM (Qdisplay_warning, "display-warning"); + DEFSYM (Qsetq, "setq"); } -- 2.33.0