* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) @ 2022-03-15 11:50 Ignacio Casso 2022-03-17 11:23 ` Lars Ingebrigtsen 2022-04-12 9:13 ` Ignacio Casso 0 siblings, 2 replies; 41+ messages in thread From: Ignacio Casso @ 2022-03-15 11:50 UTC (permalink / raw) To: 54399 Hello, I reported this org-mode bug in https://lists.gnu.org/archive/html/emacs-orgmode/2022-03/msg00085.html, but after some discussion we figured out that the issue is not particular to org-mode but generic to all Emacs and decided to bring our conclusions and questions here. The problem is the following: Calling an autoload function under the following circumstances does not always work as expected: - the function uses a variable defined with defcustom in the same file as the function. - the function is called inside a let form that binds that same variable. - the file defining the function and the variable has not been loaded yet at the time the function is called, and the variable has not been set either. I would expect to work exactly the same as if the file had already been loaded. Instead, the following happens depending on the scoping and the defcustom setter: 1) If the let form is evaluated with lexical-binding, and the variable is not also autoloaded, Emacs does not know the variable is special by the time it evaluates let, so it uses lexical binding. Later, when it evaluates defcustom and it finds out that it is special and it should have used dynamic binding, Emacs 29 produces the error (error "Defining as dynamic an already lexical var"). Emacs 27 does not perform this check and keeps going, and since it uses lexical binding, the let binding has not effect at all inside the function as the user would expect. The exact same thing happens also if the variable is defined with defvar. I guess there is nothing that can be done about it otherwise Emacs 29 would have done so instead of throwing an error. The following form reproduces this behavior (please ensure to evaluate it with lexical binding): (progn (defun my-load () (defvar my-var 1) (message "Value while loading: %s" my-var)) (defun my-var-alias () my-var) (let ((my-var 2)) (my-load) (message "Lexical value inside let: %s" my-var) (message "Dynamic value inside let: %s" (my-var-alias))) (message "Value ouside let: %s" my-var)) 2) If the let form is evaluated with dynamic binding, or the variable has also an autoload cookie so Emacs already knows is dynamic, then the behavior depends on the :set argument of defcustom: 2.1) If no explicit argument is passed, then defcustom uses as default set-default-toplevel-value. In that case everything works as expected. Note however that the documentation and comments says in many places that the default :set argument is just set-default instead of set-default-toplevel-value. 2.2) If the :set argument is set or set-default (the suggested default choice in the documentation), that function is called with arguments the variable symbol and the standard value passed as argument to defcustom. But those functions only affect the scope of the let binding, which means that a) they overwrite the let binding, which is not what the user expect, and b) when the evaluation of the let form finish the variable is void. Thus, any further use of that variable or functions that use it will produce a void variable error. And this is not trivial to fix: requiring the feature again will do nothing since it's already provided, so the user needs to finds it's definition and evaluate defvar/defcustom again himself, or restart Emacs. The following form reproduces this behavior (please ensure to evaluate it with dynamic binding): (progn (defun my-load () (defcustom my-other-var 1 "Test variable" :set 'set-default) (message "Value while loading: %s" my-other-var)) (let ((my-other-var 2)) (my-load) (message "Value inside let: %s" (my-other-var-alias))) (message "Value ouside let: %s" my-other-var)) I think that something should be done about point 2.2. Some suggestions are: - A warning when defcustom of a variable is called inside a let binding of that same variable. - Update documentation of defcustom to say that the default choice of the :set argument is set-default-toplevel-value - Document default-value, default-boundp, and set-default to say that they may not work as the user expects when called inside a let binding with dynamic binding enabled. The snippets below show how I expected them to work (please evaluate them with dynamic binding): (let ((fresh-var 1)) (default-value 'fresh-var)) ;; I expect and error, it returns 1 (let ((another-fresh-var 1)) (default-boundp 'another-fresh-var)) ;; I expect nil, it returns t (defvar yet-another-fresh-var 1) (let ((yet-another-fresh-var 2)) (set-default 'yet-another-fresh-var 3) yet-another-fresh-var) ;; I expect 2, it returns 3 yet-another-fresh-var ;; I expect 3, it returns 1 What do you think? ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-03-15 11:50 bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) Ignacio Casso @ 2022-03-17 11:23 ` Lars Ingebrigtsen 2022-03-18 0:22 ` Michael Heerdegen 2022-04-12 9:13 ` Ignacio Casso 1 sibling, 1 reply; 41+ messages in thread From: Lars Ingebrigtsen @ 2022-03-17 11:23 UTC (permalink / raw) To: Ignacio Casso; +Cc: 54399 Ignacio Casso <ignaciocasso@hotmail.com> writes: > Calling an autoload function under the following circumstances does not > always work as expected: > > - the function uses a variable defined with defcustom in the same file > as the function. > > - the function is called inside a let form that binds that same > variable. I don't think this is supported? And it's not just with user options -- normal variables will end up being unbound if you do this (unless this has been changed since I looked at this a decade ago). And I think it's documented, too? Or am I misremembering? Anybody? -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-03-17 11:23 ` Lars Ingebrigtsen @ 2022-03-18 0:22 ` Michael Heerdegen 2022-03-18 1:02 ` Michael Heerdegen 2022-03-18 9:32 ` Lars Ingebrigtsen 0 siblings, 2 replies; 41+ messages in thread From: Michael Heerdegen @ 2022-03-18 0:22 UTC (permalink / raw) To: Lars Ingebrigtsen; +Cc: Ignacio Casso, 54399 Lars Ingebrigtsen <larsi@gnus.org> writes: > Ignacio Casso <ignaciocasso@hotmail.com> writes: > > > Calling an autoload function under the following circumstances does not > > always work as expected: > > > > - the function uses a variable defined with defcustom in the same file > > as the function. > > > > - the function is called inside a let form that binds that same > > variable. > > I don't think this is supported? And it's not just with user options -- > normal variables will end up being unbound if you do this (unless this > has been changed since I looked at this a decade ago). And I think it's > documented, too? Or am I misremembering? Anybody? Hmm - I don't know much about the background, but wasn't `set-default-toplevel-value' invented to make just that work? See commit a104f656c8 Make defvar affect the default binding outside of any let. Stefan Monnier <monnier@iro.umontreal.ca> Fri Aug 2 17:16:33 2013 -0400 AFAIU this bug report is a request to (1) correct some docstrings and (2) use `set-default-toplevel-value' instead of `set-default' at more places in custom.el to assign values, where appropriate. Michael. ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-03-18 0:22 ` Michael Heerdegen @ 2022-03-18 1:02 ` Michael Heerdegen 2022-03-18 9:32 ` Lars Ingebrigtsen 1 sibling, 0 replies; 41+ messages in thread From: Michael Heerdegen @ 2022-03-18 1:02 UTC (permalink / raw) To: Lars Ingebrigtsen; +Cc: Ignacio Casso, 54399 Michael Heerdegen <michael_heerdegen@web.de> writes: > a104f656c8 Make defvar affect the default binding outside of any let. > Stefan Monnier <monnier@iro.umontreal.ca> Fri Aug 2 17:16:33 2013 -0400 And AFAIU this commit also fixed the problem for variables that are not user options. Now you can create a local special variable like this: (defvar variable) (let ((variable ...)) (require ...) ...) That has the desired effect (of binding variable dynamically) but any (defvar variable ...) form evaluated when loading still makes the VARIABLE special and sets the global value. Right? Michael. ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-03-18 0:22 ` Michael Heerdegen 2022-03-18 1:02 ` Michael Heerdegen @ 2022-03-18 9:32 ` Lars Ingebrigtsen 2022-03-18 9:38 ` Ignacio Casso 1 sibling, 1 reply; 41+ messages in thread From: Lars Ingebrigtsen @ 2022-03-18 9:32 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Ignacio Casso, 54399 Michael Heerdegen <michael_heerdegen@web.de> writes: > Hmm - I don't know much about the background, but wasn't > `set-default-toplevel-value' invented to make just that work? See > commit > > a104f656c8 Make defvar affect the default binding outside of any let. > Stefan Monnier <monnier@iro.umontreal.ca> Fri Aug 2 17:16:33 2013 -0400 Ah, newfangled code. 😀 > AFAIU this bug report is a request to (1) correct some docstrings and > (2) use `set-default-toplevel-value' instead of `set-default' at more > places in custom.el to assign values, where appropriate. Right. -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-03-18 9:32 ` Lars Ingebrigtsen @ 2022-03-18 9:38 ` Ignacio Casso 2022-04-12 13:18 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 1 reply; 41+ messages in thread From: Ignacio Casso @ 2022-03-18 9:38 UTC (permalink / raw) To: Lars Ingebrigtsen; +Cc: Michael Heerdegen, 54399 Lars Ingebrigtsen <larsi@gnus.org> writes: > Michael Heerdegen <michael_heerdegen@web.de> writes: > >> Hmm - I don't know much about the background, but wasn't >> `set-default-toplevel-value' invented to make just that work? See >> commit >> >> a104f656c8 Make defvar affect the default binding outside of any let. >> Stefan Monnier <monnier@iro.umontreal.ca> Fri Aug 2 17:16:33 2013 -0400 > > Ah, newfangled code. 😀 > >> AFAIU this bug report is a request to (1) correct some docstrings and >> (2) use `set-default-toplevel-value' instead of `set-default' at more >> places in custom.el to assign values, where appropriate. > > Right. I think custom.el already uses `set-default-toplevel-value' where appropriate by default. So my request is (1) to correct the docstrings in custom.el to reflect so, so that users know to use it instead of `set-default', and (2) Add some warnings somewhere, although I'm not sure where. I personally can not think of a single case in which someone would want to use `set-default' instead of `set-default-toplevel-value'. If I understand them correctly, they both do the same outside a let binding, and I don't see why someone would want the `set-default' behavior inside the let binding. In fact, I guess most people assume that `set-default' behaves like `set-default-toplevel-value' (I did at least). So I would at least talk about this in the docstrings of `set-default', and also `default-value' and `default-boundp' which suffer the same problem. In fact, now that I see it, the docstring of the later is just wrong. The others just don't mention let bindings and only talk about buffer-local bindings, but that one explicitly says that the function can be used to know if a variable has a non-void value outside of a let-binding, and with dynamic binding that doesn't work (see snippet below). (setq lexical-binding nil) (let ((another-fresh-var 1)) (default-boundp 'another-fresh-var)) ;; I expect nil, it returns t ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-03-18 9:38 ` Ignacio Casso @ 2022-04-12 13:18 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2022-04-12 13:23 ` Ignacio Casso 0 siblings, 1 reply; 41+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2022-04-12 13:18 UTC (permalink / raw) To: Ignacio Casso; +Cc: Michael Heerdegen, Lars Ingebrigtsen, 54399 > (setq lexical-binding nil) > (let ((another-fresh-var 1)) > (default-boundp 'another-fresh-var)) ;; I expect nil, it returns t This means you misunderstand dynamic scoping or the meaning of "default-" in `default-boundp` (it has nothing to do with let bindings but is only concerned about buffer-local or not). If you disregard lexical scoping, there are kinda to dimensions to locality of variables: there's the "let" locality and there's the "buffer" locality. They can be combined. `default-boundp/set-default` only differ from `boundp/set` on the "buffer" dimension of locality. Lexical scoping is yet a different beast because lexical variables have fundamentally no name, so a lexical binding of variable `foo` has no relation to what `boundp/set` see when passed `foo` as argument. Stefan ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-04-12 13:18 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2022-04-12 13:23 ` Ignacio Casso 2022-04-12 13:55 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 1 reply; 41+ messages in thread From: Ignacio Casso @ 2022-04-12 13:23 UTC (permalink / raw) To: Stefan Monnier; +Cc: Michael Heerdegen, Lars Ingebrigtsen, 54399 Stefan Monnier <monnier@iro.umontreal.ca> writes: >> (setq lexical-binding nil) >> (let ((another-fresh-var 1)) >> (default-boundp 'another-fresh-var)) ;; I expect nil, it returns t > > This means you misunderstand dynamic scoping or the meaning of > "default-" in `default-boundp` (it has nothing to do with let bindings > but is only concerned about buffer-local or not). I know, but the docstring for default-boundp in Emacs 29 says: "A variable may have a buffer-local or a ‘let’-bound local value. This function says whether the variable has a non-void value outside of the current context" So that docstring at least should be corrected, and either restore the docstring in Emacs 27, that does not mention let bindings at all, or clarify the distinction in that docstring an also in the docstrings for `default-value' and `set-default' ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-04-12 13:23 ` Ignacio Casso @ 2022-04-12 13:55 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 0 replies; 41+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2022-04-12 13:55 UTC (permalink / raw) To: Ignacio Casso; +Cc: Michael Heerdegen, Lars Ingebrigtsen, 54399 > I know, but the docstring for default-boundp in Emacs 29 says: > > "A variable may have a buffer-local or a ‘let’-bound local value. This > function says whether the variable has a non-void value outside of the > current context" > > So that docstring at least should be corrected, and either restore the > docstring in Emacs 27, that does not mention let bindings at all, or > clarify the distinction in that docstring an also in the docstrings for > `default-value' and `set-default' Indeed a patch which fixes these confusions would be great, Stefan ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-03-15 11:50 bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) Ignacio Casso 2022-03-17 11:23 ` Lars Ingebrigtsen @ 2022-04-12 9:13 ` Ignacio Casso 2022-04-12 11:38 ` Eli Zaretskii 2022-04-12 13:19 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 1 sibling, 2 replies; 41+ messages in thread From: Ignacio Casso @ 2022-04-12 9:13 UTC (permalink / raw) To: 54399, larsi, Michael Heerdegen > I think custom.el already uses `set-default-toplevel-value' where > appropriate by default. So my request is (1) to correct the docstrings > in custom.el to reflect so, so that users know to use it instead of > `set-default', and (2) Add some warnings somewhere, although I'm not > sure where. > > I personally can not think of a single case in which someone would want > to use `set-default' instead of `set-default-toplevel-value'. If I > understand them correctly, they both do the same outside a let binding, > and I don't see why someone would want the `set-default' behavior inside > the let binding. In fact, I guess most people assume that `set-default' > behaves like `set-default-toplevel-value' (I did at least). > > So I would at least talk about this in the docstrings of `set-default', > and also `default-value' and `default-boundp' which suffer the same > problem. In fact, now that I see it, the docstring of the later is just > wrong. The others just don't mention let bindings and only talk about > buffer-local bindings, but that one explicitly says that the function > can be used to know if a variable has a non-void value outside of a > let-binding, and with dynamic binding that doesn't work (see snippet > below). > > (setq lexical-binding nil) > (let ((another-fresh-var 1)) > (default-boundp 'another-fresh-var)) ;; I expect nil, it returns t Hello, I was revisiting this bug report and writing a patch to correct and update some docstrings, both in custom.el and for `default-value', `set-default' and `default-boundp'. But for the last three, I'm no longer sure if the errors are in the implementation or the docstrings, since I have found more strange cases while experimenting. In a few words, those functions behave differently inside let bindings depending on whether the current buffer has or not a local value for the variable, which I find a little bit inconsistent. If it has, they behave as they "toplevel" counterparts (`default-toplevel-value', `set-default-toplevel-value'). If they don't, they behave as I explained in previous emails. I describe those cases below, with code snippets and comments. Note that the behavior also depends on whether lexical binding is enabled or not. I use dynamic binding in these examples. ;;;; `default-value' ;; default defined, buffer-local undefined (defvar var1 "default") (let ((var1 "inside let")) (default-value 'var1)) ;; returns "inside let" ;; default defined, buffer-local defined (defvar var2 "default") (setq-local var2 "buffer-local") (let ((var2 "inside let")) (default-value 'var2)) ;; returns "default" ;; default undefined, buffer-local undefined (let ((var3 "inside let")) (default-value 'var3)) ;; returns "inside let" ;; default undefined, buffer-local defined (setq-local var4 "buffer-local") (let ((var4 "inside let")) (default-value 'var4)) ;; void-variable error ;;;; `default-boundp' ;; default defined, buffer-local undefined (defvar var5 "default") (let ((var5 "inside let")) (default-boundp 'var5)) ;; returns t ;; default defined, buffer-local defined (defvar var6 "default") (setq-local var6 "buffer-local") (let ((var6 "inside let")) (default-boundp 'var6)) ;; returns t ;; default undefined, buffer-local undefined (let ((var7 "inside let")) (default-boundp 'var7)) ;; returns t ;; default undefined, buffer-local defined (setq-local var8 "buffer-local") (let ((var8 "inside let")) (default-boundp 'var8)) ;; returns nil ;;;; `set-default' ;; default defined, buffer-local undefined (defvar var9 "default") (let ((var9 "inside let")) (set-default 'var9 "new-default") var9) ;; returns "new-default" var9 ;; returns "default" (default-value 'var9) ;; returns "default" ;; default defined, buffer-local defined (defvar var10 "default") (setq-local var10 "buffer-local") (let ((var10 "inside let")) (set-default 'var10 "new-default") var10) ;; returns "inside let" var10 ;; returns "buffer-local" (default-value 'var10) ;; returns "new-default" ;; default undefined, buffer-local undefined (let ((var11 "inside let")) (set-default 'var11 "new-default") var11) ;; returns "new-default" var11 ;; void-variable error (default-value 'var11) ;; void-variable error ;; default undefined, buffer-local defined (setq-local var12 "buffer-local") (let ((var12 "inside let")) (set-default 'var12 "new-default") var12) ;; returns "inside let" var12 ;; returns "buffer-local" (default-value 'var12) ;; returns "new-default" Should I go ahead and just update the docstrings so that they reflect this behavior, and then close this bug report? Or do you think that the code should be changed too? For the later I don't think I could help, since that code is too low level for me. ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-04-12 9:13 ` Ignacio Casso @ 2022-04-12 11:38 ` Eli Zaretskii 2022-04-12 12:16 ` Ignacio Casso 2022-04-12 13:19 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 1 sibling, 1 reply; 41+ messages in thread From: Eli Zaretskii @ 2022-04-12 11:38 UTC (permalink / raw) To: Ignacio Casso, Stefan Monnier; +Cc: michael_heerdegen, larsi, 54399 [Adding Stefan to the discussion.] > From: Ignacio Casso <ignaciocasso@hotmail.com> > Date: Tue, 12 Apr 2022 11:13:27 +0200 > > I was revisiting this bug report and writing a patch to correct and > update some docstrings, both in custom.el and for `default-value', > `set-default' and `default-boundp'. But for the last three, I'm no > longer sure if the errors are in the implementation or the docstrings, > since I have found more strange cases while experimenting. In a few > words, those functions behave differently inside let bindings depending > on whether the current buffer has or not a local value for the variable, > which I find a little bit inconsistent. If it has, they behave as they > "toplevel" counterparts (`default-toplevel-value', > `set-default-toplevel-value'). If they don't, they behave as I explained > in previous emails. I describe those cases below, with code snippets and > comments. Note that the behavior also depends on whether lexical binding > is enabled or not. I use dynamic binding in these examples. Please tell more in each case where you consider the behavior "surprising" why did you expect something different. I think it's important to make the subsequent discussion focused and efficient. Thanks. ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-04-12 11:38 ` Eli Zaretskii @ 2022-04-12 12:16 ` Ignacio Casso 2022-04-12 13:35 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2022-04-12 15:24 ` Eli Zaretskii 0 siblings, 2 replies; 41+ messages in thread From: Ignacio Casso @ 2022-04-12 12:16 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, larsi, 54399, Stefan Monnier > Please tell more in each case where you consider the behavior > "surprising" why did you expect something different. I think it's > important to make the subsequent discussion focused and efficient. > > Thanks. I explained why I considered some of those cases surprising by themselves in previous emails of the thread. I originally expected `default-value', `set-default' and `default-boundp' to behave like their counterparts `default-toplevel-value' and `set-default-toplevel-value'. But I assumed there was a reason for there being two versions, so I was just going to update some docstrings to make the distinction more clear (or in the case `default-boundp', correct the docstring, which is just wrong). But now, considering all the cases together, I also consider surprising that the behavior, whichever the correct one should be, depends on whether the variable has or not a buffer local binding. So for example, for the following > ;; default defined, buffer-local undefined > (defvar var1 "default") > (let ((var1 "inside let")) (default-value 'var1)) ;; returns "inside let" > > ;; default defined, buffer-local defined > (defvar var2 "default") > (setq-local var2 "buffer-local") > (let ((var2 "inside let")) (default-value 'var2)) ;; returns "default" I would expect both snippets to return the same. And the same goes for every two pair of snippets that only differ in whether the form (setq-local varX "buffer-local") is present. So I was no longer sure that the issue was just incomplete or ambiguous documentation, and I wrote all the cases I could think in the last email to see what you think about it. P.S. By the way, I had deleted the previous emails on these thread, so I could not properly reply to the last one, and had to just write to 54399@debbugs.gnu.org instead. What is the proper way to reply to an debbugs email thread that is no longer or never was in your inbox? For the org-mode mail list there is a link on the web archives, but not for debbugs.gnu.org. Is there a quick way from the debbugs package? Or maybe using some of the info in the mbox file, which can be downloaded from the archives in debbugs.gnu.org? Thanks ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-04-12 12:16 ` Ignacio Casso @ 2022-04-12 13:35 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2022-04-12 14:27 ` Ignacio Casso 2022-04-13 0:24 ` Michael Heerdegen 2022-04-12 15:24 ` Eli Zaretskii 1 sibling, 2 replies; 41+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2022-04-12 13:35 UTC (permalink / raw) To: Ignacio Casso; +Cc: michael_heerdegen, Eli Zaretskii, 54399, larsi >> ;; default defined, buffer-local undefined >> (defvar var1 "default") >> (let ((var1 "inside let")) (default-value 'var1)) ;; returns "inside let" >> >> ;; default defined, buffer-local defined >> (defvar var2 "default") >> (setq-local var2 "buffer-local") >> (let ((var2 "inside let")) (default-value 'var2)) ;; returns "default" > > I would expect both snippets to return the same. That's because you expect the "default" in `default-value` refers to the let-nesting dimension rather than the buffer dimension. BTW `set-default-toplevel-value` has a running time that's proportional to the stack depth, whereas `default-value`, like `symbol-value` is constant-time. > P.S. By the way, I had deleted the previous emails on these thread, so I > could not properly reply to the last one, and had to just write to > 54399@debbugs.gnu.org instead. What is the proper way to reply to an > debbugs email thread that is no longer or never was in your inbox? For > the org-mode mail list there is a link on the web archives, but not for > debbugs.gnu.org. Is there a quick way from the debbugs package? Or maybe > using some of the info in the mbox file, which can be downloaded from > the archives in debbugs.gnu.org? Thanks You can M-x gnu-emacs-bug RET 54399 RET and then you should be able to select the message to which you want to reply. [ The name is not `gnu-emacs-bug`, but that's the mnemonic I use, and the completion does the rest => `gnus-read-ephemeral-emacs-bug-group`. ] Stefan ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-04-12 13:35 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2022-04-12 14:27 ` Ignacio Casso 2022-04-12 15:04 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2022-04-13 0:24 ` Michael Heerdegen 1 sibling, 1 reply; 41+ messages in thread From: Ignacio Casso @ 2022-04-12 14:27 UTC (permalink / raw) To: Stefan Monnier; +Cc: michael_heerdegen, 54399, larsi Stefan Monnier <monnier@iro.umontreal.ca> writes: >>> ;; default defined, buffer-local undefined >>> (defvar var1 "default") >>> (let ((var1 "inside let")) (default-value 'var1)) ;; returns "inside let" >>> >>> ;; default defined, buffer-local defined >>> (defvar var2 "default") >>> (setq-local var2 "buffer-local") >>> (let ((var2 "inside let")) (default-value 'var2)) ;; returns "default" >> >> I would expect both snippets to return the same. > > That's because you expect the "default" in `default-value` refers to the > let-nesting dimension rather than the buffer dimension. No, I just expect to refer to any of those consistently, I don't mind which one. If it's the buffer dimension, even inside let bindings, both forms should return "default". If inside let bindings the buffer dimension is "eclipsed", both should return "inside let". If `default-value' inside a let binding just has undefined behavior, it should produce an error, or at least be documented somewhere. But right now is neither of those, and it just depends of whether the current buffer actually has a local value for the variable, which I find inconsistent. ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-04-12 14:27 ` Ignacio Casso @ 2022-04-12 15:04 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2022-04-12 15:27 ` Ignacio Casso 0 siblings, 1 reply; 41+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2022-04-12 15:04 UTC (permalink / raw) To: Ignacio Casso; +Cc: michael_heerdegen, Eli Zaretskii, 54399, larsi >>>> ;; default defined, buffer-local undefined >>>> (defvar var1 "default") >>>> (let ((var1 "inside let")) (default-value 'var1)) ;; returns "inside let" >>>> >>>> ;; default defined, buffer-local defined >>>> (defvar var2 "default") >>>> (setq-local var2 "buffer-local") >>>> (let ((var2 "inside let")) (default-value 'var2)) ;; returns "default" >>> >>> I would expect both snippets to return the same. >> >> That's because you expect the "default" in `default-value` refers to the >> let-nesting dimension rather than the buffer dimension. > > No, I just expect to refer to any of those consistently, I don't mind > which one. If it's the buffer dimension, even inside let bindings, both > forms should return "default". If there's no buffer-local value and `default-value` operates in the buffer-local dimension, why do you expect it to return a different value from `symbol-value`? Stefan ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-04-12 15:04 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2022-04-12 15:27 ` Ignacio Casso 2022-04-12 22:15 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 1 reply; 41+ messages in thread From: Ignacio Casso @ 2022-04-12 15:27 UTC (permalink / raw) To: Stefan Monnier; +Cc: michael_heerdegen, 54399, larsi Stefan Monnier <monnier@iro.umontreal.ca> writes: >>>>> ;; default defined, buffer-local undefined >>>>> (defvar var1 "default") >>>>> (let ((var1 "inside let")) (default-value 'var1)) ;; returns "inside let" >>>>> >>>>> ;; default defined, buffer-local defined >>>>> (defvar var2 "default") >>>>> (setq-local var2 "buffer-local") >>>>> (let ((var2 "inside let")) (default-value 'var2)) ;; returns "default" >>>> >>>> I would expect both snippets to return the same. >>> >>> That's because you expect the "default" in `default-value` refers to the >>> let-nesting dimension rather than the buffer dimension. >> >> No, I just expect to refer to any of those consistently, I don't mind >> which one. If it's the buffer dimension, even inside let bindings, both >> forms should return "default". > > If there's no buffer-local value and `default-value` operates in the > buffer-local dimension, why do you expect it to return a different value > from `symbol-value`? > > > Stefan Probably because I don't really understand all the concepts involved here. But I expect functions that operate on the default value of the buffer-local dimension to behave the same way regardless of whether the current buffer happens to have actually a local value. So if `default-value' returns something different as `symbol-value' when there is a buffer-local value, I expect the same to occur when there is no buffer-local value. But never mind, I just wanted to ensure that the current behavior was the expected one before updating the docstring for `default-boundp', and you already confirmed that. And this is an uncommon corner case for which I can't think of real use cases, aside from the one of autoloading inside a let binding of a variable a file which defines that (custom) variable, for which we are already using `default-toplevel-value' and `set-default-toplevel-value'. So let's leave it at that. ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-04-12 15:27 ` Ignacio Casso @ 2022-04-12 22:15 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2022-04-13 15:26 ` Ignacio Casso 0 siblings, 1 reply; 41+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2022-04-12 22:15 UTC (permalink / raw) To: Ignacio Casso; +Cc: michael_heerdegen, Eli Zaretskii, 54399, larsi > Probably because I don't really understand all the concepts involved > here. But I expect functions that operate on the default value of the > buffer-local dimension to behave the same way regardless of whether the > current buffer happens to have actually a local value. You're looking at the dimensions in the wrong way. It's like when we split a window in two. Some persons will say it's split vertically (because the two new windows are stacked vertically) while others will say it's split horizontally (because the line delimiting the two new windows is horizontal). When I say that `default-value` operates on the buffer-localness, I mean that the difference `default-value` and `symbol-value` only differ with respect to whether they consider a buffer-local value or not. They're both stuck in the current (i.e. most deeply nested) let-binding in either case. IOW, the choice between `default-value` and `symbol-value` lets you walk along the line between buffer-local and not-buffer-local, but it does not let you walk up the stack of nested let-bindings. Only `default-toplevel-value` lets you do that (and it only does that on the non-buffer-local part of the space: there is nothing like `symbol-toplevel-value` which would let you find the "top-level buffer-local value"). > But never mind, I just wanted to ensure that the current behavior was > the expected one It is, yes. Stefan ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-04-12 22:15 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2022-04-13 15:26 ` Ignacio Casso 0 siblings, 0 replies; 41+ messages in thread From: Ignacio Casso @ 2022-04-13 15:26 UTC (permalink / raw) To: Stefan Monnier; +Cc: michael_heerdegen, 54399, larsi > When I say that `default-value` operates on the buffer-localness, I mean > that the difference `default-value` and `symbol-value` only differ with > respect to whether they consider a buffer-local value or not. > > They're both stuck in the current (i.e. most deeply nested) let-binding > in either case. > > IOW, the choice between `default-value` and `symbol-value` lets you walk > along the line between buffer-local and not-buffer-local, but it does > not let you walk up the stack of nested let-bindings. > Only `default-toplevel-value` lets you do that (and it only does that on > the non-buffer-local part of the space: there is nothing like > `symbol-toplevel-value` which would let you find the "top-level > buffer-local value"). Thanks, I get it now. I didn't know that there were different stacks of let-bindings for a variable, one for the default value, and another one for each buffer-local value. I though that there were only the default value, the buffer-local value for some buffers, and a common stack of let-bindings that shadowed all of them. ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-04-12 13:35 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2022-04-12 14:27 ` Ignacio Casso @ 2022-04-13 0:24 ` Michael Heerdegen 2022-04-13 3:26 ` Glenn Morris 1 sibling, 1 reply; 41+ messages in thread From: Michael Heerdegen @ 2022-04-13 0:24 UTC (permalink / raw) To: Ignacio Casso; +Cc: larsi, 54399, Stefan Monnier Stefan Monnier <monnier@iro.umontreal.ca> writes: > You can M-x gnu-emacs-bug RET 54399 RET and then you should be able to > select the message to which you want to reply. > [ The name is not `gnu-emacs-bug`, but that's the mnemonic I use, and > the completion does the rest => `gnus-read-ephemeral-emacs-bug-group`. ] That, or the "debbugs-gnu.el" bug browser interface. But then it's best to use Gnus or Rmail. If your mail client allows it you can also read the newsgroup gnu.emacs.bug (or gmane.emacs.bug), look for your message and answer per mail "from there". (AFAIU, there is a "References" named mail header that controls the associations between messages. Gnus allows to show this (normally hidden) header. When your mail program allows to use given references you copy from somewhere as part of the mail header that composed mail should be correctly classified as an answer to that message.) Michael. ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-04-13 0:24 ` Michael Heerdegen @ 2022-04-13 3:26 ` Glenn Morris 2022-04-13 3:43 ` Michael Heerdegen 0 siblings, 1 reply; 41+ messages in thread From: Glenn Morris @ 2022-04-13 3:26 UTC (permalink / raw) To: Michael Heerdegen; +Cc: larsi, Ignacio Casso, 54399, Stefan Monnier Michael Heerdegen wrote: > If your mail client allows it you can also read the newsgroup > gnu.emacs.bug (or gmane.emacs.bug), look for your message and answer per > mail "from there". Please don't post via usenet for bug reporting or commenting on issues. It creates various technical problems. Please forget that gnu.emacs.bug exists. ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-04-13 3:26 ` Glenn Morris @ 2022-04-13 3:43 ` Michael Heerdegen 0 siblings, 0 replies; 41+ messages in thread From: Michael Heerdegen @ 2022-04-13 3:43 UTC (permalink / raw) To: Glenn Morris; +Cc: larsi, Ignacio Casso, 54399, Stefan Monnier Glenn Morris <rgm@gnu.org> writes: > > If your mail client allows it you can also read the newsgroup > > gnu.emacs.bug (or gmane.emacs.bug), look for your message and answer per > > mail "from there". > > Please don't post via usenet for bug reporting or commenting on issues. > It creates various technical problems. > Please forget that gnu.emacs.bug exists. Thanks for the important hint. That's why I said "answer _per_mail_". But with the right setup one can have a convenient workflow. I more or less never post via News, but reading the bug threads as Newsgroup is just too convenient, for reasons like this one (how to respond to the correct subthread). If you can't ensure that you never post via usenet, then it's better to forget gnu.emacs.bug, agreed. Michael. ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-04-12 12:16 ` Ignacio Casso 2022-04-12 13:35 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2022-04-12 15:24 ` Eli Zaretskii 2022-04-13 17:22 ` Ignacio Casso 1 sibling, 1 reply; 41+ messages in thread From: Eli Zaretskii @ 2022-04-12 15:24 UTC (permalink / raw) To: Ignacio Casso; +Cc: michael_heerdegen, larsi, 54399, monnier > From: Ignacio Casso <ignaciocasso@hotmail.com> > Cc: Stefan Monnier <monnier@iro.umontreal.ca>, 54399@debbugs.gnu.org, > larsi@gnus.org, michael_heerdegen@web.de > Date: Tue, 12 Apr 2022 14:16:34 +0200 > > P.S. By the way, I had deleted the previous emails on these thread, so I > could not properly reply to the last one, and had to just write to > 54399@debbugs.gnu.org instead. What is the proper way to reply to an > debbugs email thread that is no longer or never was in your inbox? You can download each message of the bug discussion as an mbox file, and then visit it in your email agent. ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-04-12 15:24 ` Eli Zaretskii @ 2022-04-13 17:22 ` Ignacio Casso 0 siblings, 0 replies; 41+ messages in thread From: Ignacio Casso @ 2022-04-13 17:22 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, larsi, 54399, monnier Thanks! It seems mu4e can't visit mbox files, but I'm trying it right now with Thunderbird. Let's hope it works. On 12/4/22 17:24, Eli Zaretskii wrote: >> From: Ignacio Casso <ignaciocasso@hotmail.com> >> Cc: Stefan Monnier <monnier@iro.umontreal.ca>, 54399@debbugs.gnu.org, >> larsi@gnus.org, michael_heerdegen@web.de >> Date: Tue, 12 Apr 2022 14:16:34 +0200 >> >> P.S. By the way, I had deleted the previous emails on these thread, so I >> could not properly reply to the last one, and had to just write to >> 54399@debbugs.gnu.org instead. What is the proper way to reply to an >> debbugs email thread that is no longer or never was in your inbox? > You can download each message of the bug discussion as an mbox file, > and then visit it in your email agent. > > > ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-04-12 9:13 ` Ignacio Casso 2022-04-12 11:38 ` Eli Zaretskii @ 2022-04-12 13:19 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2022-04-12 13:51 ` Ignacio Casso 1 sibling, 1 reply; 41+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2022-04-12 13:19 UTC (permalink / raw) To: Ignacio Casso; +Cc: Michael Heerdegen, larsi, 54399 > Should I go ahead and just update the docstrings so that they reflect > this behavior, and then close this bug report? Or do you think that the > code should be changed too? For the latter I don't think I could help, > since that code is too low level for me. If you can send a patch for the docs which addresses your concerns that would be very helpful. Stefan ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-04-12 13:19 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2022-04-12 13:51 ` Ignacio Casso 2022-04-12 15:22 ` Eli Zaretskii 0 siblings, 1 reply; 41+ messages in thread From: Ignacio Casso @ 2022-04-12 13:51 UTC (permalink / raw) To: Stefan Monnier; +Cc: Michael Heerdegen, larsi, 54399 [-- Attachment #1: Type: text/plain, Size: 899 bytes --] Stefan Monnier <monnier@iro.umontreal.ca> writes: >> Should I go ahead and just update the docstrings so that they reflect >> this behavior, and then close this bug report? Or do you think that the >> code should be changed too? For the latter I don't think I could help, >> since that code is too low level for me. > > If you can send a patch for the docs which addresses your concerns that > would be very helpful. > > > Stefan Here is a first attempt of a patch. It updates the docstrings for those functions and makes some other changes regarding the original `defcustom' issue. For some places were I was not sure if a change was necessary, I just wrote a comment to mark them and maybe discuss later. I also would replace in other files `set-default' with `set-default-toplevel-value', when it is used inside a lambda expression that is passed as :set argument for `defcustom'. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: Patch for bug#54399 --] [-- Type: text/x-diff, Size: 7190 bytes --] From 348f43797e3a126471681e1f5be00bc3fd34914d Mon Sep 17 00:00:00 2001 From: Ignacio <ignaciocasso@hotmail.com> Date: Tue, 12 Apr 2022 10:48:32 +0200 Subject: [PATCH] updated documentation regarding default toplevel values of variables --- lisp/custom.el | 26 +++++++++++++------------- src/data.c | 16 +++++++++++----- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index 76c14831ca..e23ca7915a 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -68,7 +68,7 @@ custom-initialize-default (defun custom-initialize-set (symbol exp) "Initialize SYMBOL based on EXP. If the symbol doesn't have a default binding already, -then set it using its `:set' function (or `set-default' if it has none). +then set it using its `:set' function (or `set-default-toplevel-value' if it has none). The value is either the value in the symbol's `saved-value' property, if any, or the value of EXP." (condition-case nil @@ -81,7 +81,7 @@ custom-initialize-set (defun custom-initialize-reset (symbol exp) "Initialize SYMBOL based on EXP. -Set the symbol, using its `:set' function (or `set-default' if it has none). +Set the symbol, using its `:set' function (or `set-default-toplevel-value' if it has none). The value is either the symbol's current value (as obtained using the `:get' function), if any, or the value in the symbol's `saved-value' property if any, @@ -100,7 +100,7 @@ custom-initialize-changed "Initialize SYMBOL with EXP. Like `custom-initialize-reset', but only use the `:set' function if not using the standard setting. -For the standard setting, use `set-default'." +For the standard setting, use `set-default-toplevel-value'." (condition-case nil (let ((def (default-toplevel-value symbol))) (funcall (or (get symbol 'custom-set) #'set-default-toplevel-value) @@ -114,7 +114,7 @@ custom-initialize-changed symbol (eval (car (get symbol 'saved-value))))) (t - (set-default symbol (eval exp))))))) + (set-default-toplevel-value symbol (eval exp))))))) (defvar custom-delayed-init-variables nil "List of variables whose initialization is pending until startup. @@ -262,11 +262,11 @@ defcustom when using the Customize user interface. It takes two arguments, the symbol to set and the value to give it. The function should not modify its value argument destructively. The default choice - of function is `set-default'. + of function is `set-default-toplevel-value'. :get VALUE should be a function to extract the value of symbol. The function takes one argument, a symbol, and should return the current value for that symbol. The default choice of function - is `default-value'. + is `default-toplevel-value'. :require VALUE should be a feature symbol. If you save a value for this option, then when your init file loads the value, @@ -717,7 +717,7 @@ custom-set-default (if custom-local-buffer (with-current-buffer custom-local-buffer (set variable value)) - (set-default variable value))) + (set-default-toplevel-value variable value))) (defun custom-set-minor-mode (variable value) ":set function for minor mode variables. @@ -752,7 +752,7 @@ customize-mark-to-save Return non-nil if the `saved-value' property actually changed." (custom-load-symbol symbol) - (let* ((get (or (get symbol 'custom-get) #'default-value)) + (let* ((get (or (get symbol 'custom-get) #'default-toplevel-value)) (value (funcall get symbol)) (saved (get symbol 'saved-value)) (standard (get symbol 'standard-value)) @@ -779,7 +779,7 @@ customize-mark-as-set Return non-nil if the `customized-value' property actually changed." (custom-load-symbol symbol) - (let* ((get (or (get symbol 'custom-get) #'default-value)) + (let* ((get (or (get symbol 'custom-get) #'default-toplevel-value)) (value (funcall get symbol)) (customized (get symbol 'customized-value)) (old (or (get symbol 'saved-value) (get symbol 'standard-value)))) @@ -1054,12 +1054,12 @@ custom-theme-set-variables ;; Rogue variable, set it now. (put symbol 'force-value t) (funcall set symbol (eval value))) - ((default-boundp symbol) + ((default-boundp symbol) ; condition-case + default-toplevel-value? ;; Something already set this, overwrite it. (funcall set symbol (eval value)))) (error (message "Error setting %s: %s" symbol data))) - (and (or now (default-boundp symbol)) + (and (or now (default-boundp symbol)) ; condition-case + default-toplevel-value? (put symbol 'variable-comment comment))))))) (defvar custom--sort-vars-table) @@ -1608,8 +1608,8 @@ custom-theme-recalc-variable (setq valspec (get variable 'standard-value))) (if (and valspec (or (get variable 'force-value) - (default-boundp variable))) - (funcall (or (get variable 'custom-set) #'set-default) variable + (default-boundp variable))) ; (condition-case ... default-toplevel-value ...) ? + (funcall (or (get variable 'custom-set) #'set-default) variable ; set-default-toplevel-value? (eval (car valspec)))))) (defun custom-theme-recalc-face (face) diff --git a/src/data.c b/src/data.c index f06b561dcc..b73a997341 100644 --- a/src/data.c +++ b/src/data.c @@ -1927,9 +1927,10 @@ default_value (Lisp_Object symbol) DEFUN ("default-boundp", Fdefault_boundp, Sdefault_boundp, 1, 1, 0, doc: /* Return t if SYMBOL has a non-void default value. -A variable may have a buffer-local or a `let'-bound local value. This -function says whether the variable has a non-void value outside of the -current context. Also see `default-value'. */) +This is the value that is seen in buffers that do not have their own +values for this variable. Let bindings may shadow this default value. +To take them into account, use `default-toplevel-value' together with +`condition-case' instead. */) (Lisp_Object symbol) { register Lisp_Object value; @@ -1942,7 +1943,9 @@ DEFUN ("default-value", Fdefault_value, Sdefault_value, 1, 1, 0, doc: /* Return SYMBOL's default value. This is the value that is seen in buffers that do not have their own values for this variable. The default value is meaningful for variables with -local bindings in certain buffers. */) +local bindings in certain buffers. Let bindings may shadow this +default value. To take them into account, use +`default-toplevel-value' instead. */) (Lisp_Object symbol) { Lisp_Object value = default_value (symbol); @@ -2045,7 +2048,10 @@ set_default_internal (Lisp_Object symbol, Lisp_Object value, DEFUN ("set-default", Fset_default, Sset_default, 2, 2, 0, doc: /* Set SYMBOL's default value to VALUE. SYMBOL and VALUE are evaluated. The default value is seen in buffers that do not have their own values -for this variable. */) +for this variable. This function may no behave as expected inside let +bindings of SYMBOL. To take them into account, use +`set-default-toplevel-value' instead. */) + (Lisp_Object symbol, Lisp_Object value) { set_default_internal (symbol, value, SET_INTERNAL_SET); -- 2.25.1 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-04-12 13:51 ` Ignacio Casso @ 2022-04-12 15:22 ` Eli Zaretskii 2022-04-13 0:06 ` Michael Heerdegen 0 siblings, 1 reply; 41+ messages in thread From: Eli Zaretskii @ 2022-04-12 15:22 UTC (permalink / raw) To: Ignacio Casso; +Cc: michael_heerdegen, larsi, 54399, monnier > Date: Tue, 12 Apr 2022 15:51:17 +0200 > Cc: Michael Heerdegen <michael_heerdegen@web.de>, larsi@gnus.org, > 54399@debbugs.gnu.org > > DEFUN ("set-default", Fset_default, Sset_default, 2, 2, 0, > doc: /* Set SYMBOL's default value to VALUE. SYMBOL and VALUE are evaluated. > The default value is seen in buffers that do not have their own values > -for this variable. */) > +for this variable. This function may no behave as expected inside let ^ ^^ Typo: should be "not". Also, only one space between sentences. ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-04-12 15:22 ` Eli Zaretskii @ 2022-04-13 0:06 ` Michael Heerdegen 2022-04-13 12:08 ` Ignacio Casso 0 siblings, 1 reply; 41+ messages in thread From: Michael Heerdegen @ 2022-04-13 0:06 UTC (permalink / raw) To: Eli Zaretskii; +Cc: larsi, 54399, Ignacio Casso, monnier Eli Zaretskii <eliz@gnu.org> writes: > > +for this variable. This function may no behave as expected inside let > ^ ^^ > Typo: should be "not". Also, only one space between sentences. And > +values for this variable. Let bindings may shadow this default value. ^^^^^^^^^^^^ "Let-bindings" (with a hyphen; appear several times). But the more interesting question is whether the changes per se are all correct. Michael. ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-04-13 0:06 ` Michael Heerdegen @ 2022-04-13 12:08 ` Ignacio Casso 2022-05-12 2:32 ` Lars Ingebrigtsen 0 siblings, 1 reply; 41+ messages in thread From: Ignacio Casso @ 2022-04-13 12:08 UTC (permalink / raw) To: Michael Heerdegen; +Cc: larsi, 54399, monnier Michael Heerdegen <michael_heerdegen@web.de> writes: > Eli Zaretskii <eliz@gnu.org> writes: > >> > +for this variable. This function may no behave as expected inside let >> ^ ^^ >> Typo: should be "not". Also, only one space between sentences. > Fixed > >> +values for this variable. Let bindings may shadow this default value. > ^^^^^^^^^^^^ > > "Let-bindings" (with a hyphen; appear several times). > Fixed > But the more interesting question is whether the changes per se are all > correct. > Most things are corrections to the docstrings. I explain each change below, as I should probably have done earlier: > (defun custom-initialize-set (symbol exp) > "Initialize SYMBOL based on EXP. > If the symbol doesn't have a default binding already, > -then set it using its `:set' function (or `set-default' if it has none). > +then set it using its `:set' function (or `set-default-toplevel-value' if it has none). > The value is either the value in the symbol's `saved-value' property, > if any, or the value of EXP." > (condition-case nil docstring correction, the function used is actually `set-default-toplevel-value' > (defun custom-initialize-reset (symbol exp) > "Initialize SYMBOL based on EXP. > -Set the symbol, using its `:set' function (or `set-default' if it has none). > +Set the symbol, using its `:set' function (or `set-default-toplevel-value' if it has none). > The value is either the symbol's current value > (as obtained using the `:get' function), if any, > or the value in the symbol's `saved-value' property if any, Same > (defun custom-initialize-changed (symbol exp) > "Initialize SYMBOL with EXP. > Like `custom-initialize-reset', but only use the `:set' function if > not using the standard setting. > -For the standard setting, use `set-default'." > +For the standard setting, use `set-default-toplevel-value'." > (condition-case nil > (let ((def (default-toplevel-value symbol))) > (funcall (or (get symbol 'custom-set) #'set-default-toplevel-value) and > symbol > (eval (car (get symbol 'saved-value))))) > (t > - (set-default symbol (eval exp))))))) > + (set-default-toplevel-value symbol (eval exp))))))) > Everywhere else `set-default-toplevel-value' is used instead, so I have changed it here too. > @@ -262,11 +262,11 @@ defcustom > :set VALUE should be a function to set the value of the symbol > when using the Customize user interface. It takes two arguments, > the symbol to set and the value to give it. The function should > not modify its value argument destructively. The default choice > - of function is `set-default'. > + of function is `set-default-toplevel-value'. Same correction > :get VALUE should be a function to extract the value of symbol. > The function takes one argument, a symbol, and should return > the current value for that symbol. The default choice of function > - is `default-value'. > + is `default-toplevel-value'. Similar correction > @@ -717,7 +717,7 @@ custom-set-default > (if custom-local-buffer > (with-current-buffer custom-local-buffer > (set variable value)) > - (set-default variable value))) > + (set-default-toplevel-value variable value))) Here and in the rest of the changes in custom.el I have made or suggested one of the following changes: `default-value' -> `default-toplevel-value' `set-default' -> `set-default-toplevel-value' `default-boundp' -> (condition-case nil (or (default-toplevel-value) t) (void-variable nil)) But I'm not really sure of when those functions are used, so I don't know whether they are necessary. I actually made the changes just to get the feedback, we can discard them if you don't think that they are an improvement or that it is worth to invest the time in finding out whether they are an improvement. > @@ -752,7 +752,7 @@ customize-mark-to-save > > Return non-nil if the `saved-value' property actually changed." > (custom-load-symbol symbol) > - (let* ((get (or (get symbol 'custom-get) #'default-value)) > + (let* ((get (or (get symbol 'custom-get) #'default-toplevel-value)) > (value (funcall get symbol)) > (saved (get symbol 'saved-value)) > (standard (get symbol 'standard-value)) See last comment > @@ -779,7 +779,7 @@ customize-mark-as-set > > Return non-nil if the `customized-value' property actually changed." > (custom-load-symbol symbol) > - (let* ((get (or (get symbol 'custom-get) #'default-value)) > + (let* ((get (or (get symbol 'custom-get) #'default-toplevel-value)) > (value (funcall get symbol)) > (customized (get symbol 'customized-value)) > (old (or (get symbol 'saved-value) (get symbol 'standard-value)))) See last comment > @@ -1054,12 +1054,12 @@ custom-theme-set-variables > ;; Rogue variable, set it now. > (put symbol 'force-value t) > (funcall set symbol (eval value))) > - ((default-boundp symbol) > + ((default-boundp symbol) ; condition-case + default-toplevel-value? > ;; Something already set this, overwrite it. > (funcall set symbol (eval value)))) > (error > (message "Error setting %s: %s" symbol data))) > - (and (or now (default-boundp symbol)) > + (and (or now (default-boundp symbol)) ; condition-case + default-toplevel-value? > (put symbol 'variable-comment comment))))))) See last comment > > (defvar custom--sort-vars-table) > @@ -1608,8 +1608,8 @@ custom-theme-recalc-variable > (setq valspec (get variable 'standard-value))) > (if (and valspec > (or (get variable 'force-value) > - (default-boundp variable))) > - (funcall (or (get variable 'custom-set) #'set-default) variable > + (default-boundp variable))) ; (condition-case ... default-toplevel-value ...) ? > + (funcall (or (get variable 'custom-set) #'set-default) variable ; set-default-toplevel-value? > (eval (car valspec)))))) See last comment > diff --git a/src/data.c b/src/data.c > index f06b561dcc..b73a997341 100644 > --- a/src/data.c > +++ b/src/data.c > @@ -1927,9 +1927,10 @@ default_value (Lisp_Object symbol) > > DEFUN ("default-boundp", Fdefault_boundp, Sdefault_boundp, 1, 1, 0, > doc: /* Return t if SYMBOL has a non-void default value. > -A variable may have a buffer-local or a `let'-bound local value. This > -function says whether the variable has a non-void value outside of the > -current context. Also see `default-value'. */) > +This is the value that is seen in buffers that do not have their own > +values for this variable. Let-bindings may shadow this default value. > +To take them into account, use `default-toplevel-value' together with > +`condition-case' instead. */) > (Lisp_Object symbol) > { > register Lisp_Object value; Corrected `default-boundp' docstring, which said that it can be used to check if a variable is non-void outside a let-binding context, which is false. I just reverted to Emacs 27's version, which was correct. Also, in this docstring and the ones for `default-value' and `set-default', I update them to suggest using their "toplevel" counterparts when let-bindings need to be taken into account. But I probably use the wrong vocabulary to do so, and that information is already on the pertinent section of the manual, so we can discard these changes too if you don't think they belong in the docstrings. > @@ -1942,7 +1943,9 @@ DEFUN ("default-value", Fdefault_value, Sdefault_value, 1, 1, 0, > doc: /* Return SYMBOL's default value. > This is the value that is seen in buffers that do not have their own values > for this variable. The default value is meaningful for variables with > -local bindings in certain buffers. */) > +local bindings in certain buffers. Let-bindings may shadow this > +default value. To take them into account, use > +`default-toplevel-value' instead. */) > (Lisp_Object symbol) > { > Lisp_Object value = default_value (symbol); See last comment > @@ -2045,7 +2048,10 @@ set_default_internal (Lisp_Object symbol, Lisp_Object value, > DEFUN ("set-default", Fset_default, Sset_default, 2, 2, 0, > doc: /* Set SYMBOL's default value to VALUE. SYMBOL and VALUE are evaluated. > The default value is seen in buffers that do not have their own values > -for this variable. */) > +for this variable. This function may not behave as expected inside let-bindings > +of SYMBOL. To take them into account, use > +`set-default-toplevel-value' instead. */) > + See last comment I've also made some new changes in customize.texi after I sent this patch. They are equivalent to those in the docstring of `defcustom'. ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-04-13 12:08 ` Ignacio Casso @ 2022-05-12 2:32 ` Lars Ingebrigtsen 2022-05-12 6:58 ` Ignacio Casso 0 siblings, 1 reply; 41+ messages in thread From: Lars Ingebrigtsen @ 2022-05-12 2:32 UTC (permalink / raw) To: Ignacio Casso; +Cc: Michael Heerdegen, Eli Zaretskii, 54399, monnier Ignacio Casso <ignaciocasso@hotmail.com> writes: > I've also made some new changes in customize.texi after I sent this > patch. They are equivalent to those in the docstring of > `defcustom'. I didn't see any new version of the proposed patch in this bug report? -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-05-12 2:32 ` Lars Ingebrigtsen @ 2022-05-12 6:58 ` Ignacio Casso 2022-05-12 7:34 ` Eli Zaretskii 0 siblings, 1 reply; 41+ messages in thread From: Ignacio Casso @ 2022-05-12 6:58 UTC (permalink / raw) To: Lars Ingebrigtsen; +Cc: Michael Heerdegen, Eli Zaretskii, 54399, monnier [-- Attachment #1: Type: text/plain, Size: 577 bytes --] >> I've also made some new changes in customize.texi after I sent this >> patch. They are equivalent to those in the docstring of >> `defcustom'. > > I didn't see any new version of the proposed patch in this bug report? Sorry, I was waiting for more feedback in other parts of the patch before sending it. I send a new version now with the typos you pointed out fixed, and the changes in customize.texi that I said. I've also dropped some of the changes in the previous path that I don't think that were actually necessary, to keep the patch and review simpler. --Ignacio [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: Patch 54399 --] [-- Type: text/x-diff, Size: 6727 bytes --] From 9ebf1065c2970f688fdcafd6278ae5e239265065 Mon Sep 17 00:00:00 2001 From: Ignacio Casso <ignaciocasso@hotmail.com> Date: Thu, 12 May 2022 08:41:44 +0200 Subject: [PATCH] updated some documentation regarding customize and default values --- doc/lispref/customize.texi | 8 ++++---- lisp/custom.el | 18 +++++++++--------- src/data.c | 4 ++-- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/doc/lispref/customize.texi b/doc/lispref/customize.texi index 54059d7b6e..06a2f5365d 100644 --- a/doc/lispref/customize.texi +++ b/doc/lispref/customize.texi @@ -376,7 +376,7 @@ Variable Definitions the value properly for this option (which may not mean simply setting the option as a Lisp variable); preferably, though, it should not modify its value argument destructively. The default for -@var{setfunction} is @code{set-default}. +@var{setfunction} is @code{set-default-toplevel-value}. If you specify this keyword, the variable's documentation string should describe how to do the same job in hand-written Lisp code. @@ -387,7 +387,7 @@ Variable Definitions option. The function @var{getfunction} should take one argument, a symbol, and should return whatever customize should use as the current value for that symbol (which need not be the symbol's Lisp -value). The default is @code{default-value}. +value). The default is @code{default-toplevel-value}. You have to really understand the workings of Custom to use @code{:get} correctly. It is meant for values that are treated in @@ -409,7 +409,7 @@ Variable Definitions @item custom-initialize-default Like @code{custom-initialize-set}, but use the function -@code{set-default} to set the variable, instead of the variable's +@code{set-default-toplevel-value} to set the variable, instead of the variable's @code{:set} function. This is the usual choice for a variable whose @code{:set} function enables or disables a minor mode; with this choice, defining the variable will not call the minor mode function, but @@ -424,7 +424,7 @@ Variable Definitions @item custom-initialize-changed Use the @code{:set} function to initialize the variable, if it is already set or has been customized; otherwise, just use -@code{set-default}. +@code{set-default-toplevel-value}. @item custom-initialize-delay This function behaves like @code{custom-initialize-set}, but it diff --git a/lisp/custom.el b/lisp/custom.el index 76c14831ca..2ab7c69d00 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -68,7 +68,7 @@ custom-initialize-default (defun custom-initialize-set (symbol exp) "Initialize SYMBOL based on EXP. If the symbol doesn't have a default binding already, -then set it using its `:set' function (or `set-default' if it has none). +then set it using its `:set' function (or `set-default-toplevel-value' if it has none). The value is either the value in the symbol's `saved-value' property, if any, or the value of EXP." (condition-case nil @@ -81,7 +81,7 @@ custom-initialize-set (defun custom-initialize-reset (symbol exp) "Initialize SYMBOL based on EXP. -Set the symbol, using its `:set' function (or `set-default' if it has none). +Set the symbol, using its `:set' function (or `set-default-toplevel-value' if it has none). The value is either the symbol's current value (as obtained using the `:get' function), if any, or the value in the symbol's `saved-value' property if any, @@ -100,7 +100,7 @@ custom-initialize-changed "Initialize SYMBOL with EXP. Like `custom-initialize-reset', but only use the `:set' function if not using the standard setting. -For the standard setting, use `set-default'." +For the standard setting, use `set-default-toplevel-value'." (condition-case nil (let ((def (default-toplevel-value symbol))) (funcall (or (get symbol 'custom-set) #'set-default-toplevel-value) @@ -114,7 +114,7 @@ custom-initialize-changed symbol (eval (car (get symbol 'saved-value))))) (t - (set-default symbol (eval exp))))))) + (set-default-toplevel-value symbol (eval exp))))))) (defvar custom-delayed-init-variables nil "List of variables whose initialization is pending until startup. @@ -262,11 +262,11 @@ defcustom when using the Customize user interface. It takes two arguments, the symbol to set and the value to give it. The function should not modify its value argument destructively. The default choice - of function is `set-default'. + of function is `set-default-toplevel-value'. :get VALUE should be a function to extract the value of symbol. The function takes one argument, a symbol, and should return the current value for that symbol. The default choice of function - is `default-value'. + is `default-toplevel-value'. :require VALUE should be a feature symbol. If you save a value for this option, then when your init file loads the value, @@ -717,7 +717,7 @@ custom-set-default (if custom-local-buffer (with-current-buffer custom-local-buffer (set variable value)) - (set-default variable value))) + (set-default-toplevel-value variable value))) (defun custom-set-minor-mode (variable value) ":set function for minor mode variables. @@ -752,7 +752,7 @@ customize-mark-to-save Return non-nil if the `saved-value' property actually changed." (custom-load-symbol symbol) - (let* ((get (or (get symbol 'custom-get) #'default-value)) + (let* ((get (or (get symbol 'custom-get) #'default-toplevel-value)) (value (funcall get symbol)) (saved (get symbol 'saved-value)) (standard (get symbol 'standard-value)) @@ -779,7 +779,7 @@ customize-mark-as-set Return non-nil if the `customized-value' property actually changed." (custom-load-symbol symbol) - (let* ((get (or (get symbol 'custom-get) #'default-value)) + (let* ((get (or (get symbol 'custom-get) #'default-toplevel-value)) (value (funcall get symbol)) (customized (get symbol 'customized-value)) (old (or (get symbol 'saved-value) (get symbol 'standard-value)))) diff --git a/src/data.c b/src/data.c index 72dcf6f878..9b36ecc1b2 100644 --- a/src/data.c +++ b/src/data.c @@ -1939,9 +1939,9 @@ default_value (Lisp_Object symbol) DEFUN ("default-boundp", Fdefault_boundp, Sdefault_boundp, 1, 1, 0, doc: /* Return t if SYMBOL has a non-void default value. -A variable may have a buffer-local or a `let'-bound local value. This +A variable may have a buffer-local value. This function says whether the variable has a non-void value outside of the -current context. Also see `default-value'. */) +current buffer context. Also see `default-value'. */) (Lisp_Object symbol) { register Lisp_Object value; -- 2.25.1 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-05-12 6:58 ` Ignacio Casso @ 2022-05-12 7:34 ` Eli Zaretskii 2022-05-12 8:14 ` Ignacio Casso 0 siblings, 1 reply; 41+ messages in thread From: Eli Zaretskii @ 2022-05-12 7:34 UTC (permalink / raw) To: Ignacio Casso; +Cc: michael_heerdegen, larsi, 54399, monnier > From: Ignacio Casso <ignaciocasso@hotmail.com> > Cc: Michael Heerdegen <michael_heerdegen@web.de>, Eli Zaretskii > <eliz@gnu.org>, 54399@debbugs.gnu.org, monnier@iro.umontreal.ca > Date: Thu, 12 May 2022 08:58:09 +0200 > > >> I've also made some new changes in customize.texi after I sent this > >> patch. They are equivalent to those in the docstring of > >> `defcustom'. > > > > I didn't see any new version of the proposed patch in this bug report? > > Sorry, I was waiting for more feedback in other parts of the patch > before sending it. I send a new version now with the typos you pointed > out fixed, and the changes in customize.texi that I said. I've also > dropped some of the changes in the previous path that I don't think that > were actually necessary, to keep the patch and review simpler. This doesn't just change documentation, it also changes some code. ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-05-12 7:34 ` Eli Zaretskii @ 2022-05-12 8:14 ` Ignacio Casso 2022-05-12 8:36 ` Eli Zaretskii 0 siblings, 1 reply; 41+ messages in thread From: Ignacio Casso @ 2022-05-12 8:14 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, larsi, 54399, monnier >> >> I've also made some new changes in customize.texi after I sent this >> >> patch. They are equivalent to those in the docstring of >> >> `defcustom'. >> > >> > I didn't see any new version of the proposed patch in this bug report? >> >> Sorry, I was waiting for more feedback in other parts of the patch >> before sending it. I send a new version now with the typos you pointed >> out fixed, and the changes in customize.texi that I said. I've also >> dropped some of the changes in the previous path that I don't think that >> were actually necessary, to keep the patch and review simpler. > > This doesn't just change documentation, it also changes some code. Do you say it because of the commit message? I was waiting until you agreed on the patch to write a proper one following the guidelines. Or if you want a patch with only documentation changes, I can update it, but the changes are just using the toplevel versions in a few places that were missing. --Ignacio ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-05-12 8:14 ` Ignacio Casso @ 2022-05-12 8:36 ` Eli Zaretskii 2022-05-12 8:41 ` Ignacio Casso 0 siblings, 1 reply; 41+ messages in thread From: Eli Zaretskii @ 2022-05-12 8:36 UTC (permalink / raw) To: Ignacio Casso; +Cc: michael_heerdegen, larsi, 54399, monnier > From: Ignacio Casso <ignaciocasso@hotmail.com> > Cc: larsi@gnus.org, michael_heerdegen@web.de, 54399@debbugs.gnu.org, > monnier@iro.umontreal.ca > Date: Thu, 12 May 2022 10:14:13 +0200 > > > This doesn't just change documentation, it also changes some code. > > Do you say it because of the commit message? No, because of this: > - (let* ((get (or (get symbol 'custom-get) #'default-value)) > + (let* ((get (or (get symbol 'custom-get) #'default-toplevel-value)) and this: > @@ -114,7 +114,7 @@ custom-initialize-changed > symbol > (eval (car (get symbol 'saved-value))))) > (t > - (set-default symbol (eval exp))))))) > + (set-default-toplevel-value symbol (eval exp))))))) and several similar changes. > I was waiting until you agreed on the patch to write a proper one > following the guidelines. > > Or if you want a patch with only documentation changes, I can > update it, but the changes are just using the toplevel versions in a > few places that were missing. My point is that you seemed to be sating that you suggest a documentation change, but the changeset actually changes some code. So I'm not sure anymore what is this changeset about. Perhaps I forgot what we were discussing at the beginning, since that was quite some time ago. Can you remind? ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-05-12 8:36 ` Eli Zaretskii @ 2022-05-12 8:41 ` Ignacio Casso 2022-05-12 9:40 ` Eli Zaretskii 2022-06-09 15:02 ` Lars Ingebrigtsen 0 siblings, 2 replies; 41+ messages in thread From: Ignacio Casso @ 2022-05-12 8:41 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, larsi, 54399, monnier > My point is that you seemed to be sating that you suggest a > documentation change, but the changeset actually changes some code. > So I'm not sure anymore what is this changeset about. Perhaps I > forgot what we were discussing at the beginning, since that was quite > some time ago. Can you remind? Sure. It began as a bug report, but after you explained things to me, all that was left were some mismatches between the docstrings of some functions and their actual behavior: they use `default-toplevel-value' and `set-default-toplevel-value' and their docstring said they use `default-value' and `set-default'. And that is mainly what this patch fixes, aside from another error in the docstring of `default-boundp'. The few non-documentation changes are just using the toplevel versions of those functions in some places that were still missing, in functions and places completely equivalent to those that are already using them. This makes the use of those functions more consistent across custom.el, and fixes in those new places the potential bug that those functions were introduced to solve in the first place: calling `defcustom' or customize functions inside a let-binding of the variable in question (e.g., because a function inside the let body autoloads, calling `defcustom') A few further comments on each change: > @@ -114,7 +114,7 @@ custom-initialize-changed > symbol > (eval (car (get symbol 'saved-value))))) > (t > - (set-default symbol (eval exp))))))) > + (set-default-toplevel-value symbol (eval exp))))))) > > (defvar custom-delayed-init-variables nil > "List of variables whose initialization is pending until startup. The docstring of this function actually says that it behaves like `custom-initialize-reset', which is already using `set-default-toplevel-value'. > @@ -717,7 +717,7 @@ custom-set-default > (if custom-local-buffer > (with-current-buffer custom-local-buffer > (set variable value)) > - (set-default variable value))) > + (set-default-toplevel-value variable value))) > > (defun custom-set-minor-mode (variable value) > ":set function for minor mode variables. This would be the only setter function that does not use `set-default-toplevel-value'. > @@ -752,7 +752,7 @@ customize-mark-to-save > @@ -779,7 +779,7 @@ customize-mark-as-set These two I thought that I had remove them. Ignore them, they will not be there in the next version of the patch --Ignacio ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-05-12 8:41 ` Ignacio Casso @ 2022-05-12 9:40 ` Eli Zaretskii 2022-05-12 11:49 ` Lars Ingebrigtsen 2022-06-09 15:02 ` Lars Ingebrigtsen 1 sibling, 1 reply; 41+ messages in thread From: Eli Zaretskii @ 2022-05-12 9:40 UTC (permalink / raw) To: Ignacio Casso; +Cc: michael_heerdegen, larsi, 54399, monnier > From: Ignacio Casso <ignaciocasso@hotmail.com> > Cc: larsi@gnus.org, michael_heerdegen@web.de, 54399@debbugs.gnu.org, > monnier@iro.umontreal.ca > Date: Thu, 12 May 2022 10:41:56 +0200 > > The few non-documentation changes are just using the toplevel versions > of those functions in some places that were still missing, in functions > and places completely equivalent to those that are already using > them. This makes the use of those functions more consistent across > custom.el, and fixes in those new places the potential bug that those > functions were introduced to solve in the first place: calling > `defcustom' or customize functions inside a let-binding of the variable > in question (e.g., because a function inside the let body autoloads, > calling `defcustom') If those changes are fine with Stefan and Lars, I don't mind. ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-05-12 9:40 ` Eli Zaretskii @ 2022-05-12 11:49 ` Lars Ingebrigtsen 0 siblings, 0 replies; 41+ messages in thread From: Lars Ingebrigtsen @ 2022-05-12 11:49 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, Ignacio Casso, 54399, monnier Eli Zaretskii <eliz@gnu.org> writes: > If those changes are fine with Stefan and Lars, I don't mind. They make sense to me, but perhaps Stefan has some comments... -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-05-12 8:41 ` Ignacio Casso 2022-05-12 9:40 ` Eli Zaretskii @ 2022-06-09 15:02 ` Lars Ingebrigtsen 2022-06-09 21:19 ` Ignacio Casso 1 sibling, 1 reply; 41+ messages in thread From: Lars Ingebrigtsen @ 2022-06-09 15:02 UTC (permalink / raw) To: Ignacio Casso; +Cc: michael_heerdegen, Eli Zaretskii, 54399, monnier Ignacio Casso <ignaciocasso@hotmail.com> writes: > These two I thought that I had remove them. Ignore them, they will not > be there in the next version of the patch Ignacio, did you have a new version of the patch that we missed? -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-06-09 15:02 ` Lars Ingebrigtsen @ 2022-06-09 21:19 ` Ignacio Casso 2022-06-10 9:13 ` Lars Ingebrigtsen 0 siblings, 1 reply; 41+ messages in thread From: Ignacio Casso @ 2022-06-09 21:19 UTC (permalink / raw) To: Lars Ingebrigtsen; +Cc: michael_heerdegen, Eli Zaretskii, 54399, monnier [-- Attachment #1: Type: text/plain, Size: 495 bytes --] Lars Ingebrigtsen <larsi@gnus.org> writes: > Ignacio Casso <ignaciocasso@hotmail.com> writes: > >> These two I thought that I had remove them. Ignore them, they will not >> be there in the next version of the patch > > Ignacio, did you have a new version of the patch that we missed? Not really, just the last one but without those two changes. I guess I was waiting for all of you to agree before sending it (you and Eli did, but Stefan did not answer) and I forgot eventually. Here it is: [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: Patch for bug#54399 --] [-- Type: text/x-diff, Size: 5910 bytes --] From 6f0791ce7d5189af29362e8570659881776d7748 Mon Sep 17 00:00:00 2001 From: Ignacio Casso <ignaciocasso@hotmail.com> Date: Thu, 12 May 2022 10:37:10 +0200 Subject: [PATCH] updated some documentation regarding customize and default values --- doc/lispref/customize.texi | 8 ++++---- lisp/custom.el | 14 +++++++------- src/data.c | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/doc/lispref/customize.texi b/doc/lispref/customize.texi index 54059d7b6e..06a2f5365d 100644 --- a/doc/lispref/customize.texi +++ b/doc/lispref/customize.texi @@ -376,7 +376,7 @@ Variable Definitions the value properly for this option (which may not mean simply setting the option as a Lisp variable); preferably, though, it should not modify its value argument destructively. The default for -@var{setfunction} is @code{set-default}. +@var{setfunction} is @code{set-default-toplevel-value}. If you specify this keyword, the variable's documentation string should describe how to do the same job in hand-written Lisp code. @@ -387,7 +387,7 @@ Variable Definitions option. The function @var{getfunction} should take one argument, a symbol, and should return whatever customize should use as the current value for that symbol (which need not be the symbol's Lisp -value). The default is @code{default-value}. +value). The default is @code{default-toplevel-value}. You have to really understand the workings of Custom to use @code{:get} correctly. It is meant for values that are treated in @@ -409,7 +409,7 @@ Variable Definitions @item custom-initialize-default Like @code{custom-initialize-set}, but use the function -@code{set-default} to set the variable, instead of the variable's +@code{set-default-toplevel-value} to set the variable, instead of the variable's @code{:set} function. This is the usual choice for a variable whose @code{:set} function enables or disables a minor mode; with this choice, defining the variable will not call the minor mode function, but @@ -424,7 +424,7 @@ Variable Definitions @item custom-initialize-changed Use the @code{:set} function to initialize the variable, if it is already set or has been customized; otherwise, just use -@code{set-default}. +@code{set-default-toplevel-value}. @item custom-initialize-delay This function behaves like @code{custom-initialize-set}, but it diff --git a/lisp/custom.el b/lisp/custom.el index a084304ff8..84c740f73b 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -68,7 +68,7 @@ custom-initialize-default (defun custom-initialize-set (symbol exp) "Initialize SYMBOL based on EXP. If the symbol doesn't have a default binding already, -then set it using its `:set' function (or `set-default' if it has none). +then set it using its `:set' function (or `set-default-toplevel-value' if it has none). The value is either the value in the symbol's `saved-value' property, if any, or the value of EXP." (condition-case nil @@ -81,7 +81,7 @@ custom-initialize-set (defun custom-initialize-reset (symbol exp) "Initialize SYMBOL based on EXP. -Set the symbol, using its `:set' function (or `set-default' if it has none). +Set the symbol, using its `:set' function (or `set-default-toplevel-value' if it has none). The value is either the symbol's current value (as obtained using the `:get' function), if any, or the value in the symbol's `saved-value' property if any, @@ -100,7 +100,7 @@ custom-initialize-changed "Initialize SYMBOL with EXP. Like `custom-initialize-reset', but only use the `:set' function if not using the standard setting. -For the standard setting, use `set-default'." +For the standard setting, use `set-default-toplevel-value'." (condition-case nil (let ((def (default-toplevel-value symbol))) (funcall (or (get symbol 'custom-set) #'set-default-toplevel-value) @@ -114,7 +114,7 @@ custom-initialize-changed symbol (eval (car (get symbol 'saved-value))))) (t - (set-default symbol (eval exp))))))) + (set-default-toplevel-value symbol (eval exp))))))) (defvar custom-delayed-init-variables nil "List of variables whose initialization is pending until startup. @@ -262,11 +262,11 @@ defcustom when using the Customize user interface. It takes two arguments, the symbol to set and the value to give it. The function should not modify its value argument destructively. The default choice - of function is `set-default'. + of function is `set-default-toplevel-value'. :get VALUE should be a function to extract the value of symbol. The function takes one argument, a symbol, and should return the current value for that symbol. The default choice of function - is `default-value'. + is `default-toplevel-value'. :require VALUE should be a feature symbol. If you save a value for this option, then when your init file loads the value, @@ -717,7 +717,7 @@ custom-set-default (if custom-local-buffer (with-current-buffer custom-local-buffer (set variable value)) - (set-default variable value))) + (set-default-toplevel-value variable value))) (defun custom-set-minor-mode (variable value) ":set function for minor mode variables. diff --git a/src/data.c b/src/data.c index 72dcf6f878..9b36ecc1b2 100644 --- a/src/data.c +++ b/src/data.c @@ -1939,9 +1939,9 @@ default_value (Lisp_Object symbol) DEFUN ("default-boundp", Fdefault_boundp, Sdefault_boundp, 1, 1, 0, doc: /* Return t if SYMBOL has a non-void default value. -A variable may have a buffer-local or a `let'-bound local value. This +A variable may have a buffer-local value. This function says whether the variable has a non-void value outside of the -current context. Also see `default-value'. */) +current buffer context. Also see `default-value'. */) (Lisp_Object symbol) { register Lisp_Object value; -- 2.25.1 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-06-09 21:19 ` Ignacio Casso @ 2022-06-10 9:13 ` Lars Ingebrigtsen 2022-06-10 14:01 ` dick 0 siblings, 1 reply; 41+ messages in thread From: Lars Ingebrigtsen @ 2022-06-10 9:13 UTC (permalink / raw) To: Ignacio Casso; +Cc: michael_heerdegen, Eli Zaretskii, 54399, monnier Ignacio Casso <ignaciocasso@hotmail.com> writes: > Not really, just the last one but without those two changes. I guess I was > waiting for all of you to agree before sending it (you and Eli did, but > Stefan did not answer) and I forgot eventually. Here it is: Thanks; pushed to Emacs 29 (with some whitespace changes -- a couple of the doc strings were too wide). -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-06-10 9:13 ` Lars Ingebrigtsen @ 2022-06-10 14:01 ` dick 2022-06-11 10:51 ` Lars Ingebrigtsen 0 siblings, 1 reply; 41+ messages in thread From: dick @ 2022-06-10 14:01 UTC (permalink / raw) To: Lars Ingebrigtsen Cc: michael_heerdegen, Ignacio Casso, 54399, Eli Zaretskii, monnier This may fall under "If it hurts, don't do it?", but things like: (let (parens-require-spaces defun-prompt-regexp) (require 'cl) (custom-set-variables '(parens-require-spaces t) '(defun-prompt-regexp (cl-assert parens-require-spaces)))) used to work before commit 071722e. ^ permalink raw reply [flat|nested] 41+ messages in thread
* bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) 2022-06-10 14:01 ` dick @ 2022-06-11 10:51 ` Lars Ingebrigtsen 0 siblings, 0 replies; 41+ messages in thread From: Lars Ingebrigtsen @ 2022-06-11 10:51 UTC (permalink / raw) To: dick; +Cc: michael_heerdegen, Ignacio Casso, 54399, Eli Zaretskii, monnier dick <dick.r.chiang@gmail.com> writes: > This may fall under "If it hurts, don't do it?", but things like: > > (let (parens-require-spaces defun-prompt-regexp) > (require 'cl) > (custom-set-variables > '(parens-require-spaces t) > '(defun-prompt-regexp (cl-assert parens-require-spaces)))) > > used to work before commit 071722e. Hm, yes. That should be fixed, I think. Should we call both set-default-toplevel-value and set-default here? -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 41+ messages in thread
end of thread, other threads:[~2022-06-11 10:51 UTC | newest] Thread overview: 41+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-03-15 11:50 bug#54399: 27.2; Problems with (let ((custom-variable ...)) (autoload-function ...)) Ignacio Casso 2022-03-17 11:23 ` Lars Ingebrigtsen 2022-03-18 0:22 ` Michael Heerdegen 2022-03-18 1:02 ` Michael Heerdegen 2022-03-18 9:32 ` Lars Ingebrigtsen 2022-03-18 9:38 ` Ignacio Casso 2022-04-12 13:18 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2022-04-12 13:23 ` Ignacio Casso 2022-04-12 13:55 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2022-04-12 9:13 ` Ignacio Casso 2022-04-12 11:38 ` Eli Zaretskii 2022-04-12 12:16 ` Ignacio Casso 2022-04-12 13:35 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2022-04-12 14:27 ` Ignacio Casso 2022-04-12 15:04 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2022-04-12 15:27 ` Ignacio Casso 2022-04-12 22:15 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2022-04-13 15:26 ` Ignacio Casso 2022-04-13 0:24 ` Michael Heerdegen 2022-04-13 3:26 ` Glenn Morris 2022-04-13 3:43 ` Michael Heerdegen 2022-04-12 15:24 ` Eli Zaretskii 2022-04-13 17:22 ` Ignacio Casso 2022-04-12 13:19 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2022-04-12 13:51 ` Ignacio Casso 2022-04-12 15:22 ` Eli Zaretskii 2022-04-13 0:06 ` Michael Heerdegen 2022-04-13 12:08 ` Ignacio Casso 2022-05-12 2:32 ` Lars Ingebrigtsen 2022-05-12 6:58 ` Ignacio Casso 2022-05-12 7:34 ` Eli Zaretskii 2022-05-12 8:14 ` Ignacio Casso 2022-05-12 8:36 ` Eli Zaretskii 2022-05-12 8:41 ` Ignacio Casso 2022-05-12 9:40 ` Eli Zaretskii 2022-05-12 11:49 ` Lars Ingebrigtsen 2022-06-09 15:02 ` Lars Ingebrigtsen 2022-06-09 21:19 ` Ignacio Casso 2022-06-10 9:13 ` Lars Ingebrigtsen 2022-06-10 14:01 ` dick 2022-06-11 10:51 ` Lars Ingebrigtsen
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).