Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Two parsers priority indent on the same file #6124

Open
thomas-hiron opened this issue Feb 18, 2024 · 5 comments
Open

Two parsers priority indent on the same file #6124

thomas-hiron opened this issue Feb 18, 2024 · 5 comments
Labels
bug Something isn't working indent Issues or PRs about indentation queries or module

Comments

@thomas-hiron
Copy link

Describe the bug

I'm working on a twig indent based on https://github.com/gbprod/tree-sitter-twig. Here's the diff: gbprod/tree-sitter-twig@main...thomas-hiron:tree-sitter-twig:indent
Unfortunately, html indent and twig indent are not working together.

I'm testing a simple twig file:

<div class="page-header">
    {% if var is not null %}
        {{ include('view.html.twig') }}
    {% endif %}
</div>

This is the produced AST:

(element) ; [1:1 - 5:6]
 (start_tag) ; [1:1 - 42]
  (tag_name) ; [1:2 - 4]
  (attribute) ; [1:6 - 41]
   (attribute_name) ; [1:6 - 10]
   (quoted_attribute_value) ; [1:12 - 41]
    (attribute_value) ; [1:13 - 40]
 (end_tag) ; [5:1 - 6]
  (tag_name) ; [5:3 - 5]
(content) ; [1:1 - 2:4]
(if_block) ; [2:5 - 4:15]
 (if_statement) ; [2:8 - 30]
  (conditional) ; [2:8 - 9]
  (test_expression) ; [2:11 - 30]
   (variable) ; [2:11 - 18]
   (operator) ; [2:20 - 25]
   (test) ; [2:27 - 30]
 (output_directive) ; [2:34 - 3:60]
  (function_call) ; [3:12 - 57]
   (function_identifier) ; [3:12 - 18]
   (arguments) ; [3:19 - 57]
    (argument) ; [3:20 - 56]
     (argument_value) ; [3:20 - 56]
      (string) ; [3:20 - 56]
 (endif_statement) ; [3:61 - 4:15]
  (conditional) ; [4:8 - 12]
(content) ; [4:16 - 6:0]

The indents.scm file:

[
  (if_block)
] @indent.begin

[
  (endif_statement)
] @indent.dedent @indent.end

If I uninstall tree-sitter-html, the indentation works as expected (twig is indented):

<div class="page-header">
{% if var is not null %}
    {{ include('view.html.twig') }}
{% endif %}
</div>

But with tree-sitter-html and twig, here's the output:

<div class="page-header">
    {% if var is not null %}
    {{ include('view.html.twig') }}
    {% endif %}
</div>

Is there a way to order the parsers with a priorioty? I would like twig to indent after html. Looks like it's the other way around.

I also tried to inherits from html indents but I got the impression that inherits isn't meant for this purpose.

To Reproduce

  1. Add tree-sitter configuration for this twig_indent plugin:
local parser_config = require "nvim-treesitter.parsers".get_parser_configs()
parser_config.twig_indent = {
  install_info = {
    url = "https://github.com/thomas-hiron/tree-sitter-twig",
    files = {"src/parser.c"},
    branch = "indent",
  },
  filetype = "twig",
}
  1. Copy the queries/*.scm into $XDG_CONFIG_HOME/nvim/queries/ or any nvim runtime path.
  2. Make sure :TSInstall html twig_indent
  3. Try to indent the file

Expected behavior

Output should be:

<div class="page-header">
    {% if var is not null %}
        {{ include('view.html.twig') }}
    {% endif %}
</div>

Output of :checkhealth nvim-treesitter

Installation ~
- OK `tree-sitter` found 0.20.9 (98be227227af10cc7a269cb3ffb23686c0610b17) (parser generator, only needed for :TSInstallFromGrammar)
- OK `node` found v20.11.0 (only needed for :TSInstallFromGrammar)
- OK `git` executable found.
- OK `cc` executable found. Selected from { vim.NIL, "cc", "gcc", "clang", "cl", "zig" }
  Version: cc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
- OK Neovim was compiled with tree-sitter runtime ABI version 14 (required >=13). Parsers must be compatible with runtime ABI.

OS Info:
{
  machine = "x86_64",
  release = "6.5.0-18-generic",
  sysname = "Linux",
  version = "#18~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Wed Feb  7 11:40:03 UTC 2"
} ~

Parser/Features         H L F I J
  - c                   ✓ ✓ ✓ ✓ ✓
  - css                 ✓ . ✓ ✓ ✓
  - html                ✓ ✓ ✓ ✓ ✓
  - javascript          ✓ ✓ ✓ ✓ ✓
  - lua                 ✓ ✓ ✓ ✓ ✓
  - make                ✓ . ✓ . ✓
  - php                 ✓ ✓ ✓ ✓ ✓
  - query               ✓ ✓ ✓ ✓ ✓
  - twig_indent         ✓ . . ✓ ✓
  - vim                 ✓ ✓ ✓ . ✓
  - vimdoc              ✓ . . . ✓
  - yaml                ✓ ✓ ✓ ✓ ✓

  Legend: H[ighlight], L[ocals], F[olds], I[ndents], In[j]ections
         +) multiple parsers found, only one will be used
         x) errors found in the query, try to run :TSUpdate {lang} ~

Output of nvim --version

NVIM v0.9.5
Build type: Release
LuaJIT 2.1.1692716794

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "/__w/neovim/neovim/build/nvim.AppDir/usr/share/nvim"

Additional context

No response

@thomas-hiron thomas-hiron added the bug Something isn't working label Feb 18, 2024
@thomas-hiron
Copy link
Author

Ping @gbprod, maybe you could bring some context to this issue. Did you look into indenting already? Did you have some issues? Thanks!

@clason
Copy link
Contributor

clason commented Feb 18, 2024

Having multiple parsers for the same file is not supported. If you have multiple languages, you need to either define a "base language" with injections, or have an "extended" language that inherits from the base language (without injections), as in cpp from c or terraform from hcl (or vice versa).

@lucario387
Copy link
Member

Would need to fix indent to accept the smallest range, instead of the smallest root tree

I don't know how to do that though :). PR Welcome

@thomas-hiron
Copy link
Author

thomas-hiron commented Feb 18, 2024

Oh I see, thanks!
I tried to extends tree-sitter-html but I had too much trouble with externals (scanner.c), and it seems I couldn't add new rules. I felt like I was wasting time.
If it's the correct way to go, I'll give it another shot then.

@clason can I define injections for indents? The upstream plugin is already configured for highlights for example.

Thanks for your help!

EDIT: I didn't understand injections, injections.scm is responsible for incorrect indenting:

((content) @injection.content
 (#set! injection.language "html")
 (#set! injection.combined))

Without this, twig indenting works! How can I apply my indent rules when twig is inside a html block?

@gbprod
Copy link
Contributor

gbprod commented Feb 20, 2024

Ping @gbprod, maybe you could bring some context to this issue. Did you look into indenting already? Did you have some issues? Thanks!

Hi!
I've never tried to make indentation works for twig (mostly because I don't know how to make it works with combined injection).
But it would be awesome to improve this :)
I will make some tests ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working indent Issues or PRs about indentation queries or module
Projects
None yet
Development

No branches or pull requests

4 participants