elixir-lang / tree-sitter-elixir

Elixir grammar for tree-sitter
https://elixir-lang.org/tree-sitter-elixir
Apache License 2.0
245 stars 24 forks source link

Git conflicts #47

Closed fuelen closed 1 year ago

fuelen commented 1 year ago

I don't know how parsers for other languages handle the case, when a file has git conflicts, but Elixir knows about git and if you run the module below, then Elixir reports:

** (SyntaxError) test.exs:5:1: found an unexpected version control marker, please resolve the conflicts: <<<<<<< HEAD:lib/my_module.ex

Example:

defmodule MyModule do
  defstruct [:a, :b, :c]

  @type t :: %__MODULE__{
<<<<<<< HEAD:lib/my_module.ex
      a: binary(),
      b: integer(),
=======
      a: float(),
      b: boolean(),
>>>>>>> 816a01c71 (feat: use new library [JIRA-111]):lib/my_module.ex
      c: boolean
  }
end

And here how it is rendered in neovim image

It would be great if tree sitter knows about git as well and doesn't parse git conflict metadata as regular Elixir terms

the-mikedavis commented 1 year ago

As far as I know, no tree-sitter parsers handle version control markers. I don't think tree-sitter parsers should look for these since they aren't part of the language (the Elixir tokenizer recognizes them but bails if it sees them), the work would be duplicated between any parsers since markers can end up in a source file for any language, and they would be tricky to parse successfully. They would be similar to parsing comments but they could be within multi-line strings.

We might be able to add extras rules for them so they would be recognized but it wouldn't work in all cases (multi-line strings) and they wouldn't be parsed structurally: you wouldn't be able to highlight the deleted changes in red and the added lines in green for example.

It's something we discussed how to support in Helix and the current thinking is that we will solve it manually rather than with tree-sitter. That being said, it might be possible to support this with plain tree-sitter by writing a version control marker parser that injects Elixir or whatever language into the non-marker parts. This would be more expensive and slower though since most of the document would be an injection and it would require combined injections. (Last I looked they were not fully supported in nvim but that may have changed.)

fuelen commented 1 year ago

Thank you for response. Totally agree, it is better to rely on plugins (in case of neovim). I'll close the issue.

patrickt commented 1 year ago

As far as I know, no tree-sitter parsers handle version control markers.

This is correct. You could perhaps jury-rig something, but in general if version control markers are a thing you need to worry about, you probably want a multiple-phase parser.