Subject: Re: bug#21526: 24.5; prolog-mode: broken indentation for if-then-else construct

From: Markus Triska <[email-masked]>
Date: Wed, 21 Oct 2015 01:47:22 +0200

Stefan Monnier <[email-masked]> writes:

> But indeed, in the present case it's worse because the comment actually
> does contain a complete "sexp", it's just that with infix operators, we
> have to find the "previous" in order to decide that we've seen the
> end.

Another regression, which may also be affected by how the mode currently
finds the end of terms, also affects indentation outside comments. When
writing Prolog code, situations like the following are common: Suppose I
am in the middle of defining a predicate, with point at "HERE":

   serious_predicate :-
           goal_1,
           goal_2,
           something_complicated,
           HERE

at this point, we decide that we better define something_complicated/0
right now, before even bothering with the rest of the clause at hand.

So we leave the current rule unfinished and instead add:

   serious_predicate :-
           goal_1,
           goal_2,
           something_complicated,

   something_complicated :-HERE

When we now press RET, we get:

   serious_predicate :-
           goal_1,
           goal_2,
           something_complicated,

           something_complicated :-
                   HERE

That's OK, and Stefan Bruda's mode does that too.

But now the point: We now need a way to tell the mode to not bother (for
now) with anything prior to the new rule at hand. I.e., we now want to
focus on the definition of something_complicated/0, and need a way to
tell the mode to not bother with the still incomplete definition of
serious_predicate/0.

In Stefan Bruda's mode, there is a straight-forward and intuitive way to
do this at this point:

   C-p C-a M-\ C-n TAB

which gives us, with Stefan Bruda's original mode:

   serious_predicate :-
           goal_1,
           goal_2,
           something_complicated,

   something_complicated :-
           HERE

and we are ready to complete the definition of something_complicated/0.
Indentation will work as expected at this point, not taking into account
the prior, intentionally still unfinished clause of serious_predicate/0:

   serious_predicate :-
           goal_1,
           goal_2,
           something_complicated,

   something_complicated :-
           goal_3,
           goal_4.

In contrast, we get with the current git version, as a result of the
above key sequence in the exact same situation:

   serious_predicate :-
           goal_1,
           goal_2,
           something_complicated,

   something_complicated :-
                   HERE

which is indenting too far in this specific situation. Moreover, when we
now insert the exact same goals, we get:

   serious_predicate :-
           goal_1,
           goal_2,
           something_complicated,

   something_complicated :-
                   goal_3,
                   goal_4.

>From what I understand, the current git version parses this as if it
meant:

   serious_predicate :-
           goal_1,
           goal_2,
           something_complicated,
           something_complicated :-
                   goal_3,
                   goal_4.

But this is not valid Prolog syntax, because:

   ?- current_op(X, Y, (:-)).
   X = 1200,
   Y = fx ;
   X = 1200,
   Y = xfx.

This means that any arguments of the infix operator (:-)/2 must be of
*smaller precedence* than (:-)/2 itself (i.e., 1200).

Therefore, the above program is not syntactically valid, and it should
be treated for what it actually is: Two independent rules, with one of
them still unfinished, and only the second one mattering for indentation
in this situation, which previously also worked exactly this way.

If possible, please also take this situation into account.

Thank you and all the best,
Markus