Our toy major-mode from the previous question now works. However, if we extend
it slightly, e.g., by adding arguments to each instruction that can trail
multiple lines, they are indented as expected in almost all cases:

Only the one instruction marked above is unexpectedly indented (and others that
trail directly after an "AttributeEnd" statement). I tried to use smie-edebug
to debug the indentation of that particular line, but for some reason SMIE
doesn't even refer to the rule-set in that case.

Interestingly, adding a semi-colon after "AttributeEnd" and before the next
statement causes the indentation the line up-correctly.

Is there any particular reason that statement should behave that way and is there
something that can be added to the configuration for this to behave as intended?

3 Answers
3

You can also parse the empty string behind AttributeEnd as ;. Point behind AttributeEnd is the corresponding parser state. The only tricky detail is that you must flee from that position when you have parsed ; in forward direction and you may only parse the arrival at AttributeEnd as ; when you are parsing in backward direction.

The Att..Begin...Att..End is just a (parenthesized) "expression", like test, c, and d because it's not separated from them with any keyword (which is why the same problem doesn't show up when you add a semi-colon between them). So SMIE considers the above as 4 expressions next to each other, just like:

foo
test c
d;

test is taken to be the first arg to "foo" and is aligned with foo because of your rule (`(:elem arg) 0) and then all subsequent args (c and d) are aligned with the first.

That explains it pretty well, but is there anything that can be done for it to work as I intended?
– XaldewJul 29 at 9:20

I faced a similar problem in sml-mode and managed to work around it with an ad-hoc indentation rule, but the way it presents itself here is different and the best I can think of is to change the lexer so that it returns ";" when reading the newline that follows AttributeEnd.
– StefanJul 29 at 13:29

That's indeed what I was suggesting. It's "complex" and hackish, but otherwise there's no "keywords" to which to attach separately the AttributeBegin...AttributeEnd expression and the test c d. It's always possible to deal with it in the smie-rule-function instead, but it tends to be much more messy in the long run.
– StefanJul 29 at 17:37