* Mode loaded twice with Local Variables
@ 2006-05-09 9:53 Michaël Cadilhac
2006-05-09 13:22 ` Chong Yidong
` (2 more replies)
0 siblings, 3 replies; 14+ messages in thread
From: Michaël Cadilhac @ 2006-05-09 9:53 UTC (permalink / raw)
[-- Attachment #1.1.1: Type: text/plain, Size: 862 bytes --]
I hope this issue hasn't already been discussed.
Create a file that contains the following:
Local Variables:
mode: foo
eval: (message "aoeu")
End:
named `test.foo'.
Then M-x eval-region RET the following:
(define-derived-mode foo-mode text-mode "foo mode")
(add-hook 'foo-mode-hook (lambda () (message "File opened at %s\n"
(current-time-string))))
(add-to-list 'auto-mode-alist '("\\.foo$" . foo-mode))
Then open `test.foo'. The (message "File opened") will be displayed
twice:
- When set-auto-mode will be called (calling foo-mode),
- When local variables are evaluated (again calling foo-mode).
I don't expect that, in particular, I have some LaTeX file that
contains mode: LaTeX, but some questions are asked in my
LaTeX-mode-hook, so they're asked twice.
I propose this, maybe naive, change:
[-- Attachment #1.1.2: files.patch --]
[-- Type: text/x-patch, Size: 2380 bytes --]
Index: ChangeLog
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/ChangeLog,v
retrieving revision 1.9511
diff -c -r1.9511 ChangeLog
*** ChangeLog 9 May 2006 04:26:22 -0000 1.9511
--- ChangeLog 9 May 2006 09:50:07 -0000
***************
*** 1,3 ****
--- 1,8 ----
+ 2006-05-09 Michaël Cadilhac <michael.cadilhac@lrde.org>
+
+ * files.el (normal-mode): Look at `Local Variables' before
+ `auto-mode-alist' to prevent double mode loading.
+
2006-05-09 Michael Albinus <michael.albinus@gmx.de>
* net/tramp.el (tramp-register-file-name-handlers): Enable Tramp
Index: files.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/files.el,v
retrieving revision 1.830
diff -c -r1.830 files.el
*** files.el 6 May 2006 14:37:04 -0000 1.830
--- files.el 9 May 2006 09:50:07 -0000
***************
*** 1797,1807 ****
in that case, this function acts as if `enable-local-variables' were t."
(interactive)
(funcall (or default-major-mode 'fundamental-mode))
! (let ((enable-local-variables (or (not find-file) enable-local-variables)))
! (report-errors "File mode specification error: %s"
! (set-auto-mode))
(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
--- 1797,1814 ----
in that case, this function acts as if `enable-local-variables' were t."
(interactive)
(funcall (or default-major-mode 'fundamental-mode))
! (let ((enable-local-variables (or (not find-file) enable-local-variables))
! (current-major-mode major-mode))
! (setq major-mode nil)
(report-errors "File local-variables error: %s"
! (hack-local-variables))
! ;; If no major mode was specified by local variables, use auto mode.
! (unless major-mode
! (report-errors "File mode specification error: %s"
! (set-auto-mode))
! ;; No auto mode, restore default one.
! (unless major-mode
! (setq major-mode current-major-mode))))
;; 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
[-- Attachment #1.1.3: Type: text/plain, Size: 325 bytes --]
--
| Michaël `Micha' Cadilhac | Mieux vaut se taire |
| Epita/LRDE Promo 2007 | Que de parler trop fort. |
| http://www.lrde.org/~cadilh_m | -- As de trèfle |
`-- - JID: micha@amessage.be --' - --'
[-- Attachment #1.2: Type: application/pgp-signature, Size: 188 bytes --]
[-- Attachment #2: Type: text/plain, Size: 142 bytes --]
_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Mode loaded twice with Local Variables
2006-05-09 9:53 Mode loaded twice with Local Variables Michaël Cadilhac
@ 2006-05-09 13:22 ` Chong Yidong
2006-05-09 13:53 ` Michaël Cadilhac
2006-05-09 16:08 ` Stuart D. Herring
2006-05-10 3:20 ` Richard Stallman
2 siblings, 1 reply; 14+ messages in thread
From: Chong Yidong @ 2006-05-09 13:22 UTC (permalink / raw)
Cc: emacs-devel
> Then open `test.foo'. The (message "File opened") will be displayed
> twice:
> - When set-auto-mode will be called (calling foo-mode),
> - When local variables are evaluated (again calling foo-mode).
>
> I don't expect that, in particular, I have some LaTeX file that
> contains mode: LaTeX, but some questions are asked in my
> LaTeX-mode-hook, so they're asked twice.
AFAIK, this is the behavior in Emacs 21 as well. Does it create any
real problem? I don't think so.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Mode loaded twice with Local Variables
2006-05-09 13:22 ` Chong Yidong
@ 2006-05-09 13:53 ` Michaël Cadilhac
0 siblings, 0 replies; 14+ messages in thread
From: Michaël Cadilhac @ 2006-05-09 13:53 UTC (permalink / raw)
Cc: emacs-devel
[-- Attachment #1.1: Type: text/plain, Size: 1170 bytes --]
Chong Yidong <cyd@stupidchicken.com> writes:
>> Then open `test.foo'. The (message "File opened") will be displayed
>> twice:
>> - When set-auto-mode will be called (calling foo-mode),
>> - When local variables are evaluated (again calling foo-mode).
>>
>> I don't expect that, in particular, I have some LaTeX file that
>> contains mode: LaTeX, but some questions are asked in my
>> LaTeX-mode-hook, so they're asked twice.
>
> AFAIK, this is the behavior in Emacs 21 as well. Does it create any
> real problem? I don't think so.
As I said: on the loading of some modes, I'm asking question and
make more or less huge processing according to the answers.
Having them made twice is a pain for me. And even if this behavior
is the one of Emacs 21 too, it's still painful.
--
| Michaël `Micha' Cadilhac | All your base are belong to us. |
| Epita/LRDE Promo 2007 | You have no change to survive |
| http://www.lrde.org/~cadilh_m | make your time, hahaha. |
`-- - JID: micha@amessage.be --' -- Zero Wings - --'
[-- Attachment #1.2: Type: application/pgp-signature, Size: 188 bytes --]
[-- Attachment #2: Type: text/plain, Size: 142 bytes --]
_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Mode loaded twice with Local Variables
2006-05-09 9:53 Mode loaded twice with Local Variables Michaël Cadilhac
2006-05-09 13:22 ` Chong Yidong
@ 2006-05-09 16:08 ` Stuart D. Herring
2006-05-10 17:50 ` Richard Stallman
2006-05-10 18:29 ` Michaël Cadilhac
2006-05-10 3:20 ` Richard Stallman
2 siblings, 2 replies; 14+ messages in thread
From: Stuart D. Herring @ 2006-05-09 16:08 UTC (permalink / raw)
Cc: emacs-devel
> I propose this, maybe naive, change:
> [patch to `normal-mode']
How about this? It seems simpler to me.
Davis
PS - I copied the manual implementation of `indirect-function' from
`set-auto-mode-0'. Is there some reason i-f isn't used? Is it just to
avoid errors for unfbound symbols? What if the major mode was itself an
alias, or does that not happen?
***************
*** 2724,2733 ****
ok)))))))
(defun hack-one-local-variable (var val)
! "Set local variable VAR with value VAL."
(cond ((eq var 'mode)
! (funcall (intern (concat (downcase (symbol-name val))
! "-mode"))))
((eq var 'eval)
(save-excursion (eval val)))
(t (make-local-variable var)
--- 2738,2753 ----
ok)))))))
(defun hack-one-local-variable (var val)
! "Set local variable VAR with value VAL.
! If VAR is `mode', call `VAL-mode' as a
! function unless it's already the major mode."
(cond ((eq var 'mode)
! (let ((mode (intern (concat (downcase (symbol-name val)) "-mode"))))
! (while (symbolp (symbol-function mode))
! (setq mode (symbol-function mode)))
! (if (eq mode major-mode)
! (setq mode nil))
! (when mode (funcall mode))))
((eq var 'eval)
(save-excursion (eval val)))
(t (make-local-variable var)
--
This product is sold by volume, not by mass. If it appears too dense or
too sparse, it is because mass-energy conversion has occurred during
shipping.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Mode loaded twice with Local Variables
2006-05-09 16:08 ` Stuart D. Herring
@ 2006-05-10 17:50 ` Richard Stallman
2006-05-10 18:20 ` Stuart D. Herring
2006-05-10 18:29 ` Michaël Cadilhac
1 sibling, 1 reply; 14+ messages in thread
From: Richard Stallman @ 2006-05-10 17:50 UTC (permalink / raw)
Cc: michael.cadilhac, emacs-devel
How about this? It seems simpler to me.
Davis
I think this kind of change is ok for now.
Is there some reason i-f isn't used? Is it just to
avoid errors for unfbound symbols?
We're going to call the function and get the error anyway.
What if the major mode was itself an
alias, or does that not happen?
It could, so the code should do indirect-function on both of them
and compare the results.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Mode loaded twice with Local Variables
2006-05-10 17:50 ` Richard Stallman
@ 2006-05-10 18:20 ` Stuart D. Herring
2006-05-11 18:31 ` Richard Stallman
0 siblings, 1 reply; 14+ messages in thread
From: Stuart D. Herring @ 2006-05-10 18:20 UTC (permalink / raw)
Cc: michael.cadilhac, emacs-devel
[-- Attachment #1: Type: text/plain, Size: 905 bytes --]
> What if the major mode was itself an
> alias, or does that not happen?
>
> It could, so the code should do indirect-function on both of them
> and compare the results.
OK; the attached (tiny) patch does that in both places. This makes the
change that `set-auto-mode-0' now returns its MODE argument instead of the
final symbol (which has the real function definition) in that argument's
indirect function chain. Nothing seems to use the return value anyway;
does this matter? If so, I can write the symbol-chasing loop back in to
get the old return value.
Davis
2006-05-10 Stuart Herring <herring@lanl.gov>
* files.el (set-auto-mode-0): Use `indirect-function'.
(hack-one-local-variable): Don't reapply the current major mode.
--
This product is sold by volume, not by mass. If it appears too dense or
too sparse, it is because mass-energy conversion has occurred during
shipping.
[-- Attachment #2: mode-reapply.patch --]
[-- Type: application/octet-stream, Size: 1861 bytes --]
Index: files.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/files.el,v
retrieving revision 1.831
diff -c -r1.831 files.el
*** files.el 9 May 2006 22:55:30 -0000 1.831
--- files.el 10 May 2006 18:10:15 -0000
***************
*** 2192,2203 ****
If optional arg KEEP-MODE-IF-SAME is non-nil, MODE is chased of
any aliases and compared to current major mode. If they are the
same, do nothing and return nil."
! (when keep-mode-if-same
! (while (symbolp (symbol-function mode))
! (setq mode (symbol-function mode)))
! (if (eq mode major-mode)
! (setq mode nil)))
! (when mode
(funcall mode)
mode))
--- 2192,2199 ----
If optional arg KEEP-MODE-IF-SAME is non-nil, MODE is chased of
any aliases and compared to current major mode. If they are the
same, do nothing and return nil."
! (unless (and keep-mode-if-same
! (eq (indirect-function mode) (indirect-function major-mode)))
(funcall mode)
mode))
***************
*** 2722,2731 ****
ok)))))))
(defun hack-one-local-variable (var val)
! "Set local variable VAR with value VAL."
(cond ((eq var 'mode)
! (funcall (intern (concat (downcase (symbol-name val))
! "-mode"))))
((eq var 'eval)
(save-excursion (eval val)))
(t (make-local-variable var)
--- 2733,2745 ----
ok)))))))
(defun hack-one-local-variable (var val)
! "Set local variable VAR with value VAL.
! If VAR is `mode', call `VAL-mode' as a
! function unless it's already the major mode."
(cond ((eq var 'mode)
! (let ((mode (intern (concat (downcase (symbol-name val)) "-mode"))))
! (unless (eq (indirect-function mode) (indirect-function major-mode))
! (funcall mode))))
((eq var 'eval)
(save-excursion (eval val)))
(t (make-local-variable var)
[-- Attachment #3: Type: text/plain, Size: 142 bytes --]
_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Mode loaded twice with Local Variables
2006-05-09 16:08 ` Stuart D. Herring
2006-05-10 17:50 ` Richard Stallman
@ 2006-05-10 18:29 ` Michaël Cadilhac
2006-05-10 19:59 ` Stuart D. Herring
` (2 more replies)
1 sibling, 3 replies; 14+ messages in thread
From: Michaël Cadilhac @ 2006-05-10 18:29 UTC (permalink / raw)
Cc: emacs-devel
[-- Attachment #1.1: Type: text/plain, Size: 1839 bytes --]
"Stuart D. Herring" <herring@lanl.gov> writes:
> ***************
> *** 2724,2733 ****
> ok)))))))
>
> (defun hack-one-local-variable (var val)
> ! "Set local variable VAR with value VAL."
> (cond ((eq var 'mode)
> ! (funcall (intern (concat (downcase (symbol-name val))
> ! "-mode"))))
> ((eq var 'eval)
> (save-excursion (eval val)))
> (t (make-local-variable var)
> --- 2738,2753 ----
> ok)))))))
>
> (defun hack-one-local-variable (var val)
> ! "Set local variable VAR with value VAL.
> ! If VAR is `mode', call `VAL-mode' as a
> ! function unless it's already the major mode."
> (cond ((eq var 'mode)
> ! (let ((mode (intern (concat (downcase (symbol-name val)) "-mode"))))
> ! (while (symbolp (symbol-function mode))
> ! (setq mode (symbol-function mode)))
> ! (if (eq mode major-mode)
> ! (setq mode nil))
> ! (when mode (funcall mode))))
> ((eq var 'eval)
> (save-excursion (eval val)))
> (t (make-local-variable var)
I didn't think it was the right fix for one reason : some modes
/may/ behave differently on startup if /some/ variables have
/certain/ values. In other words, Local Variables would set
variables to some value before launching the mode, expecting
a specified behavior.
My change provides this feature, AFAIK, but I do agree that it could
be too... dangerous to patch normal-mode, and not so needed.
Regards.
--
| Michaël `Micha' Cadilhac | Un certain Blaise Pascal |
| Epita/LRDE Promo 2007 | etc... etc... |
| http://www.lrde.org/~cadilh_m | -- Prévert (Les paris stupides) |
`-- - JID: micha@amessage.be --' - --'
[-- Attachment #1.2: Type: application/pgp-signature, Size: 188 bytes --]
[-- Attachment #2: Type: text/plain, Size: 142 bytes --]
_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Mode loaded twice with Local Variables
2006-05-10 18:29 ` Michaël Cadilhac
@ 2006-05-10 19:59 ` Stuart D. Herring
2006-05-11 18:31 ` Richard Stallman
2006-05-11 18:31 ` Richard Stallman
2006-06-14 23:09 ` Stuart D. Herring
2 siblings, 1 reply; 14+ messages in thread
From: Stuart D. Herring @ 2006-05-10 19:59 UTC (permalink / raw)
Cc: emacs-devel
> I didn't think it was the right fix for one reason : some modes
> /may/ behave differently on startup if /some/ variables have
> /certain/ values. In other words, Local Variables would set
> variables to some value before launching the mode, expecting
> a specified behavior.
>
> My change provides this feature, AFAIK, but I do agree that it could
> be too... dangerous to patch normal-mode, and not so needed.
I'm not sure that's how major modes are supposed to behave. I don't
expect them to _do_ too much on startup; they ought to define commands and
bindings which may depend on variables, but which will execute later (well
after the application of local variables). Additionally, major modes run
`kill-all-local-variables', so it would currently be disastrous to
exchange those two activities (I now realize).
But the very existence of major mode hooks makes me doubt myself. WDOT?
If it'd be better to set up the mode last, perhaps `normal-mode' ought to:
1. Somehow discover what major mode should be set (via variable or
otherwise).
2. `kill-all-local-variables' if the major mode is going to change.
3. `hack-local-variables' without setting the mode.
4. Set the mode, if it changed.
But this is very much more complicated than just preventing double-loading
the mode, so should probably happen later if ever.
Davis
PS - For amusement, load a file with this:
-*- mode: normal; -*-
--
This product is sold by volume, not by mass. If it appears too dense or
too sparse, it is because mass-energy conversion has occurred during
shipping.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Mode loaded twice with Local Variables
2006-05-10 19:59 ` Stuart D. Herring
@ 2006-05-11 18:31 ` Richard Stallman
2006-05-11 19:00 ` Stuart D. Herring
0 siblings, 1 reply; 14+ messages in thread
From: Richard Stallman @ 2006-05-11 18:31 UTC (permalink / raw)
Cc: michael.cadilhac, emacs-devel
If it'd be better to set up the mode last,
Then all the local variables would be lost!
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Mode loaded twice with Local Variables
2006-05-11 18:31 ` Richard Stallman
@ 2006-05-11 19:00 ` Stuart D. Herring
0 siblings, 0 replies; 14+ messages in thread
From: Stuart D. Herring @ 2006-05-11 19:00 UTC (permalink / raw)
Cc: michael.cadilhac, emacs-devel
> If it'd be better to set up the mode last,
>
> Then all the local variables would be lost!
Ooh. Yeah. I mentioned that very result in my email and then turned
around and ignored it. Doing the major mode after local variables would
then involve not only
1. Detecting the mode-change ahead of time and killing variables then
2. Applying the local variables without setting the mode
but also
3. Applying the major mode without killing local variables.
3 would require modifying every major mode to do correctly, although it
could be faked by temporarily redefining `kill-all-local-variables'.
Moreover, it would change very fundamental rules about modes. Definitely
don't want to do this now, if ever. So my previous patch is probably the
best we're going to do.
Davis
--
This product is sold by volume, not by mass. If it appears too dense or
too sparse, it is because mass-energy conversion has occurred during
shipping.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Mode loaded twice with Local Variables
2006-05-10 18:29 ` Michaël Cadilhac
2006-05-10 19:59 ` Stuart D. Herring
@ 2006-05-11 18:31 ` Richard Stallman
2006-06-14 23:09 ` Stuart D. Herring
2 siblings, 0 replies; 14+ messages in thread
From: Richard Stallman @ 2006-05-11 18:31 UTC (permalink / raw)
Cc: emacs-devel
I didn't think it was the right fix for one reason : some modes
/may/ behave differently on startup if /some/ variables have
/certain/ values. In other words, Local Variables would set
variables to some value before launching the mode, expecting
a specified behavior.
Every major mode command discards all local variable bindings, first thing,
so that isn't going to happen. (The exception, permanent locals, is only
meant for variables that _do not_ relate to the major mode at all.)
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Mode loaded twice with Local Variables
2006-05-10 18:29 ` Michaël Cadilhac
2006-05-10 19:59 ` Stuart D. Herring
2006-05-11 18:31 ` Richard Stallman
@ 2006-06-14 23:09 ` Stuart D. Herring
2 siblings, 0 replies; 14+ messages in thread
From: Stuart D. Herring @ 2006-06-14 23:09 UTC (permalink / raw)
Cc: emacs-devel
> I didn't think it was the right fix for one reason : some modes
> /may/ behave differently on startup if /some/ variables have
> /certain/ values. In other words, Local Variables would set
> variables to some value before launching the mode, expecting
> a specified behavior.
>
> My change provides this feature, AFAIK, but I do agree that it could
> be too... dangerous to patch normal-mode, and not so needed.
I've suddenly run into a very similar thing when writing a mode -- wanting
it to depend on file-local variables at "startup". Perhaps you'll be
interested to note the solution I found:
hack-local-variables-hook's value is nil
Documentation:
Normal hook run after processing a file's local variables specs.
Major modes can use this to examine user-specified local variables
in order to initialize other data structure based on them.
Defined in `files'.
As far as I can tell, it's run whether or not there actually were any
variables to set, so it's useful as a core component of a major mode.
Hope it helps,
Davis
--
This product is sold by volume, not by mass. If it appears too dense or
too sparse, it is because mass-energy conversion has occurred during
shipping.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Mode loaded twice with Local Variables
2006-05-09 9:53 Mode loaded twice with Local Variables Michaël Cadilhac
2006-05-09 13:22 ` Chong Yidong
2006-05-09 16:08 ` Stuart D. Herring
@ 2006-05-10 3:20 ` Richard Stallman
2 siblings, 0 replies; 14+ messages in thread
From: Richard Stallman @ 2006-05-10 3:20 UTC (permalink / raw)
Cc: emacs-devel
It would be cleaner to set up the major mode only once, as you
suggest. However, there is some risk in the change. So let's change
it after the release, not now.
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2006-06-14 23:09 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-05-09 9:53 Mode loaded twice with Local Variables Michaël Cadilhac
2006-05-09 13:22 ` Chong Yidong
2006-05-09 13:53 ` Michaël Cadilhac
2006-05-09 16:08 ` Stuart D. Herring
2006-05-10 17:50 ` Richard Stallman
2006-05-10 18:20 ` Stuart D. Herring
2006-05-11 18:31 ` Richard Stallman
2006-05-10 18:29 ` Michaël Cadilhac
2006-05-10 19:59 ` Stuart D. Herring
2006-05-11 18:31 ` Richard Stallman
2006-05-11 19:00 ` Stuart D. Herring
2006-05-11 18:31 ` Richard Stallman
2006-06-14 23:09 ` Stuart D. Herring
2006-05-10 3:20 ` Richard Stallman
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.