23

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.

Nagora
  • 373
  • 1
  • 9
  • 1
    Try asking the SMIE author for documentation? – Drew Feb 12 '16 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 Feb 12 '16 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 Feb 12 '16 at 23:05
  • @Nagora Please file a bug report requesting proper documentation specifying the issues you found with the current documentation. I haven't used SMIE myself, so I cannot comment on the current documentation state. – Kaushal Modi Feb 13 '16 at 12:58
  • Just for completeness, I presume you have looked at the documentation in the elisp manual: https://www.gnu.org/software/emacs/manual/html_node/elisp/SMIE.html – Andrew Swann Feb 19 '16 at 08:05
  • @AndrewSwann. Yes. I actually have a printed copy so I've been over it in some detail. I have managed now to get a very limited indentation working but without any reference to the grammar rules. It's this linkage between the grammar and the tokens passed to the rules that is the major missing piece, I think. Everything's just hanging of very simple syntax rules. – Nagora Feb 19 '16 at 10:14
  • 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 Mar 15 '16 at 12:10
  • @Xaldew Thanks for that; I'll have a look. – Nagora Mar 16 '16 at 09:06
  • 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 Jun 17 '16 at 03:48
  • 1
    I think the question is too broad as stated. I believe some of the subquestions could get an answer if they were split though. – YoungFrog Jun 23 '17 at 05:15

3 Answers3

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.

Basil
  • 12,019
  • 43
  • 69
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.

Andreas Röhler
  • 1,894
  • 10
  • 10
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)
  ...
Stefan
  • 26,154
  • 3
  • 46
  • 84