I am working on a major mode using treesitter as my parser. It's been pretty intuitive but I ran into an issue. When trying to use multiple languages, you have to specify ranges using nodes in the AST it generates. The set ranges seem to work for syntax-coloring but not indenting correctly as it tries to find an indent rule in the host language.

    (defvar language_a-ts-range-rules
      '(:embed language_b
        :host language_a
        ((method_body (method_body_content) @capture))))

This is how I'm capturing the ranges to use the embedded language parser. And then later I do this:

    (setq-local treesit-range-settings
              (apply #'treesit-range-rules

to apply those rules to my major mode.

My indent rules look like

        (setq-local treesit-simple-indent-rules
         ((parent-is "program") parent 0) ;More rules follow ...
           ;; When indenting in language_b, it tries to find a rule here.
          ((parent-is "command_set") parent 4) ;More rules follow ...

I can't find any real-world examples of a multi-language indent rules list but I extrapolated from the manual so that could be wrong.

I tried flipping the order I create the parsers but this just causes it to recognize language_b when indenting and not language_a. This is strange considering the syntax highlighting works both on the embedded language and host language. For example:

        (define-derived-mode language_a-ts-mode prog-mode "language_a"
      "Major mode for editing 'language_a, powered by tree-sitter"
      (when (and (treesit-ready-p 'language_a) (treesit-ready-p 'language_b))
        (treesit-parser-create 'language_a) ;flipping these two flips which 
         (treesit-parser-create 'language_b);indent rules are recognized

This is more about ELisp and tree-sitter than the specific language. Let me know if I need to provide anymore information.


Your Answer

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