Subject: 24.1; (wishlist) Simple method for preserving minor-mode

From: yary <[email-masked]>
Date: Sat, 19 Oct 2013 20:22:33 -0400

There are times when I wish to set a minor-mode permanently for a
buffer, even through major-mode changes. They are display-related
minor-modes, such as buffer-face-mode or text-scale-mode.

Ideally I'd like a simple way to preserve a minor-mode between
major-mode changes. I started discussing this in Bug #15577, which is
about dir-locals, but am moving it here as this is a separate issue.

Also bug #15396 "permanent-local truncate-lines" is related, Stefan sets
a display-related local variable and would like it preserved across mode
changes (or in this case, revert-buffer). Yet setting `permanent-local'
on the `truncate-lines' variable does not protect it:
`toggle-truncate-lines' behaves like a minor mode.

A function could take a minor-mode to preserve, and then either set up
hooks needed to re-enable it after a major-mode change, or prevent
`kill-all-local-variables' from disabling it in the first place. Or
perhaps marking the minor-mode's function-symbol itself as
`permanent-local' could protect it, along with all its buffer-locals.

I have a personal workaround which works for modes I use posted at
http://stackoverflow.com/a/19439236/379333 - though it isn't fully
generalized and has other flaws. It checks if specified minor-modes
are active during `change-major-mode-hook', and if so, then tries to
figure out which variables they use, and then restores those variables
and minor modes in the `after-change-major-mode-hook'

Answering a question from bug #15577 about this issue:

>> a. Get all of that mode's customizable buffer-locals.
>
>Not sure what that is.

The modes I wanted to preserve have buffer-locals for the face, and
for the size adjustment. It's not enough to just re-enable the modes,
we have to know which buffer-locals the mode reads.

>> Ideally the minor-mode, or emacs core, would provide a function for
>> that purpose.
>
>It's probably not possible (not reliably at least) with the way minor
>modes are defined currently.  Tho depending on what you mean it might be
>a non-issue.

What I meant was, since any proposed minor-mode-preserving mechanism
needs to know what buffer-local variables also would need to be set
`permanent-local', then "Ideally the minor-mode, or emacs core, would
provide a function" listing those variables. So for example, the
`define-minor-mode' macro might get a `:local-variables' keyword
allowing the author to declare that mode's buffer-locals, along with
their documentation and defaults. Would not be required in general,
but would make it easier for anything that wants to manipulate minor
modes.

>> b. Mark those variables as permanent-local
>
>There's no such thing, currently (we instead have to use a hack with
>change-major-mode-hook, along the lines of what you did).

Must be a mis-communication here. The docs to `kill-all-local-variables' say:

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

I just tried (put 'foo 'permanent-local 't) and `foo' survived
`kill-all-local-variables' and several mode changes. So we do have the
`permanent-local' property for keeping local variables around.

>But there are some issues:
>- we have to find out which buffer-local minor-modes are enabled, which
>  presumes we have some kind of list of minor-modes.  We can probably
>  use minor-mode-list for that, tho.

Searching minor-mode-list would work, as would checking that the
symbol "name-of-minor-mide' is buffer-local and has a non-nil value.

>- some minor modes are mode-specific; e.g. it doesn't make much sense to
>  preserve reftex-mode when switching from latex-mode to haskell-mode.

This sounds like another mis-communication- proposal is to let a user
(or by extension a minor-mode-author) to easily mark a minor-mode as
"to-be-preserved." As another example, I do not want flymake still on
when switching into css-mode. It's not up to this method to decide
which minor-modes to preserve; it is up to the user.

-y