GNU bug report logs - #15577
24.3; dir-local variables not applied when switching major-mode

Previous Next

Package: emacs;

Reported by: yary <not.com <at> gmail.com>

Date: Wed, 9 Oct 2013 20:15:01 UTC

Severity: normal

Merged with 23407

Found in version 24.3

Done: Alan Mackenzie <acm <at> muc.de>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 15577 in the body.
You can then email your comments to 15577 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#15577; Package emacs. (Wed, 09 Oct 2013 20:15:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to yary <not.com <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Wed, 09 Oct 2013 20:15:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: yary <not.com <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 24.3; dir-local variables not applied when switching major-mode
Date: Wed, 9 Oct 2013 16:14:00 -0400
This bug report will be sent to the Bug-GNU-Emacs mailing list
and the GNU bug tracker at debbugs.gnu.org.  Please check that
the From: line contains a valid email address.  After a delay of up
to one day, you should receive an acknowledgment at that address.

Please write in English if possible, as the Emacs maintainers
usually do not have translators for other languages.

Please describe exactly what actions triggered the bug, and
the precise symptoms of the bug.  If you can, give a recipe
starting from `emacs -Q':

If I create a ".dir-locals.el" that applies to all major modes, such as:
  ((nil . ((tab-width . 3))))
It works when first opening any file under that directory- good. But, if
I switch the buffer's major-mode, it loses the directory-local
tab-width - and I've seen it lose other variables as well.

An alternate case showing the same is to have a ".dir-locals.el" like:
  ((js-mode . ((tab-width . 3))))

and opening a non-JS file in the directory, such as an HTML file, and
then switching to js-mode. Since I'm now editing the file in js-mode,
I would want it to read the js-mode dir-local variables.

Losing dir-locals seems like a bug to me, though perhaps there is a
reason for it. I did notice from other dir-local-related bugs that
they require some
thought as to how to handle edge cases...



In GNU Emacs 24.3.1 (i386-mingw-nt5.1.2600)
 of 2013-03-17 on MARVIN
Windowing system distributor `Microsoft Corp.', version 5.1.2600
Configured using:
 `configure --with-gcc (4.7) --cflags
 -ID:/devel/emacs/libs/libXpm-3.5.8/include
 -ID:/devel/emacs/libs/libXpm-3.5.8/src
 -ID:/devel/emacs/libs/libpng-dev_1.4.3-1/include
 -ID:/devel/emacs/libs/zlib-dev_1.2.5-2/include
 -ID:/devel/emacs/libs/giflib-4.1.4-1/include
 -ID:/devel/emacs/libs/jpeg-6b-4/include
 -ID:/devel/emacs/libs/tiff-3.8.2-1/include
 -ID:/devel/emacs/libs/gnutls-3.0.9/include
 -ID:/devel/emacs/libs/libiconv-1.13.1-1-dev/include
 -ID:/devel/emacs/libs/libxml2-2.7.8/include/libxml2'

Important settings:
  value of $LANG: ENU
  locale-coding-system: cp1252
  default enable-multibyte-characters: t

Major mode: Info

Minor modes in effect:
  yas-global-mode: t
  yas-minor-mode: t
  global-auto-complete-mode: t
  diff-auto-refine-mode: t
  recentf-mode: t
  desktop-save-mode: t
  tooltip-mode: t
  mouse-wheel-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  buffer-read-only: t
  line-number-mode: t
  transient-mark-mode: t

Features:
(shadow sort mail-extr emacsbug message rfc822 mml mml-sec mm-decode
mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader
sendmail rfc2047 rfc2045 ietf-drums conf-mode sh-script smie executable
info dos org-table org-wl org-w3m org-vm org-rmail org-mhe org-mew
org-irc org-jsinfo org-infojs org-html org-exp ob-exp org-exp-blocks
org-agenda org-info org-gnus org-docview org-bibtex bibtex org-bbdb
face-remap gtags js json moz imenu thingatpt vc-git js2-mode-autoloads
finder-inf undo-tree-autoloads package multi-web-mode mumamo-fun
mumamo-chunks amrita desktop-autosave hide-lines yasnippet help-mode
auto-complete-config auto-complete popup flymake-jslint flymake php-mode
etags cc-langs cc-mode cc-fonts cc-guess cc-menus cc-cmds cc-styles
cc-align speedbar sb-image ezimage dframe psvn derived log-edit
pcvs-util add-log diff-mode elp ediff-merg ediff-diff ediff-wind
ediff-mult ediff-help ediff-init ediff-util dired emacsw32 w32-integ
w32shell w32-grep rebind ourcomments-widgets ourcomments-util rx
cus-edit cus-start cus-load uniquify recentf tree-widget mm-url url
url-proxy url-privacy url-expand url-methods url-history url-cookie
url-domsuf url-util url-parse auth-source eieio password-cache url-vars
mailcap gnus gnus-ems nnheader gnus-util mail-utils mm-util mail-prsvr
org ob-tangle ob-ref ob-lob ob-table org-footnote org-src ob-comint
ob-keys org-pcomplete pcomplete org-list org-faces org-entities noutline
outline org-version ob-emacs-lisp ob org-compat org-macs ob-eval
org-loaddefs format-spec find-func cal-menu calendar cal-loaddefs ido
grep compile comint ansi-color ring bookmark pp apropos mumamo byte-opt
warnings bytecomp byte-compile cconv advice help-fns advice-preload
sgml-mode ruby-mode rng-nxml rng-valid rng-loc rng-uri rng-parse
nxml-parse rng-match rng-dt rng-util rng-pttrn nxml-ns nxml-mode
nxml-outln nxml-rap nxml-util nxml-glyph nxml-enc xmltok mumamo-cmirr
flyspell ispell desktop cc-engine cc-vars cc-defs new-key-seq-widget
edmacro kmacro wid-edit hfyview easy-mmode easymenu htmlfontify cl-macs
gv cl cl-lib noprint nxhtml-loader emacsw32-eol time-date tooltip
ediff-hook vc-hooks lisp-float-type mwheel dos-w32 ls-lisp
w32-common-fns disp-table w32-win w32-vars tool-bar dnd fontset image
regexp-opt fringe tabulated-list newcomment lisp-mode register page
menu-bar rfn-eshadow timer select scroll-bar mouse jit-lock font-lock
syntax facemenu font-core frame cham georgian utf-8-lang misc-lang
vietnamese tibetan thai tai-viet lao korean japanese hebrew greek
romanian slovak czech european ethiopic indian cyrillic chinese
case-table epa-hook jka-cmpr-hook help simple abbrev minibuffer loaddefs
button faces cus-face macroexp files text-properties overlay sha1 md5
base64 format env code-pages mule custom widget hashtable-print-readable
backquote make-network-process w32 multi-tty emacs)




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15577; Package emacs. (Wed, 09 Oct 2013 21:43:02 GMT) Full text and rfc822 format available.

Message #8 received at 15577 <at> debbugs.gnu.org (full text, mbox):

From: Glenn Morris <rgm <at> gnu.org>
To: yary <not.com <at> gmail.com>
Cc: 15577 <at> debbugs.gnu.org
Subject: Re: bug#15577: 24.3;
 dir-local variables not applied when switching major-mode
Date: Wed, 09 Oct 2013 17:42:05 -0400
yary wrote:

> If I create a ".dir-locals.el" that applies to all major modes, such as:
>   ((nil . ((tab-width . 3))))
> It works when first opening any file under that directory- good. But, if
> I switch the buffer's major-mode, it loses the directory-local
> tab-width -

File-local variables behave in the same way.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15577; Package emacs. (Thu, 10 Oct 2013 18:35:02 GMT) Full text and rfc822 format available.

Message #11 received at 15577 <at> debbugs.gnu.org (full text, mbox):

From: yary <not.com <at> gmail.com>
To: Glenn Morris <rgm <at> gnu.org>
Cc: 15577 <at> debbugs.gnu.org
Subject: Re: bug#15577: 24.3;
 dir-local variables not applied when switching major-mode
Date: Thu, 10 Oct 2013 14:34:20 -0400
Before posting the mode-change-clobbering-locals behavior as a bug, I
asked about it on stackoverflow, which generated a thorough
explanation : http://stackoverflow.com/questions/19280851/how-to-keep-dir-local-variables-when-switching-major-modes
-y


On Wed, Oct 9, 2013 at 5:42 PM, Glenn Morris <rgm <at> gnu.org> wrote:
> yary wrote:
>
>> If I create a ".dir-locals.el" that applies to all major modes, such as:
>>   ((nil . ((tab-width . 3))))
>> It works when first opening any file under that directory- good. But, if
>> I switch the buffer's major-mode, it loses the directory-local
>> tab-width -
>
> File-local variables behave in the same way.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15577; Package emacs. (Thu, 10 Oct 2013 21:28:02 GMT) Full text and rfc822 format available.

Message #14 received at 15577 <at> debbugs.gnu.org (full text, mbox):

From: Glenn Morris <rgm <at> gnu.org>
To: yary <not.com <at> gmail.com>
Cc: 15577 <at> debbugs.gnu.org
Subject: Re: bug#15577: 24.3;
 dir-local variables not applied when switching major-mode
Date: Thu, 10 Oct 2013 17:27:26 -0400
yary wrote:

> Before posting the mode-change-clobbering-locals behavior as a bug, I
> asked about it on stackoverflow, which generated a thorough
> explanation : http://stackoverflow.com/questions/19280851/how-to-keep-dir-local-variables-when-switching-major-modes

I think it slightly impolite to post the same question to two different
places at the same time.

Anyway, are you happy with the answers you have, or do you want Emacs to
change? It is a long-standing behaviour that local variables (file or
directory) are only applied (by normal-mode) when you visit a file, and
get clobbered by major-mode changes.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15577; Package emacs. (Thu, 10 Oct 2013 21:53:02 GMT) Full text and rfc822 format available.

Message #17 received at 15577 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Glenn Morris <rgm <at> gnu.org>
Cc: yary <not.com <at> gmail.com>, 15577 <at> debbugs.gnu.org
Subject: Re: bug#15577: 24.3;
 dir-local variables not applied when switching major-mode
Date: Thu, 10 Oct 2013 17:52:33 -0400
> Anyway, are you happy with the answers you have, or do you want Emacs to
> change? It is a long-standing behaviour that local variables (file or
> directory) are only applied (by normal-mode) when you visit a file, and
> get clobbered by major-mode changes.

I do think it's at least undesirable behavior.

Not sure how best to fix it, tho.  We could try and setup file-local
vars when we run after-change-major-mode-hook.


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15577; Package emacs. (Thu, 10 Oct 2013 23:13:02 GMT) Full text and rfc822 format available.

Message #20 received at 15577 <at> debbugs.gnu.org (full text, mbox):

From: yary <not.com <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Glenn Morris <rgm <at> gnu.org>, 15577 <15577 <at> debbugs.gnu.org>
Subject: Re: bug#15577: 24.3;
 dir-local variables not applied when switching major-mode
Date: Thu, 10 Oct 2013 19:12:22 -0400
@Glenn "slightly impolite to post the same question to two different
places" -Understood, but this is a bug report, different purpose from
Stackoverflow question- and thus "are you happy with the answers you
have, or do you want Emacs to change?"- both! The answers are a
workaround for the current situation, but are slightly imperfect, and
as Stefan just wrote the current scheme is "at least undesirable
behavior."

The problem with the "(add-hook 'after-change-major-mode-hook
'hack-local-variables)" workaround and its variants, is when a
major-mode is set by a file-local variable- changing major mode will
reload the local variables, which will revert the major-mode again!

And the trouble with current Emacs out-of-the-box behavior is not
gaining the relevant file-local and dir-local variables for a new
major-mode when changing to that major-mode. I'd like to see a
well-thought-out solution in some future release.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15577; Package emacs. (Mon, 14 Oct 2013 18:43:02 GMT) Full text and rfc822 format available.

Message #23 received at 15577 <at> debbugs.gnu.org (full text, mbox):

From: yary <not.com <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Glenn Morris <rgm <at> gnu.org>, 15577 <15577 <at> debbugs.gnu.org>
Subject: Re: bug#15577: 24.3;
 dir-local variables not applied when switching major-mode
Date: Mon, 14 Oct 2013 14:41:34 -0400
Thinking about switching major modes more, my instinct is that the
right solution involves being "smarter" both about which local
variables to clear and reloading any {dir,file}-local variables for
the new node.

Basically, at the start, instead of calling
"kill-all-local-variables", only clear the locals that were set as a
consequence of the old mode. That is, if it was set directly by the
old mode, or by dir-local matching the old mode, delete it. Don't
delete a buffer-local variable if it was set explicitly by the user
after opening during the editing session.

Then after the new mode has set itself, recheck dir-locals and set any
that match the new mode.

Alas I don't use file-locals so am not sure how their use cases fit.
Ignore any "mode:" specifiers and maybe "eval:" as well after the
mode-change, I'd guess.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15577; Package emacs. (Wed, 16 Oct 2013 14:27:02 GMT) Full text and rfc822 format available.

Message #26 received at 15577 <at> debbugs.gnu.org (full text, mbox):

From: yary <not.com <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Glenn Morris <rgm <at> gnu.org>, 15577 <15577 <at> debbugs.gnu.org>
Subject: Re: bug#15577: 24.3;
 dir-local variables not applied when switching major-mode
Date: Wed, 16 Oct 2013 10:26:14 -0400
More thoughts, overturning my previous message of Oct 14th. I think I
have the essence of the issues now.

In my editing, I switch modes within a buffer (file) when working on:
A. databases- SQL inside code, or non-SQL language inside SQL triggers
B. web- HTML, CSS, JS is just the beginning...
C. any language with heredocs (shell, python, perl)- sometimes have
unrelated language blocks inside parent/wrapper code

and I've had these undesirable local-variable issues caused by that
mode switching:

1. dir-locals not being applied in the new mode
2. "manually" set local variables and minor-modes being lost.

Issue #1 "dir locals" is a narrow use case. Dir locals are not
intended to set a major mode; they are meant to set buffer-locals
after the major mode is in place. Whether set by a .dir-locals,el file
or dir-locals-set-* functions, the user is saying "buffers from files
here in this mode should have those variables set" and is saying so
clearly.

So, to fix that issue, after switching major modes, it would be good
to run "hack-dir-local-variables-non-file-buffer" to pick up any
dir-locals for the new mode.

Properly implementing that as an Emacs bug-fix is out of my skillset,
though the tips from stackoverflow helped me put a workaround in my
~/.emacs

Issue #2- "manually" set buffer-local's, and by extension file-local
variables- is trickier. Trying to automate what happens there smells
of unintended consequences. The answer here is an easier way for us to
set the "permanent-local-hook" property for variables (eg
"tab-width"), and minor-modes (eg "buffer-face-mode" with its new
face). Then I & others who use file-locals can mark a particular item
as "permanent" right in the file. Additionally, for other local
variables that people might want to keep (eg set interactively), have
an interactive command to mark a buffer-local variable or minor-mode
as permanent. And also, allow describe-variable, describe-minor-mode
to show/set the "permanent-local-hook" property.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15577; Package emacs. (Fri, 18 Oct 2013 15:45:03 GMT) Full text and rfc822 format available.

Message #29 received at 15577 <at> debbugs.gnu.org (full text, mbox):

From: yary <not.com <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Glenn Morris <rgm <at> gnu.org>, 15577 <15577 <at> debbugs.gnu.org>
Subject: Re: bug#15577: 24.3;
 dir-local variables not applied when switching major-mode
Date: Fri, 18 Oct 2013 11:43:54 -0400
My implementation thoughts for core-level fixes, after working on
personal workarounds.

For sub-issue #1 "dir-locals not being applied in the new mode,"
divide the responsibility for setting file-locals and dir-locals
between `normal-mode find-file=t' and `define-derived-mode'. Just have
`define-derived-mode' call
`(hack-dir-local-variables)(hack-local-variables-apply)' unless it is
being called as a result of `normal-mode t'. There's no change needed
for the normal-mode function or anything it calls, except perhaps
setting something that the define-derived-mode macro can check.


For sub-issue #2 "an easier way for us to preserve minor-modes and
buffer-local variables when switching modes"- I discovered this
exchange showing it's been raised before
https://lists.gnu.org/archive/html/emacs-devel/2007-12/msg00366.html
which resulted in adding the property `permanent-local-hook' to
compliment the `permanent-local' property, facilitating minor-mode
preservation. That was in the context of helping mode authors preserve
specific minor-modes. In itself, it isn't enough for a generic
minor-mode preservation but it can help.

A function to preserve any minor-mode needs to

a. Get all of that mode's customizable buffer-locals. Ideally the
minor-mode, or emacs core, would provide a function for that purpose.
If not, might be able to reliably get a list by creating a scratch
buffer, saving results of `buffer-local-variables', enabling the minor
mode in question, then mark the differences from a subsequent call to
`buffer-local-variables'.
b. Mark those variables as permanent-local

Then either

b1. Continue to allow major-mode changes to disable all minor-modes,
but re-enable the user-requested minor-modes after calling
kill-all-local-variables. This doesn't require any use of
`permanent-local-hook'; the minor mode is being disabled and
re-enabled and any hooks can be normally uninstalled & re-installed &
re-run

b2. Apply `permanent-local-hook' to all the minor-mode's hook
functions. The minor mode might provide those symbols via a function
for that purpose, or perhaps they could be auto-discovered.

Alas I don't yet know enough about Emacs' minor-mode handling to get
further with these thoughts. Thanks for bearing with me.

-y




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15577; Package emacs. (Fri, 18 Oct 2013 16:30:02 GMT) Full text and rfc822 format available.

Message #32 received at 15577 <at> debbugs.gnu.org (full text, mbox):

From: Phil Sainty <psainty <at> orcon.net.nz>
To: 15577 <15577 <at> debbugs.gnu.org>
Subject: Re: bug#15577: 24.3; dir-local variables not applied when switching
 major-mode
Date: Sat, 19 Oct 2013 05:29:11 +1300
My gut feeling is that retaining (across a major mode change)
the values of local variables which were set *interactively*
probably isn't a practical thing to try to do?

For starters we would have to flag variables as having been
set interactively, otherwise there would be no way of telling
which local values should be kept and which should be cleared.
(e.g. if a major mode hook sets a local variable, we're not
going to want to retain that when we change major modes.)

But even knowing that a value was set interactively still
isn't a *guarantee* that it should remain unchanged for the
new major mode?

What seems much simpler is to always hack-local-variables
after a major mode change, and simply work out a solution to
the associated problem with local 'mode' variables.

If we do that, then all of the local variables which are
*automatically* set for a given mode will be set correctly,
which is all people actually need, most of the time. That seems
to me like a "good enough" approach (and one which should be
safer).


At present `normal-mode' runs:
(report-errors "File local-variables error: %s"
  (hack-local-variables))

My first thought was to just move that into `run-mode-hooks',
but that relies upon the major mode function running its mode
hook, which I presume isn't guaranteed (and maybe this is exactly
why the code *does* run in `normal-mode'?)

It's unclear to me whether this is a real concern, though -- can we
assume that all major modes *will* call `kill-all-local-variables'
and `run-mode-hooks'? Certainly all the non-derived major modes
I've looked at in the Emacs lisp files take care of these steps
manually.

(Well... I suppose for any modes which don't do this housekeeping,
there's actually nothing we can do to help in the situation when
they are called interactively. So as long as we ensure that things
work when `normal-mode' runs, and also when any *well-behaved*
major mode is called interactively, we'll be doing everything that
we can reasonably do.)

So... how about this as a basic approach:

* Define a new buffer-local variable to track whether local vars
  have been hacked (nil by default). This will obviously get reset
  in any given buffer when a mode calls `kill-all-local-variables';
  and to take care of the case when `set-auto-mode' calls a
  'badly-behaved' mode (one which does not kill local vars), we
  can also let-bind the variable to nil in normal-mode.

* `normal-mode' then tests this variable before calling
  `hack-local-variables', only calling the function if the
  variable is nil. Most of the time, however, it will be
  non-nil, because...

* `run-mode-hooks' calls `hack-local-variables' after it has
  run `after-change-major-mode-hook'. This is therefore the way
  that the vast majority of major modes will set the local vars,
  (but the code in `normal-mode' will still account for
  exceptions).

See diffs below (from 24.3, and untested) for a possible
implementation.

This approach seems a little cleaner than the one used in the
Stack Overflow workaround, as this way we are more consistent
in *where* we call `hack-local-variables' for a given mode (the
other approach would either call it after the mode change OR in
normal-mode, depending on whether or not the mode was called
interactively.)



That leaves the problem of local 'mode' variables making it
impossible to interactively call a different mode (because we
immediately switch back to the mode specified by the local var).

The code has me slightly confused here: `hack-one-local-variable'
calls the mode function when there is a local mode variable, but
my initial thought is that we only want to use a local mode var
when running `set-auto-mode'? Yet set-auto-mode has already set
the mode -- using the (hack-local-variables MODE-ONLY) look-up --
*before* we get to `hack-one-local-variable', so should the latter
function actually ignore 'mode' vars instead? If we did that, then
the problem would go away. I suspect I'm missing something here?

Ah, okay; `autoload-find-file' is an example of code which could
need a mode var to be processed directly by `hack-one-local-variable'.

How about if we provide a new variable which determines whether
or not local mode variables will be applied? Or maybe it should be
an argument to `hack-local-variables'? By default we enable the
behaviour, so there's no change for any code which hacks local
variables directly; but in `normal-mode' and `run-mode-hooks'
we explicitly disable it, so that mode variables are ignored.

(n.b. The example code below does not implement this suggestion.)


-Phil





diff -u -L /usr/local/share/emacs/24.3/lisp/files.el.gz -L \#\<buffer\
files.el.gz\> /tmp/jka-com2287tTC /tmp/buffer-content-2287HoO
--- /usr/local/share/emacs/24.3/lisp/files.el.gz
+++ #<buffer files.el.gz>
@@ -2172,13 +2172,17 @@
 in that case, this function acts as if `enable-local-variables' were t."
   (interactive)
   (funcall (or (default-value 'major-mode) 'fundamental-mode))
-  (let ((enable-local-variables (or (not find-file)
enable-local-variables)))
+  (let ((enable-local-variables (or (not find-file)
enable-local-variables))
+        (local-variables-hacked nil))
     ;; FIXME this is less efficient than it could be, since both
     ;; s-a-m and h-l-v may parse the same regions, looking for "mode:".
     (report-errors "File mode specification error: %s"
       (set-auto-mode))
-    (report-errors "File local-variables error: %s"
-      (hack-local-variables)))
+    ;; Most major modes will hack local vars via `run-mode-hooks';
+    ;; this catches the exceptions:
+    (unless local-variables-hacked
+      (report-errors "File local-variables error: %s"
+        (hack-local-variables))))
   ;; Turn font lock off and on, to make sure it takes account of
   ;; whatever file local variables are relevant to it.
   (when (and font-lock-mode
@@ -3140,6 +3144,11 @@
 		   (assq-delete-all (car elt) file-local-variables-alist)))
 	   (push elt file-local-variables-alist)))))

+(defvar local-variables-hacked nil
+  "Buffer-local variable which indicates whether `hack-local-variables'
+has run for the current buffer.")
+(make-variable-buffer-local 'local-variables-hacked)
+
 (defun hack-local-variables (&optional mode-only)
   "Parse and put into effect this buffer's local variables spec.
 Uses `hack-local-variables-apply' to apply the variables.
@@ -3277,7 +3286,8 @@
       (if mode-only result
 	;; Otherwise, set the variables.
 	(hack-local-variables-filter result nil)
-	(hack-local-variables-apply)))))
+	(hack-local-variables-apply)
+        (setq local-variables-hacked t)))))

 (defun hack-local-variables-apply ()
   "Apply the elements of `file-local-variables-alist'.





diff -u -L /usr/local/share/emacs/24.3/lisp/subr.el.gz -L \#\<buffer\
subr.el.gz\> /tmp/jka-com2287GnH /tmp/buffer-content-2287g7T
--- /usr/local/share/emacs/24.3/lisp/subr.el.gz
+++ #<buffer subr.el.gz>
@@ -1588,7 +1588,9 @@
     (setq hooks (nconc (nreverse delayed-mode-hooks) hooks))
     (setq delayed-mode-hooks nil)
     (apply 'run-hooks (cons 'change-major-mode-after-body-hook hooks))
-    (run-hooks 'after-change-major-mode-hook)))
+    (run-hooks 'after-change-major-mode-hook)
+    (report-errors "File Local-variables error: %s"
+      (hack-local-variables))))

 (defmacro delay-mode-hooks (&rest body)
   "Execute BODY, but delay any `run-mode-hooks'.






Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15577; Package emacs. (Sat, 19 Oct 2013 01:19:01 GMT) Full text and rfc822 format available.

Message #35 received at 15577 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: yary <not.com <at> gmail.com>
Cc: Glenn Morris <rgm <at> gnu.org>, 15577 <15577 <at> debbugs.gnu.org>
Subject: Re: bug#15577: 24.3;
 dir-local variables not applied when switching major-mode
Date: Fri, 18 Oct 2013 21:18:39 -0400
> For sub-issue #1 "dir-locals not being applied in the new mode,"
> divide the responsibility for setting file-locals and dir-locals
> between `normal-mode find-file=t' and `define-derived-mode'. Just have
> `define-derived-mode' call
> `(hack-dir-local-variables)(hack-local-variables-apply)' unless it is
> being called as a result of `normal-mode t'. There's no change needed
> for the normal-mode function or anything it calls, except perhaps
> setting something that the define-derived-mode macro can check.

Yes, as mentioned earlier, a possible fix is to move the file-local and
dir-local setup code from normal-mode to after-change-major-mode-hook.

> a. Get all of that mode's customizable buffer-locals.

Not sure what that is.

> 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.

> 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).

For minor-modes, what we could do is to check which buffer-local
minor-modes are enabled, and to "simply" re-enable them in
after-change-major-mode-hook.

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.
- 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.


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15577; Package emacs. (Sat, 19 Oct 2013 19:09:01 GMT) Full text and rfc822 format available.

Message #38 received at 15577 <at> debbugs.gnu.org (full text, mbox):

From: yary <not.com <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Glenn Morris <rgm <at> gnu.org>, 15577 <15577 <at> debbugs.gnu.org>
Subject: Re: bug#15577: 24.3;
 dir-local variables not applied when switching major-mode
Date: Sat, 19 Oct 2013 15:08:17 -0400
On Fri, Oct 18, 2013 at 9:18 PM, Stefan Monnier
<monnier <at> iro.umontreal.ca> wrote:
>> For sub-issue #1 "dir-locals not being applied in the new mode,"
>> divide the responsibility for setting file-locals and dir-locals
>> between `normal-mode find-file=t' and `define-derived-mode'. Just have
>> `define-derived-mode' call
>> `(hack-dir-local-variables)(hack-local-variables-apply)' unless it is
>> being called as a result of `normal-mode t'. There's no change needed
>> for the normal-mode function or anything it calls, except perhaps
>> setting something that the define-derived-mode macro can check.
>
> Yes, as mentioned earlier, a possible fix is to move the file-local and
> dir-local setup code from normal-mode to after-change-major-mode-hook.

Moving dir-local setup code to after-change-major-mode-hook would be a
simple fix for issue #1. File-local (as it is now) in
after-change-major-mode-hook would cause some problems eg. if a
file-local sets the mode!

I'm opening a new bug for handling file-locals after
major-mode-change, it's different enough to warrant its own discussion
(and will also answer your questions about what I meant there), The
initial report here was about dir-locals, which has a solution
independent from the other buffer-local issues; let's just keep this
bug#15577 about re-applying dir locals after a mode change.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15577; Package emacs. (Sat, 19 Oct 2013 21:56:01 GMT) Full text and rfc822 format available.

Message #41 received at 15577 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: yary <not.com <at> gmail.com>
Cc: Glenn Morris <rgm <at> gnu.org>, 15577 <15577 <at> debbugs.gnu.org>
Subject: Re: bug#15577: 24.3;
 dir-local variables not applied when switching major-mode
Date: Sat, 19 Oct 2013 17:55:09 -0400
> Moving dir-local setup code to after-change-major-mode-hook would be a
> simple fix for issue #1. File-local (as it is now) in
> after-change-major-mode-hook would cause some problems eg. if a
> file-local sets the mode!

Obviously if we move the mode-setting part, we introduce a bug, so we
wouldn't move it (it's already handled separately for the same kind of
reasons).


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15577; Package emacs. (Sun, 20 Oct 2013 13:02:02 GMT) Full text and rfc822 format available.

Message #44 received at 15577 <at> debbugs.gnu.org (full text, mbox):

From: yary <not.com <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Glenn Morris <rgm <at> gnu.org>, 15577 <15577 <at> debbugs.gnu.org>
Subject: Re: bug#15577: 24.3;
 dir-local variables not applied when switching major-mode
Date: Sun, 20 Oct 2013 09:00:57 -0400
For anyone following this discussion, I moved the non-dir-local parts to:

bug#15658: Easy way to make a file-local variable also permanent-local
bug#15659: Simple method for preserving minor-mode

>> Moving dir-local setup code to after-change-major-mode-hook would be a
>> simple fix for issue #1. File-local (as it is now) in
>> after-change-major-mode-hook would cause some problems eg. if a
>> file-local sets the mode!
>
>Obviously if we move the mode-setting part, we introduce a bug, so we
>wouldn't move it (it's already handled separately for the same kind of
>reasons).

Right. So it looks like a patch for moving dir-local setup to
after-change-major-mode-hook is in order. Where I fall down in the
implementation is figuring out what exactly changes so that I don't
change behavior for find-file or kill-all-local-variables, and also
don't set dir-locals twice when opening a file (without using
defadvice which seems wrong in the core). Plus I'd have to get started
as a contributor. Neither are insurmountable, though I think I don't
have much more time to devote to these at the moment.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15577; Package emacs. (Sun, 20 Oct 2013 13:40:02 GMT) Full text and rfc822 format available.

Message #47 received at 15577 <at> debbugs.gnu.org (full text, mbox):

From: Phil Sainty <psainty <at> orcon.net.nz>
To: yary <not.com <at> gmail.com>, Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 15577 <15577 <at> debbugs.gnu.org>
Subject: Re: bug#15577: 24.3; dir-local variables not applied when switching
 major-mode
Date: Mon, 21 Oct 2013 02:38:59 +1300
I've been experimenting with this today (along the lines of
http://lists.gnu.org/archive/html/bug-gnu-emacs/2013-10/msg00534.html )
and one of the things I noticed which I'd not previously considered
was the major mode switches which happen every time you enter the
minibuffer.

I expect that we should make an exception for those mode changes, as
(a) that is going to be a far more frequent occurrence -- and for
people who enable local variable processing for tramp buffers, probably
annoyingly expensive to boot -- but more importantly (b) there surely
aren't any actual use-cases for dir/file locals in the minibuffer?

Does that sound sensible?


-Phil





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15577; Package emacs. (Mon, 21 Oct 2013 13:12:02 GMT) Full text and rfc822 format available.

Message #50 received at 15577 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Phil Sainty <psainty <at> orcon.net.nz>
Cc: yary <not.com <at> gmail.com>, 15577 <15577 <at> debbugs.gnu.org>
Subject: Re: bug#15577: 24.3;
 dir-local variables not applied when switching major-mode
Date: Mon, 21 Oct 2013 09:11:00 -0400
> I've been experimenting with this today (along the lines of
> http://lists.gnu.org/archive/html/bug-gnu-emacs/2013-10/msg00534.html )
> and one of the things I noticed which I'd not previously considered
> was the major mode switches which happen every time you enter the
> minibuffer.

I don't see why that would be a problem: only the *Minibuf-N* buffer
changes major mode (and not even that, really, because mini-buffers
don't follow the rules w.r.t major modes).


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15577; Package emacs. (Mon, 21 Oct 2013 13:25:02 GMT) Full text and rfc822 format available.

Message #53 received at 15577 <at> debbugs.gnu.org (full text, mbox):

From: yary <not.com <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Phil Sainty <psainty <at> orcon.net.nz>, 15577 <15577 <at> debbugs.gnu.org>
Subject: Re: bug#15577: 24.3;
 dir-local variables not applied when switching major-mode
Date: Mon, 21 Oct 2013 09:23:41 -0400
On Mon, Oct 21, 2013 at 9:11 AM, Stefan Monnier
<monnier <at> iro.umontreal.ca> wrote:
>> I've been experimenting with this today (along the lines of
>> http://lists.gnu.org/archive/html/bug-gnu-emacs/2013-10/msg00534.html )
>> and one of the things I noticed which I'd not previously considered
>> was the major mode switches which happen every time you enter the
>> minibuffer.
>
> I don't see why that would be a problem: only the *Minibuf-N* buffer
> changes major mode (and not even that, really, because mini-buffers
> don't follow the rules w.r.t major modes).

I also noticed that going into the minibuffer would trigger
mode-change hooks, and much hilarity ensued when I had a call to the
debugger dropped in there... I don't have more to add other than I am
following these posts with interest, and thanks for running it. Seems
like you will be able to handle both file and dir-locals, and that
splitting out file locals to bug #15658 was premature- I prefer the
way you're going, since it keeps the permanence within the buffer; my
proposal would have set the "permanent-local" property and alas
properties are always global.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15577; Package emacs. (Mon, 21 Oct 2013 14:24:01 GMT) Full text and rfc822 format available.

Message #56 received at 15577 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: yary <not.com <at> gmail.com>
Cc: Phil Sainty <psainty <at> orcon.net.nz>, 15577 <15577 <at> debbugs.gnu.org>
Subject: Re: bug#15577: 24.3;
 dir-local variables not applied when switching major-mode
Date: Mon, 21 Oct 2013 10:23:12 -0400
> I prefer the way you're going,

Just to clarify, in case there was some confusion: I'm not actually
working on any of that.  I'm just giving guidance for someone who wants
to write a patch.


        Stefan "plenty of other things to do right now"




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15577; Package emacs. (Mon, 21 Oct 2013 21:59:01 GMT) Full text and rfc822 format available.

Message #59 received at 15577 <at> debbugs.gnu.org (full text, mbox):

From: "Phil Sainty" <psainty <at> orcon.net.nz>
To: "Stefan Monnier" <monnier <at> iro.umontreal.ca>
Cc: yary <not.com <at> gmail.com>, Phil Sainty <psainty <at> orcon.net.nz>,
 15577 <15577 <at> debbugs.gnu.org>
Subject: Re: bug#15577: 24.3;
 dir-local variables not applied when switching major-mode
Date: Tue, 22 Oct 2013 10:58:37 +1300 (NZDT)
>> I prefer the way you're going,
>
> Just to clarify, in case there was some confusion: I'm not actually
> working on any of that.  I'm just giving guidance for someone who
> wants to write a patch.

That comment may have been directed at me (and I do indeed intend
to provide a patch).

I need to rework some code to make the major mode variable detection
more generally-available, as my existing solution to avoid applying a major
mode local variable depends on hack-local-variables being called, but
that doesn't happen in all cases.

I think it's looking promising, though.


-Phil







Merged 15577 23407. Request was from Glenn Morris <rgm <at> gnu.org> to control <at> debbugs.gnu.org. (Sat, 30 Apr 2016 18:53:02 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#15577; Package emacs. (Thu, 05 May 2016 11:27:02 GMT) Full text and rfc822 format available.

Message #64 received at 15577-done <at> debbugs.gnu.org (full text, mbox):

From: Alan Mackenzie <acm <at> muc.de>
To: 15577-done <at> debbugs.gnu.org
Cc: yary <not.com <at> gmail.com>
Subject: Re: bug#15577: 24.3;
 dir-local variables not applied when switching major-mode
Date: 5 May 2016 11:26:46 -0000
Bug fixed in the master branch of GNU's savannah Emacs repository.

-- 
Alan Mackenzie (Nuremberg, Germany).





bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Fri, 03 Jun 2016 11:24:03 GMT) Full text and rfc822 format available.

This bug report was last modified 7 years and 300 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.