[Top][All Lists]

[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 18:43:02 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.2 (windows-nt)

Stefan Monnier <address@hidden> writes:

>> I just encountered another case where I need smie-skip-associative t:
>> declare
>>    <declarations>
>> begin
>>    <statements>
>> exception
>>    <exception handlers>
>> end;
>> "exception" is optional.
>> With smie-skip-associative nil, (smie-backward-sexp "exception") stops
>> with point after "begin".  But (smie-backward-sexp "end") stops with
>> point before "declare".
> Starting from where?

Starting with point before the keyword passed to smie-backward-sexp.

>> That's not consistent, so it complicates my code, meaning more time
>> spent testing.
> Can you give me some detail about the complication?

I'd have to add special cases in the code, which means each special case
needs to be tested, and maintained.

In this particular situation, doing 

(goto-char (nth 1 (smie-backward-sexp (smie-default-forward-token)) 

would give consistent behavior for indentation; it would leave point on
the right column to use for indenting the keyword we started at.

That's not a lot of code. But there might be different code required for
the next grammar fragment that encounters this issue. The point is I
should not have to worry about it in the first place; smie-backward-sexp
should not treat associative operators specially, for the language I'm

>> With smie-skip-associative t, (smie-backward-sexp "exception") stops
>> with point before "declare", simplifying the code.
> But such a smie-skip-associative also suffers from inconvenients
> (e.g. it will make you look further back than needed for some
> indentation decisions 

Not _me_, just the CPU. That's ok, that's what CPUs are for! as long as
it takes less than noticable time (which it does, so far, on my
admittedly very fast machine). And it gives that gain only for a very
small set of keywords (two out of 130 for Ada mode); from most of the
keywords in statements, smie-backward-sexp will parse back to the
statement start.

>From my point of view, setting smie-skip-associative t makes things
simpler; (smie-backward-sexp keyword) always goes to the _first_ keyword
in a statement. I don't have to worry about any special cases. That's
the optimization I need to make right now.

> and will prevent your users from jumping from one elseif to the next
> with C-M-f).

True. But that's not very consistent behavior anyway. If I did want to
offer something like that as a feature, it would have to be a keystroke
for "move from any keyword in a statement to the previous/next keyword
of the same statement". C-M-f does _not_ do that, on its own; it usually
jumps all the way to the end of the sexp, it's only for associative
operators that it stops anywhere else. I'd have to write an entirely new
movement function (which I may do; it could be useful for navigating
across largish function bodies). So I don't see that as a significant
gain of smie-skip-associative nil.

Do you have any examples of when smie-skip-associative nil is useful for
actual indentation issues? The comments imply that's why the special
treatment was introduced in the first place.

> My intuition tells me there's a better solution to your particular
> problem (one where you don't have to skip over such associative
> siblings), 

The only _problem_ is the time it takes me to recognize and fix each
case. I agree I could handle the current behavior for each particular
case in some innovative way. And that might even be fun, if there wasn't
so much _else_ to do to get Ada mode 5.0 into useful shape.

> but if you really want to do that, I'd rather do it with a new
> function (ideally written on top of smie-next/backward/forward-sexp)
> than with a configuration variable.

Can you explain a little more about the downside of having this choice
provided as a configuration option? It's not a _user_ option, just a
language programmer option. It doesn't significantly complicate smie!

Providing another function that does almost exactly the same thing as
smie-backward-sexp would be more confusing to language programmers, in
my opinion (what would we call it?
smie-backward-sexp-skip-associative-nil? :). There are lots of functions
in Emacs whose behavior is affected by variables in ways much more
significant than this.

I don't think I can build it on top of smie-backward-sexp, because the
crucial stack information is thrown away. I might be able to factor out
a simpler smie-backward-sexp-basic, and then implement the two behaviors
on top of that. That would be significantly more complex code than the
patch I have now. 

And that would _not_ give the language implementor the same level of
control; there are higher level smie functions that call
smie-backward-sexp, so we'd have to provide two of each of those? 

Since the right value for smie-skip-associative is tied to the language,
it would make sense to incorporate it into the grammar structure in some
way. That might be better than providing it as a separate variable.

-- Stephe

reply via email to

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