* mode-line-format - local variableness @ 2009-04-05 22:18 Drew Adams 2009-04-05 22:50 ` Johan Bockgård 2009-04-06 1:37 ` Stefan Monnier 0 siblings, 2 replies; 11+ messages in thread From: Drew Adams @ 2009-04-05 22:18 UTC (permalink / raw) To: emacs-devel (defun foo (text &optional buffer) "Display TEXT in BUFFER's mode line for 2 sec." (with-current-buffer (or buffer (current-buffer)) (let ((mode-line-format text)) (force-mode-line-update) (sit-for 2)) (force-mode-line-update))) M-: (foo "JJJJJ" "*scratch*") In Emacs 20, JJJJJ is displayed in the mode-line of buffer *scratch* only. The mode lines of other buffers are unaffected. In Emacs 21 and later, *each* buffer's mode-line shows JJJJJ. What am I missing? `mode-line-format' is a buffer-local variable. That makes me think the Emacs 20 behavior is correct and the behavior since then is incorrect. I assume I must be missing something here. Can someone please clue me in? Thx. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: mode-line-format - local variableness 2009-04-05 22:18 mode-line-format - local variableness Drew Adams @ 2009-04-05 22:50 ` Johan Bockgård 2009-04-05 23:24 ` Miles Bader 2009-04-05 23:29 ` Drew Adams 2009-04-06 1:37 ` Stefan Monnier 1 sibling, 2 replies; 11+ messages in thread From: Johan Bockgård @ 2009-04-05 22:50 UTC (permalink / raw) To: emacs-devel "Drew Adams" <drew.adams@oracle.com> writes: > What am I missing? `mode-line-format' is a buffer-local variable. No, it isn't. (local-variable-p 'mode-line-format) => nil (local-variable-if-set-p 'mode-line-format) => t ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: mode-line-format - local variableness 2009-04-05 22:50 ` Johan Bockgård @ 2009-04-05 23:24 ` Miles Bader 2009-04-05 23:29 ` Drew Adams 1 sibling, 0 replies; 11+ messages in thread From: Miles Bader @ 2009-04-05 23:24 UTC (permalink / raw) To: emacs-devel bojohan+news@dd.chalmers.se (Johan Bockgård) writes: >> What am I missing? `mode-line-format' is a buffer-local variable. > > No, it isn't. > > (local-variable-p 'mode-line-format) => nil > (local-variable-if-set-p 'mode-line-format) => t My impression is that let-binding of variables isn't generally so well-defined in association with "magic" emacs features like buffer-localness... -Miles -- Politeness, n. The most acceptable hypocrisy. ^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: mode-line-format - local variableness 2009-04-05 22:50 ` Johan Bockgård 2009-04-05 23:24 ` Miles Bader @ 2009-04-05 23:29 ` Drew Adams 2009-04-05 23:37 ` Drew Adams 1 sibling, 1 reply; 11+ messages in thread From: Drew Adams @ 2009-04-05 23:29 UTC (permalink / raw) To: 'Johan "Bockgård"', emacs-devel > From: Johan "Bockgård" Sent: Sunday, April 05, 2009 3:50 PM > > What am I missing? `mode-line-format' is a buffer-local variable. > > No, it isn't. > (local-variable-p 'mode-line-format) => nil > (local-variable-if-set-p 'mode-line-format) => t Then there seems to be a bug (either Emacs behavior or doc). `C-h v mode-line-format' seems to say that it is buffer-local: "Automatically becomes buffer-local when set in any fashion." And "Each buffer has its own value of this variable." And exactly the same thing is said after you do M-: (make-variable-buffer-local 'mode-line-format). To me, that doc is saying that the variable is buffer-local in all buffers: setting it in a buffer affects only the mode-line of that buffer. Looking at some of the Emacs source code, things are not too clear. hideshow.el (why hideshow.el?), for instance, calls `make-variable-buffer-local' for it. I don't see where it is made buffer-local generally (hide-show.el is not loaded by default, AFAIK), but the doc string does seem to indicate that it is. (Maybe it's done in C code.) To me, the behavior from the code snippet I sent seems like a product bug, not a doc bug. But Emacs has been this way apparently since Emacs 21 (not 20). Wrt the code I sent (which uses `let', not `setq'), this, from Elisp manual node Creating Buffer-Local, seems to be part of the explanation: "A peculiar wrinkle of this feature is that binding the variable (with `let' or other binding constructs) does not create a buffer-local binding for it. Only setting the variable (with `set' or `setq'), while the variable does not have a `let'-style binding that was made in the current buffer, does so." That text was not present in Emacs 20, where the code works (only the mode-line of the given buffer is affected). I guess the bottom line is that I will need to use `setq' for the code to work beyond Emacs 20. Presumably (hopefully), the change that introduced "this feature" (whatever the undisclosed feature might be) did improve something, even at the cost of breaking this. Further elucidations/advice is welcome. ^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: mode-line-format - local variableness 2009-04-05 23:29 ` Drew Adams @ 2009-04-05 23:37 ` Drew Adams 2009-04-06 0:50 ` Miles Bader 0 siblings, 1 reply; 11+ messages in thread From: Drew Adams @ 2009-04-05 23:37 UTC (permalink / raw) To: 'Johan "Bockgård"', emacs-devel Summary (with no understanding of why, beyond the catechismic don't-use-let-use-setq): This will not work: (defun foo (text &optional buffer) (with-current-buffer (or buffer (current-buffer)) (let ((mode-line-format text)) (force-mode-line-update) (sit-for 2)) (force-mode-line-update))) This works (ugh!): (defun foo (text &optional buffer) (with-current-buffer (or buffer (current-buffer)) (let ((old-mode-line-format mode-line-format)) (setq mode-line-format text) (force-mode-line-update) (sit-for 2) (setq mode-line-format old-mode-line-format)) (force-mode-line-update))) Don't `let'-bind `mode-line-format', but you can `let'-bind something to its value and then restore that later. Ugh! ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: mode-line-format - local variableness 2009-04-05 23:37 ` Drew Adams @ 2009-04-06 0:50 ` Miles Bader 2009-04-06 3:05 ` Drew Adams 0 siblings, 1 reply; 11+ messages in thread From: Miles Bader @ 2009-04-06 0:50 UTC (permalink / raw) To: Drew Adams; +Cc: emacs-devel, Johan Bockgård "Drew Adams" <drew.adams@oracle.com> writes: > Don't `let'-bind `mode-line-format', but you can `let'-bind something to its > value and then restore that later. Ugh! The issue is that things like buffer-local variables are (useful but) weird, and there's a certain amount of hair involved in their implementation. They work pretty well when used as intended, but beyond that, all bets are off. [BTW, if you're gonna use setq, you should of course use unwind-protect.] -Miles -- I'm beginning to think that life is just one long Yoko Ono album; no rhyme or reason, just a lot of incoherent shrieks and then it's over. --Ian Wolff ^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: mode-line-format - local variableness 2009-04-06 0:50 ` Miles Bader @ 2009-04-06 3:05 ` Drew Adams 0 siblings, 0 replies; 11+ messages in thread From: Drew Adams @ 2009-04-06 3:05 UTC (permalink / raw) To: 'Miles Bader'; +Cc: emacs-devel, 'Johan Bockgård' > [BTW, if you're gonna use setq, you should of course use > unwind-protect.] Yes, I did that in my code. I left it off here, to keep it simple. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: mode-line-format - local variableness 2009-04-05 22:18 mode-line-format - local variableness Drew Adams 2009-04-05 22:50 ` Johan Bockgård @ 2009-04-06 1:37 ` Stefan Monnier 2009-04-06 3:19 ` Drew Adams 1 sibling, 1 reply; 11+ messages in thread From: Stefan Monnier @ 2009-04-06 1:37 UTC (permalink / raw) To: Drew Adams; +Cc: emacs-devel > (with-current-buffer (or buffer (current-buffer)) > (let ((mode-line-format text)) > (force-mode-line-update) (sit-for 2)) > (force-mode-line-update))) Combining let-binding and buffer-local values is a difficult exercise. The behavior of the above depends on whether mode-line-format is currently buffer-local in the current buffer. Some Elisp variables are never buffer-local (e.g. the ones that are frame-local), others (most) are by default global can be made buffer-local to a particular buffer by calling `make-local-variable', others are buffer-local by default, which means that they become buffer-local as soon as you use `setq' on them (but not `let'), and finally yet others are simply always buffer-local (e.g. default-directory). It seems that mode-line-format was "always buffer-local" in Emacs-20 and changed to "buffer-local by default" in Emacs-21. I don't know what was the reason for it, but in any case an explicit call to `make-local-variable' before the let will clear up any ambiguity. Stefan ^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: mode-line-format - local variableness 2009-04-06 1:37 ` Stefan Monnier @ 2009-04-06 3:19 ` Drew Adams 2009-04-06 13:30 ` Stefan Monnier 0 siblings, 1 reply; 11+ messages in thread From: Drew Adams @ 2009-04-06 3:19 UTC (permalink / raw) To: 'Stefan Monnier'; +Cc: emacs-devel > It seems that mode-line-format was "always buffer-local" in > Emacs-20 and changed to "buffer-local by default" in Emacs-21. > I don't know what was the reason for it, but in any case an > explicit call to `make-local-variable' before the let will > clear up any ambiguity. Oh, I thought it _was_ always buffer-local, even in recent Emacs. And I thought the manual was advising not to use `let' with buffer-local variables. That text is not too clear to me. Is it trying to say instead to not use `let' with a variable that _will be_ buffer-local but is not yet so? But it's OK to use `let' with a variable that is already buffer-local? Not too clear, IMO. Yes, it's simpler and looks cleaner to do what you mention than to monkey around with setq and unwind-protect. From the doc, I didn't get the impression that that would help, but it seems to work fine. (defun foo (text &optional buffer) (with-current-buffer (or buffer (current-buffer)) (make-local-variable 'mode-line-format) (let ((mode-line-format text)) (force-mode-line-update) (sit-for 10)) (force-mode-line-update))) Whether or not that is actually cleaner, I don't know, but it certainly looks so. I admit that I don't understand the problem with `let' and buffer-local-to-be-but-not-yet vars. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: mode-line-format - local variableness 2009-04-06 3:19 ` Drew Adams @ 2009-04-06 13:30 ` Stefan Monnier 2009-04-06 21:37 ` Miles Bader 0 siblings, 1 reply; 11+ messages in thread From: Stefan Monnier @ 2009-04-06 13:30 UTC (permalink / raw) To: Drew Adams; +Cc: emacs-devel > Oh, I thought it _was_ always buffer-local, even in recent Emacs. > And I thought the manual was advising not to use `let' with > buffer-local variables. "Always buffer-local" is used for variables for which a "global value" basically doesn't make any sense. `buffer-file-name' for example. mode-line-format, OTOH has a default global value shared by most buffers. Ideally it probably shouldn't even be made buffer-loal by `setq' but only by `make-local-variable'. > That text is not too clear to me. Is it trying to say instead to not > use `let' with a variable that _will be_ buffer-local but is not yet > so? But it's OK to use `let' with a variable that is already > buffer-local? Not too clear, IMO. In general it's better to avoid mixing let and buffer-local. If you have to, then try to make sure that during the let, the variable's buffer-localness is not changed. In older versions of Emacs (<21 IIRC) you alsa had to try and avoid switching into another buffer during the let (or at least revert back to the same buffer before finishing the let). > Whether or not that is actually cleaner, I don't know, but it > certainly looks so. I admit that I don't understand the problem with > `let' and buffer-local-to-be-but-not-yet vars. (let ((x e1)) e2) is more or less equivalent to (let ((old-x x)) (unwind-protect (progn (setq x e1) e2) (setq x old-x))) So if the buffer-localness of x is changed in `e2' we have a problem: if old-x was read from the global part of `x', should (setq x old-x) assign to the new buffer-local part of `x' or to the global part of `x' or both? If OTOH `old-x' was read from the buffer-local part of `x' but `x' was kill-local-variable'd, should (setq x old-x) "reset" the global part of `x' or do nothing? There are reasonable choices for these questions, but no matter what you choose, you will sooner or later find a situation where it doesn't actually do what was intended, and furthermore, the implementation tends to be painful and costly, which is a bummer since it's supposed to be a *very* rare case that's fairly easy to avoid, yet you'll end up paying for it all the time. Stefan ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: mode-line-format - local variableness 2009-04-06 13:30 ` Stefan Monnier @ 2009-04-06 21:37 ` Miles Bader 0 siblings, 0 replies; 11+ messages in thread From: Miles Bader @ 2009-04-06 21:37 UTC (permalink / raw) To: emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: > There are reasonable choices for these questions, but no matter what you > choose, you will sooner or later find a situation where it doesn't > actually do what was intended, and furthermore, the implementation tends > to be painful and costly, which is a bummer since it's supposed to be > a *very* rare case that's fairly easy to avoid, yet you'll end up paying > for it all the time. ... and any guarantees we make now may come back to haunt us if we want to change the way the internal mechanisms work later. -Miles -- Accord, n. Harmony. ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2009-04-06 21:37 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-04-05 22:18 mode-line-format - local variableness Drew Adams 2009-04-05 22:50 ` Johan Bockgård 2009-04-05 23:24 ` Miles Bader 2009-04-05 23:29 ` Drew Adams 2009-04-05 23:37 ` Drew Adams 2009-04-06 0:50 ` Miles Bader 2009-04-06 3:05 ` Drew Adams 2009-04-06 1:37 ` Stefan Monnier 2009-04-06 3:19 ` Drew Adams 2009-04-06 13:30 ` Stefan Monnier 2009-04-06 21:37 ` Miles Bader
Code repositories for project(s) associated with this external index https://git.savannah.gnu.org/cgit/emacs.git https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.