Subject: Re: bug#347: C mode asks twice about local variables

From: Alan Mackenzie <[email-masked]>
Date: Mon, 9 Jun 2008 14:36:51 +0000

Hi, Stefan and Glenn,

On Tue, Jun 03, 2008 at 02:40:29AM -0400, Stefan Monnier wrote:
> > Yes.  This needs fixing, somehow.
> 
> > The way this happens is that in a C file's local variables list, there
> > are two "special" variables, e.g. `c-file-style'.
> 
> > When 
> 
> >     c-basic-offset: 11
> >     c-file-style: "k&r"
> 
> > occurs in the local variable list, this triggers a hook function
> > which calls (c-set-style "k&r").  The hook is
> > hack-local-variables-hook.  The problem is that this c-set-style call
> > will overwrite the explicit value for c-basic-offset.  The explicit
> > value MUST take precedence here.
 
> Can you try and call `c-file-style' with some extra "don't override"
> (when called from that hack-local-variables-hook) argument so that any
> variable that already has a buffer-local binding will not be
> overridden?

> > My solution was to call hack-local-variables a second time from
> > within the hook function, first having deleted any occurrences of
> > `mode', `c-file-style' etc. from the Local Variables.  This kludge
> > worked reasonably well until the handling of
> > safe/dangerous-local-variables was changed for Emacs 22.

> How 'bout wrapping the call inside (let ((enable-local-variables
> :safe))?

I've been thinking this over.  It's not the right solution.  For a start,
the second call to `hack-local-variables' is in itself a kludge.

More importantly, the value ":safe" is non-portable (to earlier Emacsen,
or to the other one), and doesn't feel at all safe.  I'd have to emulate,
to some extent, the processing of `enable-local-variables' inside CC Mode
code, and this variable gives the distinct feeling of not yet having
reached its final definition.  And I'd almost certainly get this wrong,
either causing lots of bug reports for the failure of LV handling or
leaving a security hole for unsafe variables.

The right thing is to increase the granularity of control over the Local
Variables handling.  In particular, to have a new hook called just after
parsing the local variables, but before setting them.  I think it should
look like this:

#########################################################################
(defvar before-hack-local-variables-hook nil
  "Normal hook run before setting a file's local variables.
This hook is called only when there is at least one local
variable to set.

At the time of call, the content of the \"-*-\" line at the top
of the buffer and of any \"Local Variables\" section have been
parsed, respectively in the two dynamically bound variables
`hack-variables-on-prop-line' and `hack-variables-in-list'.  Each
of these is an alist with elements of the form (VAR . VALUE), VAR
being the name of the variable to set and VALUE the raw string
representation of its value.  The elements are in the same order
as in the buffer.

A hook function may change the value of either of these alists.

Point is at the start of the line with \"Local Variables\", or at
the beginning of buffer if there is no such line.")
#########################################################################

What do you think?

>         Stefan

-- 
Alan Mackenzie (Nuremberg, Germany).