all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Re: Proposal: `buffer-offer-save' be made a permanent-local
@ 2010-06-17 21:36 MON KEY
  2010-06-17 22:25 ` Lennart Borgman
  0 siblings, 1 reply; 20+ messages in thread
From: MON KEY @ 2010-06-17 21:36 UTC (permalink / raw)
  To: kevin.d.rodgers; +Cc: emacs-devel

Kevin Rodgers wrote:
> Isn't it as easy as:
>
> (put 'nonpermanent-local-variable 'permanent-local t)

Yep, and therein lies the rub.

My major-mode did this instead:

(put 'deadweight-unless-you-look-for-me 'permanent-local t)

How does _your_ major-mode know to test for this permanent local?

And vice versa, how does _my_ major-mode know to test for
`nonpermanent-local-variable'?

Right now we rely on the scorched earth tactics of
`kill-all-local-variables' to resolve these sorts of ambiguities. IOW
we napalm the room to erase whatever farts the previous fella left
behind.  And, in general this approach has been a fairly effective
form of air freshener but doesn't cover up certain lingering odors:

,----
| As a special exception, local variables whose names have a non-nil
| `permanent-local' property are not eliminated by this function.
|
`---- (describe-function 'kill-all-local-variables)


If you find the existing approach above ugly then you may then agree
with the proposed solution to:

 a) elevate some symbol e.g. `buffer-offer-save' to a higher status

 b) teach your major-mode to check for this symbol (where applicable)

 c) hope everyone elses major-modes do this as well

 d) wait for Emacs to begin verbosely prompting you to save every last
    useless buffer you visited _before_ she will allow her process to
    terminate.

 e) Seek out the offending elisp code that did:

    (set (make-local-variable 'buffer-offer-save) t)

    i) Check in a coupla places 'cause the major-mode/code which first
        set the var may be two or three times removed.

 f) Having located the offending code fire off a disgruntled email to
    the responsible party asking why they thought it reasonable to
    reach into your Emacsen and toggle that variable in _your_ buffers
    without first asking if it was kosher to do so...

 g) Become increasingly baffled when said coder explains that while the
    property _was_ set by his code _you_ are wrong to be miffed b/c he
    assumed:

    "this is what most people expect.
     You are the corner case.
     Sorry 'bout that"

Good luck trying to explain to someone how it is that the real
exceptional special circumstance isn't your expectations but the
permanent local variable that keeps getting flipped behind your back
when you aren't looking.

--
/s_P\



^ permalink raw reply	[flat|nested] 20+ messages in thread
* Proposal: `buffer-offer-save' be made a permanent-local
@ 2010-06-14  0:17 MON KEY
  2010-06-14  0:59 ` Lennart Borgman
  2010-06-14  1:00 ` Stefan Monnier
  0 siblings, 2 replies; 20+ messages in thread
From: MON KEY @ 2010-06-14  0:17 UTC (permalink / raw)
  To: emacs-devel

Proposal: `buffer-offer-save' be made a permanent-local.

Recently there was a proposal on bug-gnu-emacs to have
`buffer-offer-save' be made a permanent-local e.g.
 "bug#6241: Please make buffer-offer-save permanent local"
in which Stefan expressed some willingness to endorse the change:

,----
|  { ... } it's easier to circumvent an annoying permanent-local than
| it is to fake one.  I.e. if a var is permanent-local and you need it
| to be killed by kill-all-local-variables, you can do something like:
|
|  (add-hook 'change-major-mode-hook
|            (lambda () (kill-local-variable 'foobar)))
|
| whereas if it is not permanent-local and you need it to survive a
| change of major-mode, you have to jump through a few more hoops (a
| change-major-mode-hook to stash the variable's content somewhere,
| plus an after-change-major-mode-hook to reset it after the fact,
| plus additional code to handle the case when
| after-change-major-mode-hook is not run, ...).
|
| So, now that the question of "should it ideally be permanent-local?"
| is resolved, the remaining question is: "what would be the impact of
| such a change", which requires examining all uses of the variable
| and assessing the effect of the change for each case.
`----
 http://lists.gnu.org/archive/html/bug-gnu-emacs/2010-05/msg00730.html

I requested that this decision be discussed/proposed to emacs-devel b/c
it struck me as both a potentially breaking change and one that isn't
needed. To date, this discussion hasn't happened.

So, what do others here think?

Is this proposed changed needed, desirable, welcome?

IIUC Stefan's rationale for consideration of making
`buffer-offer-save' permanent-local is that it would ease the burden
placed on major-modes (and their authors) to set/check for the
presence of `buffer-offer-save' by making the value a permanent
property of every Emacs buffer not yet visiting a file such that a
major-mode/feature would now be able to set `buffer-offer-save' as a
`buffer-local-value' and thereafter rely on the value persisting
across multiple subsequent invocations of the
`kill-all-local-variables'->`change-major-mode-hook' call chain.

Consideration of following exchange which transpired between RMS and
Stefan on emacs-devel circa 2003-06-01 as thread:
 "Re: kill-buffer-hook permanent-local"
has caused me some doubt as to whether the current proposed change is
TRT and is in keeping with the rationale for other similar such
changes in the past:

,----
| Stefan Monnier:
| >> Shouldn't kill-buffer-hook be permanent-local ?
|
| RMS:
| > I think it is OK to make this change.
| > If a certain major mode wants to set up a hook value
| > that should not remain if you change the mode, it could
| > use change-major-mode-hook to remove that hook.
`----
 http://lists.gnu.org/archive/html/emacs-devel/2003-06/msg00066.html

My impression is that `kill-all-local-variables' is generally relied
upon to restore/reset a buffer to a more or less default state and
then evaluates `change-major-mode-hook' to begin the process of
introducing/enabling the variables and behaviors which are
peculiar/relevant on entrance to a particular major-mode e.g.:

 (describe-variable 'change-major-mode-hook)

,----
| Normal hook run before changing the major mode of a buffer.  The
| function `kill-all-local-variables' runs this before doing anything
| else.
`----

What I don't understand is, why if `kill-buffer-hook' is
permanent-local (which it now is), and calls to
`kill-all-local-variables' automatically evaluate
`change-major-mode-hook' do we now also need to have
`buffer-offer-save' be made permanent-local?

IIUC, RMS seems to be saying above that his caveat for allowing
`kill-buffer-hook' as a permanent-local was _because_ it could be
removed/altered/overridden by subsequent calls to
`change-major-mode-hook'.  In contrast, the currently proposed change
to have `buffer-offer-save' become permanent-local is essentially an
attempt to circumvent the same exceptional behavior which RMS seems
to suggest convinced him that it was reasonable to allow
`kill-buffer-hook' as a permanent-local.

As currently proposed this new permanent-local will mean that
major-modes will now have to explicitly check for the
`buffer-local-value' of `buffer-offer-save' whereas up until now
major-mode authors could assume it to be nil being that it was
automatically zapped by `kill-all-local-variables' before the any
further major-mode changes occurred.

IME most buffers rarely require more than three distinct major-modes
to reasonably edit the text within context. So, I personally don't
understand what problem the proposed change solves. It doesn't seem
like that big a deal for a particular major-mode to check for the
value of variable if it is necessary for it to do so in order to
reasonably satisfy user expectations.

To the extent that the change is needed/wanted/desirable,
why can't a mode-local `buffer-offer-save' be added to the
`kill-buffer-hook' instead to accomplish the same goal of making
`buffer-offer-save' permanent-local without having to add an
additional atomic and effectively immutable global to every buffer's
list of `buffer-local-variables'?

Does the proposed change offer the right level of granularity for a
variable which globally affects the effective state of buffer
savedness?

Should `buffer-offer-save' be allowed to become a permanent-local
property of a buffer it may indeed solve what is at present a
relatively minor and esoteric issue affecting a few developers of
certain major-modes whose features require programatically
enabling/disabling the mode multiple times during the life of a buffer
to accomplish complicated presentation tasks.

My concern, is that though the issue doesn't currently seem to
adversely affect the development of most major-modes this doesn't mean
that if/once buffer-offer-save is made permanent-local it won't be
bound more often via the `change-major-mode-hook' in the wild by third
party code. Should this occur it may well violate many user
expectations placing a burden on the _user_ to find and remove any
inadvertent binding of this global property hidden away in a dedicated
package function/macro. Right now this isn't a problem for users
because the buffer-offer-save property is typically bound/removed with
each call to `kill-all-local-variables'->`change-major-mode-hook' on a
mode-change.

One argument which has been made for making `buffer-offer-save'
permanent-local is that this value reflects aspects of a buffers
textual content whereas the current situation treats it as part of a
buffer's major-mode context.

IOW Currently it is left to the buffer's major-mode (context) to
determine on each mode-change whether an unsaved buffer in that mode
should require that Emacs always offer to save the buffer on
exit. However, if I should change from `emacs-lisp-mode' to
`scheme-mode' the the text/chars the buffer contains (content) don't
necessarily change, the decision of whether Emacs will offer to save
the buffer is now decided by the `scheme-mode' context.

I like the current behavior, I find it intuitive, and generally for a
given buffer I know how Emacs will respond according to what the
mode-line displays about the state of a given buffers major-mode. I'm
comfortable knowing that when I'm in comint-mode buffer I'm gonna get
an entirely different set of behaviors than when I'm in `org-mode'.

I am adverse to making buffer-offer-save permanent-local because:
 - It treats the users choice of major-modes (context) as 2nd class;
 - Elevates buffer characters to vi modal status;
 - Abstracts and/or removes a user interface for controlling/monitoring
   a fundamental bit of Emacs behavior (buffer savedness);
 - May violate user notions of whether or not a buffer is treated by
   default as optionally expendable or inherently immutable.

IMHO Emacs is better served moving _away_ from permanent-locals and
other sorts of heavy-handed globals with an implicit reliance on
dynamic-scoping and instead seek to find/incorporate first-class
lexical-scoping solutions which can better accommodate both the user
and package developers.

Related Background:

http://lists.gnu.org/archive/html/emacs-devel/2003-06/msg00025.html
http://lists.gnu.org/archive/html/emacs-devel/2007-12/msg00169.html
http://article.gmane.org/gmane.emacs.devel/82069
http://lists.gnu.org/archive/html/emacs-devel/2009-06/msg00364.html

--
/s_P\



^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2010-06-28  4:39 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-06-17 21:36 Proposal: `buffer-offer-save' be made a permanent-local MON KEY
2010-06-17 22:25 ` Lennart Borgman
2010-06-18  0:13   ` MON KEY
2010-06-18  0:33     ` Lennart Borgman
2010-06-18  2:53       ` MON KEY
2010-06-19 15:20         ` Lennart Borgman
2010-06-20  5:05           ` MON KEY
  -- strict thread matches above, loose matches on Subject: below --
2010-06-14  0:17 MON KEY
2010-06-14  0:59 ` Lennart Borgman
2010-06-14  1:00 ` Stefan Monnier
2010-06-14  8:48   ` MON KEY
2010-06-14  9:18     ` Lennart Borgman
2010-06-16  7:21       ` MON KEY
2010-06-16 11:39         ` Lennart Borgman
2010-06-16 22:02           ` MON KEY
2010-06-16 23:11             ` Lennart Borgman
2010-06-28  4:39               ` MON KEY
2010-06-14 13:38     ` Stefan Monnier
2010-06-17  4:15   ` Kevin Rodgers
2010-06-17 20:19     ` Stefan Monnier

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.