24

I've spent many, many hours now trying to get any sort of SMIE indentation rule/grammar/thing working.

Are there any examples of a small, toy or skeleton SMIE-based mode with documentation on how it actually works, or any discussion anywhere about how to use it? Something that, say, defines an expression as a string of tokens ending in semi-colon and a block as some expressions between brackets and nothing else. Really, really simple?

Specific questions: when using smie-config-show-indent 90% of the time I get the response ':list-intro "" -> nil'. What is list-intro basing its definition of an expression or a list of expressions on? Why does it say nil and still indent the following lines? How do I change it?

Secondly: is there any relationship between my grammar and my smie-rules? I assume there is because they are both passed into smie-setup, but I can't find any way of saying, "when you see a 'block', indent the contents", for example, based on a grammar that identifies a block.

Thirdly, SMIE seems to have lots of rules "baked in". Just kicking it off gives a general handling of brackets, braces, and parenthesis for instance. Is there any way of seeing these rules or modifying them? Or is it that the syntax table is doing all this and SMIE is literally doing nothing at all (which I'm starting to suspect).

Finally, when trying to debug SMIE I try to do an "edit, eval mode buffer, go to example code in other buffer, M-X <my mode>, test" cycle but it seems that each trip around does not clear out the rules from the previous cycle. How can I be sure that define-derived-mode starts from a clean sheet? I have (kill-all-local-variables) in there but it doesn't seem to be enough and I end up having to close emacs.

I'm not posting any examples of what I have because I have nothing that even vaguely works, aside from highlighting (using font-lock-defaults, so it's not even really SMIE I guess). I need some real baby steps.

10
  • 1
    Try asking the SMIE author for documentation?
    – Drew
    Commented Feb 12, 2016 at 22:55
  • 5
    @drew He has publicly stated that he is not a good documenter (and having read his documentation I can't argue), so it seems pointless.
    – Nagora
    Commented Feb 12, 2016 at 23:03
  • 1
    Yes, I know. He has even said that code should suffice as doc. Oh, did I forget to put a ";-)" after my suggestion? ;-)
    – Drew
    Commented Feb 12, 2016 at 23:05
  • 1
    I had a look at this a while back and noticed that lisp/progmodes/sh-script.el seem to use smie.el rather extensively. They also seem to document their use of it so perhaps that may be a somewhat better example?
    – Xaldew
    Commented Mar 15, 2016 at 12:10
  • 2
    SML mode and Modula2 mode both use SMIE. IIRC SMIE was extracted from SML mode originally. I must admit, I have also found this particularly difficult.
    – ocodo
    Commented Jun 17, 2016 at 3:48

3 Answers 3

2

As was already mentioned in a comment, the canonical documentation for SMIE is found in the Elisp reference manual at Info node (info "(elisp) SMIE"). It contains a small number of toy examples inline with features as they are introduced.

Since then, its author has also published a tutorial article on the topic, SMIE: Weakness is Power! which you can find at https://programming-journal.org/2021/5/1/. Table 1 on page 20 lists several known indenters based on SMIE which you might take inspiration from.

1

A mode which heavily uses SMIE is https://github.com/elixir-lang/emacs-elixir Not sure if it really works though - see the list of indent-related bugs.

1

You could start with something like

(defconst foo-smie-grammar
    (smie-prec2->grammar
     (smie-bnf->prec2
      '((exp ("begin" insts "end"))
        (insts (exp) (insts ";" insts))))))

  ...
  (smie-setup foo-smie-grammar #'ignore)
  ...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.