I've tried for a while to create a simple major mode that uses SMIE to perform navigation and indentation, but it seems like even the simple examples that I've found seems to break quite easily.
The mode I'm trying to create consist of semi-colon separated statements and blocks of the construct "AttributeBegin" and "AttributeEnd". E.g.:
test;
AttributeBegin
test;
AttributeBegin
test;
AttributeEnd
AttributeEnd
AttributeBegin
test;
AttributeEnd
test;
# ...
(This also shows how I want it to be indented.)
To this end, I created the following SMIE grammar and SMIE rules:
(defvar smie-sample-grammar
(smie-prec2->grammar
(smie-bnf->prec2
`((insts (inst) (insts ";" insts))
(inst ("AttributeBegin" inst "AttributeEnd")))
'((assoc ";"))))
"Sample BNF grammar for `smie'.")
(defun smie-sample-rules (kind token)
"Perform indentation of KIND on TOKEN using the `smie' engine."
(pcase (list kind token)
(`(:elem basic) smie-sample-indent-offset)
(`(:elem arg) 0)))
This mostly works, but I'm getting some strange behaviors in several cases:
test;
AttributeBegin
test;
AttributeEnd
# (1)
AttributeBegin # <--- Why is this intended?
test;
AttributeEnd
AttributeBegin # (2)
test;
AttributeEnd
test;
For some reason, the block pointed to above is erroneously indented, but for some reason, (2) is not. Additionally, if I add a statement at (1), the following block is correctly indented.
I believe that I've written an incorrect grammar/rule pair, but I don't see what I need to change in order to fix it. Most examples I've seen so far doesn't seem to require special rules for blocks like this, so is there something I'm missing?
For completeness, the entire code I used for testing these things are here.