1

I'm writing an SMIE-based mode for a language that has type definitions that look like this:

type Foo = {
  foo : Int,
  bar : String
}

One problem I'm running into is that type and = are treated as parentheses. For example, if I put the cursor on type in my previous example, it's highlighted as an unmatched parenthesis:

The type keyword highlighted as an unmatched parenthesis.

The = is also treated as a parenthesis, but, oddly, it is matched with the corresponding type keyword:

The = is matched with the type keyword.

How can I tell SMIE not to treat type and = as parentheses?

Here's a pared-down version of the grammar I'm using that exhibits this problem:

(defconst theta-grammar
  (smie-prec2->grammar
   (smie-bnf->prec2
    '((id)

      (statement ("type" id "=" type-definition))

      (type-definition (type-definition "|" type-definition)
                       ("{" fields "}"))

      (fields (fields "," fields)
              (id ":" id)))

    '((assoc "|"))
    '((assoc ","))
    '((assoc ":")))))
Tikhon Jelvis
  • 6,152
  • 2
  • 27
  • 40

1 Answers1

1

Not sure why it highlights type as unmatched in the first case. Seems like a bug.

If you don't want your = to match type then you're expected to set smie-blink-matching-inners to nil in your ~/.emacs. This said, I'm not completely sure if paren-mode obeys it. If not, that'd be a bug.

Finally, you can also change your grammar to:

...
(statement ("type" typedef))
(typedef (id "=" type-definition))
...

tho this will prevent your users from enabling this feature when they like it.

Stefan
  • 26,154
  • 3
  • 46
  • 84
  • Thanks! Changing the grammar fixed the matching problem, but it then messed up my indentation rules :P. That's entirely SMIE's fault—seemingly trivial changes to the grammar significantly change its behavior in practice. – Tikhon Jelvis Sep 01 '19 at 03:34
  • 1
    Indeed: the indentation rules basically work from the abstract syntax tree automatically derived from the grammar, so changes to the grammar change the AST which in turn change the indentation behavior, even when the changes to the grammar don't really change the language it describes. It's not easy to make the system robust against such changes. This said, it might be worth keeping track of concrete cases where such changes occurred and how they break indentation, so maybe `smie.el` can be refined to try and avoid some of the more common problems. – Stefan Sep 02 '19 at 14:39