unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#57003: 28.1.90; Can local variables be loaded before loading major mode?
@ 2022-08-05 11:44 Ihor Radchenko
  2022-08-06 13:06 ` Lars Ingebrigtsen
  0 siblings, 1 reply; 15+ messages in thread
From: Ihor Radchenko @ 2022-08-05 11:44 UTC (permalink / raw)
  To: 57003


Hi,

Some user settings in Org mode need to be set before loading the major mode.
Further, some people want to set such settings in individual files using file-local variables.

However, Emacs loads file-local variables only _after_ major mode is being loaded.
As a result, we are getting user requests like https://list.orgmode.org/587be554-906c-5370-2cf2-f08b14fa58ff@gmail.com/T/#u

Currently, Elisp allows manual loading of file-local variables via `hack-local-variables'. However, this function itself is too forceful, and it is running, e.g. in non-file buffers. Moreover, calling `hack-local-variables' does not prevent its subsequent call after Org mode is loaded, which sometimes causes double unsafe variable prompts.
See https://list.orgmode.org/87r11wkmew.fsf@ucl.ac.uk/T/#mab6359ed2107d5515c6bb6b266551f0c5049ceca

Would it be possible in Emacs to implement a function or possibly major-mode option that will make Emacs load local variables before loading major mode, not after?

Best,
Ihor





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

* bug#57003: 28.1.90; Can local variables be loaded before loading major mode?
  2022-08-05 11:44 bug#57003: 28.1.90; Can local variables be loaded before loading major mode? Ihor Radchenko
@ 2022-08-06 13:06 ` Lars Ingebrigtsen
  2022-08-06 13:35   ` Ihor Radchenko
  0 siblings, 1 reply; 15+ messages in thread
From: Lars Ingebrigtsen @ 2022-08-06 13:06 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: 57003

Ihor Radchenko <yantar92@gmail.com> writes:

> Some user settings in Org mode need to be set before loading the major mode.
> Further, some people want to set such settings in individual files
> using file-local variables.
>
> However, Emacs loads file-local variables only _after_ major mode is
> being loaded.
> As a result, we are getting user requests like
> https://list.orgmode.org/587be554-906c-5370-2cf2-f08b14fa58ff@gmail.com/T/#u

Is the problem here that there are defvars in the major-mode file being
loaded that depend on one another?  (I'm not sure I understand the
explanation in that bug report.)

If that's the case, then this is inherently fragile, since the user may
have already loaded the .el file otherwise.  So visiting files in a
different order will lead to other results, and eval-ing local variables
before loading the files won't really help, in general.





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

* bug#57003: 28.1.90; Can local variables be loaded before loading major mode?
  2022-08-06 13:06 ` Lars Ingebrigtsen
@ 2022-08-06 13:35   ` Ihor Radchenko
  2022-08-06 14:00     ` Visuwesh
  2022-08-07 12:44     ` Lars Ingebrigtsen
  0 siblings, 2 replies; 15+ messages in thread
From: Ihor Radchenko @ 2022-08-06 13:35 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 57003

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Is the problem here that there are defvars in the major-mode file being
> loaded that depend on one another?  (I'm not sure I understand the
> explanation in that bug report.)

No.

Let me try to explain a simple case when setting variables before/after
loading Org mode matters.

We have a variable org-startup-folded:

   Non-nil means entering Org mode will switch to OVERVIEW.

This variable controls the initial state of the Org buffer.
When, non-nil, headings will be folded at the end of Org initialization.
This folding happens inside org-mode specification and hence setting the
variable after Org mode is loaded makes no difference.

There are also less trivial cases like some variables controlling Org
parser. For example, we have org-todo-keywords. Its value controls how
the headlines are parsed. Because Org parser is initialized during Org
loading, setting this variable after loading Org mode can be simply
disastrous.

Best,
Ihor






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

* bug#57003: 28.1.90; Can local variables be loaded before loading major mode?
  2022-08-06 13:35   ` Ihor Radchenko
@ 2022-08-06 14:00     ` Visuwesh
  2022-08-06 14:34       ` Phil Sainty
  2022-08-07 12:44     ` Lars Ingebrigtsen
  1 sibling, 1 reply; 15+ messages in thread
From: Visuwesh @ 2022-08-06 14:00 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: Lars Ingebrigtsen, 57003

[சனி ஆகஸ்ட் 06, 2022] Ihor Radchenko wrote:

> Lars Ingebrigtsen <larsi@gnus.org> writes:
>
>> Is the problem here that there are defvars in the major-mode file being
>> loaded that depend on one another?  (I'm not sure I understand the
>> explanation in that bug report.)
>
> No.
>
> Let me try to explain a simple case when setting variables before/after
> loading Org mode matters.
>
> We have a variable org-startup-folded:
>
>    Non-nil means entering Org mode will switch to OVERVIEW.
>
> This variable controls the initial state of the Org buffer.
> When, non-nil, headings will be folded at the end of Org initialization.
> This folding happens inside org-mode specification and hence setting the
> variable after Org mode is loaded makes no difference.
>
> There are also less trivial cases like some variables controlling Org
> parser. For example, we have org-todo-keywords. Its value controls how
> the headlines are parsed. Because Org parser is initialized during Org
> loading, setting this variable after loading Org mode can be simply
> disastrous.

Correct me if I'm wrong, this is about the major-mode definition
clearing the buffer's local variables before turning on the major-mode,
right?  If so, I was hit by this for a personal package too where I
needed to expose a local variable for the major-mode-hook but failed
because the function created `define-derived-mode' clears the buffer
local variables before running the major-mode-hook and the major-mode's
BODY.





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

* bug#57003: 28.1.90; Can local variables be loaded before loading major mode?
  2022-08-06 14:00     ` Visuwesh
@ 2022-08-06 14:34       ` Phil Sainty
  0 siblings, 0 replies; 15+ messages in thread
From: Phil Sainty @ 2022-08-06 14:34 UTC (permalink / raw)
  To: Visuwesh; +Cc: Lars Ingebrigtsen, 57003, Ihor Radchenko

On 2022-08-07 02:00, Visuwesh wrote:
> Correct me if I'm wrong, this is about the major-mode definition
> clearing the buffer's local variables before turning on the major-mode,
> right?

To elaborate, every major mode calls `kill-all-local-variables',
and this is pretty much the first thing that happens (although
`change-major-mode-hook' runs before the local variables are
actually clobbered).

https://stackoverflow.com/a/19295380/324105 (specifically the
"Derived modes, and mode hooks" section) might be a useful write-up
if you want to get your head around the sequence of events.

Note that variables which are marked as permanent-local will
retain their values.  Refer to:

M-x elisp-index-search RET kill-all-local-variables


-Phil






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

* bug#57003: 28.1.90; Can local variables be loaded before loading major mode?
  2022-08-06 13:35   ` Ihor Radchenko
  2022-08-06 14:00     ` Visuwesh
@ 2022-08-07 12:44     ` Lars Ingebrigtsen
  2022-08-07 13:23       ` Ihor Radchenko
  1 sibling, 1 reply; 15+ messages in thread
From: Lars Ingebrigtsen @ 2022-08-07 12:44 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: 57003

Ihor Radchenko <yantar92@gmail.com> writes:

> We have a variable org-startup-folded:
>
>    Non-nil means entering Org mode will switch to OVERVIEW.
>
> This variable controls the initial state of the Org buffer.
> When, non-nil, headings will be folded at the end of Org initialization.
> This folding happens inside org-mode specification and hence setting the
> variable after Org mode is loaded makes no difference.

I see.  In that case, it does seem attractive to allow file-local
variables to set the variables before running the mode.  However, as
Visuwesh points out, a major mode clears buffer-local variables, so just
setting them before running the mode won't do anything.

So I think the interface here is just a bit confused and confusing.  It
would make more sense to allow users to do these things via mode
hooks/interface functions instead of variables.






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

* bug#57003: 28.1.90; Can local variables be loaded before loading major mode?
  2022-08-07 12:44     ` Lars Ingebrigtsen
@ 2022-08-07 13:23       ` Ihor Radchenko
  2022-08-07 13:30         ` Lars Ingebrigtsen
  0 siblings, 1 reply; 15+ messages in thread
From: Ihor Radchenko @ 2022-08-07 13:23 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 57003

Lars Ingebrigtsen <larsi@gnus.org> writes:

> I see.  In that case, it does seem attractive to allow file-local
> variables to set the variables before running the mode.  However, as
> Visuwesh points out, a major mode clears buffer-local variables, so just
> setting them before running the mode won't do anything.

Indeed. I imagine something like :before-hook in `define-derived-mode'
that will run just before the mode body.

Or maybe more direct :hack-local-variables-when defining when to run
`hack-local-variables' in contrast to currently hard-coded call in
`run-mode-hooks'. This is not equivalent to calling
`hack-local-variables' in :before-hook because `run-mode-hooks' would
call `hack-local-variables' second time in such a case.

Or maybe something more user-facing like major-mode-before-init-hook
that will be executed before the major mode body form in
`define-derived-mode'.

> So I think the interface here is just a bit confused and confusing.  It
> would make more sense to allow users to do these things via mode
> hooks/interface functions instead of variables.

Agree. However, the file-local variables specifically are not equivalent
to the mode hooks. File/directory-local variables can be set on
per-file/per-project basis, which is much more convenient compared to
explicitly defining a global hook.

Best,
Ihor






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

* bug#57003: 28.1.90; Can local variables be loaded before loading major mode?
  2022-08-07 13:23       ` Ihor Radchenko
@ 2022-08-07 13:30         ` Lars Ingebrigtsen
  2022-08-07 13:52           ` Ihor Radchenko
  0 siblings, 1 reply; 15+ messages in thread
From: Lars Ingebrigtsen @ 2022-08-07 13:30 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: 57003

Ihor Radchenko <yantar92@gmail.com> writes:

> Agree. However, the file-local variables specifically are not equivalent
> to the mode hooks. File/directory-local variables can be set on
> per-file/per-project basis, which is much more convenient compared to
> explicitly defining a global hook.

I think you can say something like

(eval . (org-startup-folded-mode))

to your .dir-locals (etc) to achieve this.  (And then you have to add
that to `safe-local-eval-forms' to avoid getting prompted, but Org could
do that in general.  And, of course, add this functionality as a minor
mode instead of just a variable.)






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

* bug#57003: 28.1.90; Can local variables be loaded before loading major mode?
  2022-08-07 13:30         ` Lars Ingebrigtsen
@ 2022-08-07 13:52           ` Ihor Radchenko
  2022-08-08 11:28             ` Lars Ingebrigtsen
  0 siblings, 1 reply; 15+ messages in thread
From: Ihor Radchenko @ 2022-08-07 13:52 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 57003

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Ihor Radchenko <yantar92@gmail.com> writes:
>
>> Agree. However, the file-local variables specifically are not equivalent
>> to the mode hooks. File/directory-local variables can be set on
>> per-file/per-project basis, which is much more convenient compared to
>> explicitly defining a global hook.
>
> I think you can say something like
>
> (eval . (org-startup-folded-mode))
>
> to your .dir-locals (etc) to achieve this.  (And then you have to add
> that to `safe-local-eval-forms' to avoid getting prompted, but Org could
> do that in general.  And, of course, add this functionality as a minor
> mode instead of just a variable.)

I do not think that it is a good idea.

1. Having a need to do the eval is not expected by users.
2. Allowing eval is not safe compared to setting variables. Your
   suggestion about `safe-local-eval-forms' will not work well because
   even in your example it is not just about running
   (org-startup-folded-mode); org-startup-folded has 7 allowed values -
   marking each (org-startup-folded-mode value) form as safe sounds
   awkward.
3. org-startup-folded is just an example. We have numerous variables
   like this. I can recall at least several dozens without looking into
   source code. Creating a minor mode for each and every single possible
   variable like this is not maintainable. We will certainly forget
   creating dedicated modes when adding similar variables in future.
4. We have a somewhat similar approach in org-link settings - each link
   type is activated by evaluating a sexp. The result is slow Org
   startup time.

   If we implement per-file settings like you suggested, each setting
   will require partial re-evaluation of (org-mode). 
   A handful of settings like you suggested will easily degrade Org
   startup time by an order of magnitude.

Best,
Ihor





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

* bug#57003: 28.1.90; Can local variables be loaded before loading major mode?
  2022-08-07 13:52           ` Ihor Radchenko
@ 2022-08-08 11:28             ` Lars Ingebrigtsen
  2022-08-08 12:30               ` Ihor Radchenko
  0 siblings, 1 reply; 15+ messages in thread
From: Lars Ingebrigtsen @ 2022-08-08 11:28 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: 57003

Ihor Radchenko <yantar92@gmail.com> writes:

> 1. Having a need to do the eval is not expected by users.
> 2. Allowing eval is not safe compared to setting variables. Your
>    suggestion about `safe-local-eval-forms' will not work well because
>    even in your example it is not just about running
>    (org-startup-folded-mode); org-startup-folded has 7 allowed values -
>    marking each (org-startup-folded-mode value) form as safe sounds
>    awkward.

I'd forgotten that you can just enable minor modes without any of that.
You can just say

((org-mode . ((mode . org-startup-folded-mode))))

Or of there are different types:

((org-mode . ((org-startup-type . foo)
              (mode . org-startup-folded-mode))))

> 3. org-startup-folded is just an example. We have numerous variables
>    like this. I can recall at least several dozens without looking into
>    source code. Creating a minor mode for each and every single possible
>    variable like this is not maintainable. We will certainly forget
>    creating dedicated modes when adding similar variables in future.

There's dozens of variables that have to be set before `org-mode' is
called?  That sounds like an fragile design.






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

* bug#57003: 28.1.90; Can local variables be loaded before loading major mode?
  2022-08-08 11:28             ` Lars Ingebrigtsen
@ 2022-08-08 12:30               ` Ihor Radchenko
  2022-08-08 12:35                 ` Lars Ingebrigtsen
  0 siblings, 1 reply; 15+ messages in thread
From: Ihor Radchenko @ 2022-08-08 12:30 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 57003

Lars Ingebrigtsen <larsi@gnus.org> writes:

>> 3. org-startup-folded is just an example. We have numerous variables
>>    like this. I can recall at least several dozens without looking into
>>    source code. Creating a minor mode for each and every single possible
>>    variable like this is not maintainable. We will certainly forget
>>    creating dedicated modes when adding similar variables in future.
>
> There's dozens of variables that have to be set before `org-mode' is
> called?  That sounds like an fragile design.

This is not strictly necessary to set them before the whole Org is
loaded. In some cases, only part of Org has to be reloaded: font-locking
setup; parser; folding state; etc (which is a normal scenario when done
interactively). However, such reloading adds up to file opening time. It
is much faster to set everything once and load Org compared to (1) load
org; (2) load variable and reload org; (3) load another variable and
reload org; and so on.

+ creating a dedicated minor mode for every variable is not maintainable.

Having Emacs support early setting would be much easier.

Best,
Ihor






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

* bug#57003: 28.1.90; Can local variables be loaded before loading major mode?
  2022-08-08 12:30               ` Ihor Radchenko
@ 2022-08-08 12:35                 ` Lars Ingebrigtsen
  2022-08-08 12:58                   ` Ihor Radchenko
  0 siblings, 1 reply; 15+ messages in thread
From: Lars Ingebrigtsen @ 2022-08-08 12:35 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: 57003

Ihor Radchenko <yantar92@gmail.com> writes:

> Having Emacs support early setting would be much easier.

You could make the relevant Org variables `permanent-local' -- then
calling `org-mode' won't clear them out.






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

* bug#57003: 28.1.90; Can local variables be loaded before loading major mode?
  2022-08-08 12:35                 ` Lars Ingebrigtsen
@ 2022-08-08 12:58                   ` Ihor Radchenko
  2022-08-08 14:23                     ` Lars Ingebrigtsen
  0 siblings, 1 reply; 15+ messages in thread
From: Ihor Radchenko @ 2022-08-08 12:58 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 57003

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Ihor Radchenko <yantar92@gmail.com> writes:
>
>> Having Emacs support early setting would be much easier.
>
> You could make the relevant Org variables `permanent-local' -- then
> calling `org-mode' won't clear them out.

Could you please elaborate on how it is going to help with loading
file-local variables before loading Org mode?

Best,
Ihor





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

* bug#57003: 28.1.90; Can local variables be loaded before loading major mode?
  2022-08-08 12:58                   ` Ihor Radchenko
@ 2022-08-08 14:23                     ` Lars Ingebrigtsen
  2022-08-09 11:29                       ` Ihor Radchenko
  0 siblings, 1 reply; 15+ messages in thread
From: Lars Ingebrigtsen @ 2022-08-08 14:23 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: 57003

Ihor Radchenko <yantar92@gmail.com> writes:

>>> Having Emacs support early setting would be much easier.
>>
>> You could make the relevant Org variables `permanent-local' -- then
>> calling `org-mode' won't clear them out.
>
> Could you please elaborate on how it is going to help with loading
> file-local variables before loading Org mode?

Sorry, phrased that all wrong -- I meant that if we had a mechanism to
read the dir-locals earlier, then if you make the variables
permanently-local, then things would indeed work fine without any
further scaffolding here.

So perhaps we should just allow that, but I'm not sure how we'd specify
this.






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

* bug#57003: 28.1.90; Can local variables be loaded before loading major mode?
  2022-08-08 14:23                     ` Lars Ingebrigtsen
@ 2022-08-09 11:29                       ` Ihor Radchenko
  0 siblings, 0 replies; 15+ messages in thread
From: Ihor Radchenko @ 2022-08-09 11:29 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 57003

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Sorry, phrased that all wrong -- I meant that if we had a mechanism to
> read the dir-locals earlier, then if you make the variables
> permanently-local, then things would indeed work fine without any
> further scaffolding here.
>
> So perhaps we should just allow that, but I'm not sure how we'd specify
> this.

I am not sure what you mean by earlier.

The first thing executed when activating a major-mode is (according to
define-derived-mode) kill-all-local-variables which consist of

  run_hook (Qchange_major_mode_hook);
  reset_buffer_local_variables (current_buffer, 0);
  bset_update_mode_line (current_buffer);

Having 'permanent-local variables will only affect
change-major-mode-hook. I know no other hook ran earlier.

Why not instead add something that is run _after_
kill-all-local-variables? Then, there will be no need to fiddle with
'permanently-local (which might have undesired side effects).

Best,
Ihor








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

end of thread, other threads:[~2022-08-09 11:29 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-05 11:44 bug#57003: 28.1.90; Can local variables be loaded before loading major mode? Ihor Radchenko
2022-08-06 13:06 ` Lars Ingebrigtsen
2022-08-06 13:35   ` Ihor Radchenko
2022-08-06 14:00     ` Visuwesh
2022-08-06 14:34       ` Phil Sainty
2022-08-07 12:44     ` Lars Ingebrigtsen
2022-08-07 13:23       ` Ihor Radchenko
2022-08-07 13:30         ` Lars Ingebrigtsen
2022-08-07 13:52           ` Ihor Radchenko
2022-08-08 11:28             ` Lars Ingebrigtsen
2022-08-08 12:30               ` Ihor Radchenko
2022-08-08 12:35                 ` Lars Ingebrigtsen
2022-08-08 12:58                   ` Ihor Radchenko
2022-08-08 14:23                     ` Lars Ingebrigtsen
2022-08-09 11:29                       ` Ihor Radchenko

Code repositories for project(s) associated with this inbox:

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).