virchau13 / tree-sitter-astro

Tree-sitter grammar for the Astro web framework
MIT License
98 stars 9 forks source link

Breaks when I add a script tag anywhere #18

Closed Hubro closed 1 year ago

Hubro commented 1 year ago

Example:

---
console.log("This is a test");
---

<html>
  <head>
  </head>
  <body>
    <p>All good</p>
  </body>
</html>

This works great. Here's how it looks in Neovim:

image

However, as soon as I add a script tag anywhere in the document, everything breaks horribly:

image

It doesn't matter where the script tag is or if it's empty.

It seems like the entire document is parsed correctly, but the entire document is also parsed as typescript. If I scroll down the node tree, I scroll through the entire document twice, once parsed as HTML and once parsed as TypeScript.

This breaks syntax highlighting, navigation and some editing features. For example, typing out a tag will no longer auto-close the tag (I'm using an auto-closing plugin for Tree-sitter). Also, % will no longer jump between open and close tags.

Uninstalling the typescript parser fixes the issue:

:TSUninstall typescript

With the obvious drawback that I no longer get syntax highlighting for code blocks and the frontmatter.

virchau13 commented 1 year ago

I can't reproduce this: image

What version of Neovim are you running?

Hubro commented 1 year ago

Neovim v0.9.1 and nvim-treesitter commit 691d732. I also deleted all my parsers and reinstalled them just to make sure I have up-to-date parsers as well (rm ~/.local/share/nvim/lazy/nvim-treesitter/parser/*).

Hubro commented 1 year ago

Come to think of it, it's definitely not an issue with the parser, as evidenced by the fact that the issue only occurs when the typescript parser is installed. I also tried parsing the file using the command line and it works fine:

$ tree-sitter parse test.astro
(fragment [0, 0] - [11, 0]
  (frontmatter [0, 0] - [2, 3]
    (raw_text [1, 0] - [1, 19]))
  (element [4, 0] - [10, 7]
    (start_tag [4, 0] - [4, 6]
      (tag_name [4, 1] - [4, 5]))
    (element [5, 4] - [6, 11]
      (start_tag [5, 4] - [5, 10]
        (tag_name [5, 5] - [5, 9]))
      (end_tag [6, 4] - [6, 11]
        (tag_name [6, 6] - [6, 10])))
    (element [7, 4] - [8, 11]
      (start_tag [7, 4] - [7, 10]
        (tag_name [7, 5] - [7, 9]))
      (end_tag [8, 4] - [8, 11]
        (tag_name [8, 6] - [8, 10])))
    (script_element [9, 4] - [9, 21]
      (start_tag [9, 4] - [9, 12]
        (tag_name [9, 5] - [9, 11]))
      (raw_text [9, 12] - [9, 12])
      (end_tag [9, 12] - [9, 21]
        (tag_name [9, 14] - [9, 20])))
    (end_tag [10, 0] - [10, 7]
      (tag_name [10, 2] - [10, 6]))))

So it's either an issue with the injections query or a bug in Neovim or nvim-treesitter.

I'm very curious why this doesn't happen for you, though. Figuring that out would probably be very helpful.

Hubro commented 1 year ago

@virchau13 Are you perhaps overriding the injections query in your config? Or do you have remnants of them from developing the parser? I see the injections query in the nvim-treesitter differ from the ones in this repo:

https://github.com/nvim-treesitter/nvim-treesitter/blob/master/queries/astro/injections.scm

Perhaps that explains it.

virchau13 commented 1 year ago

The injections query in this repo aren't used at all. I sense this is an issue with your configuration.

Hubro commented 1 year ago

@virchau13 I tried overriding the Astro injections query with the one in this repo, and that fixed the issue. I think the issue is with the injections.scm query in nvim-treesitter.

vim.treesitter.query.set(
  "astro",
  "injections",
  [[
((script_element
  (raw_text) @injection.content)
 (#set! injection.language "javascript"))

((style_element
  (raw_text) @injection.content)
 (#set! injection.language "css"))

((frontmatter
   (raw_text) @injection.content)
 (#set! injection.language "typescript"))

((interpolation
   (raw_text) @injection.content)
 (#set! injection.language "tsx"))
  ]]
)

Are you sure you aren't using these queries? I've accidentally done that before when writing queries for my own tree-sitter parsers.

But if you have any suggestions for how my config can cause the original issue I'm all ears, because I can't think of any :thinking:

virchau13 commented 1 year ago

You may be overriding the queries somehow in your configuration. Do you have any plugins that would do that / have you written any Lua to do that?

Hubro commented 1 year ago

I'm not overriding my Astro queries anywhere. I only started using Astro a couple of weeks ago, so I would remember.

This is my entire nvim-treesitter config file:

require("nvim-next.integrations").treesitter_textobjects()

require("nvim-treesitter.configs").setup({
  sync_install = true,
  auto_install = true,

  highlight = {
    enable = true,
    -- Can also enable/disable for specific languages
    -- enable = { "python" },
    -- disable = { "c", "rust" },

    disable = { "gitcommit" },
  },

  incremental_selection = {
    enable = true,
    keymaps = {
      init_selection = "<A-9>",
      node_incremental = "<A-9>",
      -- scope_incremental = "<C-l>",
      node_decremental = "<A-8>",
    },
  },

  indent = {
    enable = true,

    -- The indent expressions for some languages are complete shit
    disable = { "svelte", "php" },
  },

  autotag = {
    enable = true,
    filetypes = {
      "astro",
      "html",
      "xml",
      "javascript",
      "javascriptreact",
      "typescriptreact",
      "svelte",
      "vue",
    },
  },

  textobjects = {
    select = {
      enable = true,
      lookahead = true,
      include_surrounding_whitespace = false,

      keymaps = {
        ["af"] = "@function.outer",
        ["if"] = "@function.inner",
        ["ac"] = "@comment.outer",
        ["ic"] = "@comment.inner",
        ["ap"] = "@parameter.outer",
        ["ip"] = "@parameter.inner",
      },

      selection_modes = {},
    },

    swap = {
      enable = true,
      swap_next = {
        ["<leader>+"] = "@parameter.inner",
      },
      swap_previous = {
        ["<leader>-"] = "@parameter.inner",
      },
    },
  },

  -- I'm defining all textobject moves through nvim_text, which makes them
  -- repeatable
  nvim_next = {
    enable = true,

    textobjects = {
      move = {
        -- enable = true,
        -- set_jumps = true,
        goto_next_start = {
          ["]f"] = "@function.outer",
        },
        goto_previous_start = {
          ["[f"] = "@function.outer",
        },
      },
    },
  },
})

I guess it's technically possible that some of my nvim-treesitter plugins are overriding the Astro queries?

I'll just try to replicate the issue from a minimal config, I probably should have done that from the start.

Hubro commented 1 year ago

@virchau13 It's not an issue with my config, I reproduced the issue with a minimal config:

https://github.com/Hubro/reproduce-tree-sitter-injections-issue

I guess I'll report this issue on nvim-treesitter, but I'm still curious why this doesn't happen for you. My guess is that you're not actually using the injections query from nvim-treesitter. I don't know what else could be the reason, if you have all the same software versions as I do.

virchau13 commented 1 year ago

Still unable to reproduce: image

Other people seem to be able to get this working so I'm leaning towards it being an issue in your environment.

I'm thinking maybe your cached parsers have issues. Try this with the following minimal configuration?

for name, url in pairs {
  nvim_treesitter = "https://github.com/nvim-treesitter/nvim-treesitter.git"
} do
  local install_path = vim.fn.fnamemodify('plugins/' .. name, ':p')
  if vim.fn.isdirectory(install_path) == 0 then
    vim.fn.system { 'git', 'clone', '--depth=1', url, install_path }
  end
  vim.opt.runtimepath:append(install_path)
end

-- added two lines below:
local parserpath = "/tmp/treesitter-tmpparserpath"
vim.opt.runtimepath:append(parserpath)

require("nvim-treesitter.configs").setup({
  ensure_installed = {
    "astro",
    "typescript",
    "css",
  },
  -- added one line below:
  parser_install_dir = parserpath,

  highlight = {
    enable = true,
  },
})
Hubro commented 1 year ago

@virchau13 Still absolutely explodes for me... What the heck can cause this? :confused:

image

Do you have any clue what in my environment can affect Tree-sitter injections?

Hubro commented 1 year ago

I just tried the Neovim nightly appimage, and that actually solves the issue...

Out of curiosity, are you running nightly? Or are you on a stable release?

virchau13 commented 1 year ago

Yep, I was running nightly. Probably a Neovim bug then.