unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* smie-next-sexp vs associative operators
@ 2012-10-14  9:16 Stephen Leake
  2012-10-14 15:54 ` Stefan Monnier
  0 siblings, 1 reply; 19+ messages in thread
From: Stephen Leake @ 2012-10-14  9:16 UTC (permalink / raw)
  To: emacs-devel

I'm having a problem with the way smie-next-sexp handles associative
operators.

The problem comes when I'm trying to indent a line in this statement;

         select
            accept BILLY;
            null;
         or
            accept SILLY;
            null;
         or
            accept LILLY do
               null;
            end LILLY;
         end select;

I'm indenting "accept LILLY". It should be indented relative to
"select". 

(I could put in a special case rule for "or", but I want to use the
general purpose rule, that uses smie-backward-sexp to find the statement
start, and indents relative to that.)

In this case, smie-backward-sexp is called with "or"; 

(smie-backward-sexp "or") 

However, this stops with point on "accept SILLY", not accept.

The reason is this code:

                   ((not (smie--associative-p toklevels))
                    (push toklevels levels))
                   ;; The new operator is associative.  Two cases:
                   ;; - it's really just an associative operator (like + or ;)
                   ;;   in which case we should have stopped right before.
                   ((and lastlevels
                         (smie--associative-p (car lastlevels)))
                    (throw 'return
                           (prog1 (list (or (car toklevels) t) (point) token)
                             (goto-char pos))))
                   ;; - it's an associative operator within a larger construct
                   ;;   (e.g. an "elsif"), so we should just ignore it and keep
                   ;;   looking for the closing element.
                   (t (setq levels lastlevels))))))))

Here `lastlevels' is "or" (the one we started with), and `toklevels' is
the next "or". "or" is associative; the right and left levels are the
same. So (smie--associative-p toklevels) and (smie--associative-p (car
lastlevels)) are both true.

That means the code decides it's like +, and stops, and the higher level
indents relative to "accept", which is wrong.

But this is exactly like the "elsif" case the comments are talking
about, so I think the code is broken. In general, there is no way for
SMIE to distinguish an "associative operator" from an "associative
keyword", because at this level everything is an operator.

So I'd like to add an option `smie-next-sexp-stop-on-associative', that
controls whether this stops or keeps going. That way, the user can
let-bind this appropriately, depending on the circumstances. For Ada,
I'll probably set it to nil always, but maybe not.

Somewhat apropos of this topic; I ended up leaving all of the math
operators out of my Ada SMIE grammar; I don't make indentation decisions
based on them, so they don't need to be in the grammar. So this "or" is
the only associative operator I have.

-- 
-- Stephe



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

end of thread, other threads:[~2012-10-25 21:01 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-14  9:16 smie-next-sexp vs associative operators Stephen Leake
2012-10-14 15:54 ` Stefan Monnier
2012-10-14 18:44   ` Stephen Leake
2012-10-14 21:48     ` Stephen Leake
2012-10-15  1:47     ` Stefan Monnier
2012-10-15 12:09       ` Stephen Leake
2012-10-20  9:15       ` Stephen Leake
2012-10-21 14:58         ` Stephen Leake
2012-10-23 17:37           ` Stefan Monnier
2012-10-23 22:43             ` Stephen Leake
2012-10-24 14:24               ` Stefan Monnier
2012-10-24 23:45                 ` Stephen Leake
2012-10-25  3:01                   ` Stefan Monnier
2012-10-25 19:17                     ` Stephen Leake
2012-10-25 21:01                       ` Stefan Monnier
2012-10-23 18:07         ` Stefan Monnier
2012-10-23 23:14           ` Stephen Leake
2012-10-24 14:44             ` Stefan Monnier
2012-10-25  0:22               ` Stephen Leake

Code repositories for project(s) associated with this public 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).