emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: smie-next-sexp vs associative operators


From: Stephen Leake
Subject: Re: smie-next-sexp vs associative operators
Date: Tue, 23 Oct 2012 19:14:08 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.2 (windows-nt)

Stefan Monnier <address@hidden> writes:

>> This is the prefered indentation. I'm using it as an example of a case
>> when calling smie-backward-sexp is necessary, when computing the
>> indentation of F.
>
> Yes, smie-backward-sexp is often needed, but very rarely directly in
> indentation rules.

Right; it is buried lower than that in my code as well. The point is
that it is called, not how directly it is called.

>> That's what modula-2-mode does as well; smie-indent-after-keyword calls
>> smie-indent-virtual to compute the indentation for "then"; that calls
>> smie-indent-keyword, which calls (smie-backward-sexp token), with
>> `token' = "then". This parses all the way back to "if".
>
> That's actually a bug: the THEN should be indented relative to its
> corresponding ELSIF (if any) rather than to the top IF.

_all_ of the keywords in the if/then/elsif/else/endif, and in every
other multi-keyword statement in modula-2 and Ada, work this way; they
_all_ jump to the first keyword in the statement. Except for the ones
that happen to be associative. You'd have to totally rewrite
smie-backward-sexp, to fix this "bug".

>>> More specifically, with point right after an "elsif", I'd expect C-M-b
>>> to stop right after the previous "elsif".
>> How is that useful for indentation?
>
> It's useful because it lets the indentation work by looking at a smaller
> part of the buffer.  This is good for performance, and it is good for
> graceful degradation (when we misparse some part of the code).

Optimizing for performance is premature at this point in my project;
simplicity of design is much preferable. I can change this setting
later, if I need the performance gain.

I can believe it might be useful for graceful degradation; I have not done
much testing on Ada mode for that yet.

Have people complained about modula-2-mode for this?

> It's also useful when the user doesn't like the auto-indentation's
> choice, since we use the user's choice of where to indent the previous
> `elsif'.

I admit there are times when I override the indentation engine's choice
with Ada mode 4.01. But they are extremely rare, and that's part of why
I'm rewriting it :).

But all of this just goes to say that the current behavior of
smie-backward-sexp for _non_-associative operators is wrong in the first
place; that's a _major_ redesign!

>>> (exp ("if" expthenexp "end")
>>> ("if" expthenexp "else" exp "end")
>>> ("if" expthenexp "elsif" expthenexp "end")
>>> ("if" expthenexp "elsif" expthenexp "end")
>>> (expthenexp (exp "then" exp))
>> I tried that (see the attached example_grammars.el, grammar-3). It does
>> change the levels assigned by the grammar compiler. But "then" does not
>> have equal left and right levels, and the behavior of smie-backward-sexp
>> is no more useful, as far as I can tell.
>
> I don't know what would be "useful" to you and/or why the changes
> aren't "useful".

That is pretty much the crux of the matter; we have different visions
about how indentation engines should work, partly influenced by the
different languages we are implementing.

As a tool intended to be shared by many languages, smie should
accomodate both visions, and it does so quite nicely, except for this
one minor point.

>> I've verified that the patch shown below allows me to make
>> smie-backward-sexp behave the same for the Ada "select/or" and
>> "if/elsif" statements. 
>
> Can you tell me in terms of C-M-f or C-M-b in which circumstance they
> don't behave identically (and show me the corresponding grammar rules
> you're using)?

Not directly, no, because C-M-f doesn't call (smie-backward-sexp
keyword), it calls (smie-backward-sexp 'halfsexp), which gives different
behavior.

Which is why I wrote the attached example_grammars.el. It contains
several simple grammars all implementing the same if statement, and
defines movement functions that call smie-backward-sexp with each of the
three possible options, and keys to invoke those functions. See the
comments there for the details. Playing with that was quite educational!

grammar-1a (which is a superset of grammar-1, and also implements the
select statement), is my prefered grammar for Ada mode for these two
statements, and is closest to the current modula-2 grammar.

-- 
-- Stephe

Attachment: example_grammars.el
Description: application/emacs-lisp


reply via email to

[Prev in Thread] Current Thread [Next in Thread]