yorickpeterse / nvim-tree-pairs

NeoVim plugin for jumping to the other end of the current Tree-sitter node
Mozilla Public License 2.0
75 stars 0 forks source link

For certain nodes/languages, pairs aren't part of a single node so jumping doesn't work reliably #1

Open yorickpeterse opened 1 week ago

yorickpeterse commented 1 week ago

An example of this is JavaScript:

for (const path of paths) { 
  if (filepath === path) { return path; } 
} 

Here the ( and ) in for are separate literal nodes, so % can't jump between them:

(program ; [0, 0] - [3, 0]
  (for_in_statement ; [0, 0] - [2, 1]
    "for" ; [0, 0] - [0, 3]
    "(" ; [0, 4] - [0, 5]
    "const" ; [0, 5] - [0, 10]
    left: (identifier) ; [0, 11] - [0, 15]
    "of" ; [0, 16] - [0, 18]
    right: (identifier) ; [0, 19] - [0, 24]
    ")" ; [0, 24] - [0, 25]
    body: (statement_block ; [0, 26] - [2, 1]
      "{" ; [0, 26] - [0, 27]
      (if_statement ; [1, 2] - [1, 41]
        "if" ; [1, 2] - [1, 4]
        condition: (parenthesized_expression ; [1, 5] - [1, 24]
          "(" ; [1, 5] - [1, 6]
          (binary_expression ; [1, 6] - [1, 23]
            left: (identifier) ; [1, 6] - [1, 14]
            "===" ; [1, 15] - [1, 18]
            right: (identifier)) ; [1, 19] - [1, 23]
          ")") ; [1, 23] - [1, 24]
        consequence: (statement_block ; [1, 25] - [1, 41]
          "{" ; [1, 25] - [1, 26]
          (return_statement ; [1, 27] - [1, 39]
            "return" ; [1, 27] - [1, 33]
            (identifier) ; [1, 34] - [1, 38]
            ";") ; [1, 38] - [1, 39]
          "}")) ; [1, 40] - [1, 41]
      "}"))) ; [2, 0] - [2, 1]

Ideally Tree-sitter has a way of finding the next balanced ) given we're on a (, but I'm not sure.

yorickpeterse commented 1 week ago

I looked a bit into using Tree-sitter queries, but it seems this requires a query file for each language, along with some non-trivial matching code. I really don't want to start maintaining hundreds of query files, so hopefully there's a better approach.

yorickpeterse commented 1 week ago

Having played around with a bunch of tree-sitter languages, it seems this particular for case is the only one I can find that exhibits this issue, all other languages I tried wrap anything involving brackets in a proper node, instead of just sticking them as-is in the parent node.

yorickpeterse commented 1 week ago

I've opened https://github.com/tree-sitter/tree-sitter-javascript/issues/315 to see if the parser maintainers are open to wrapping the condition into a dedicated node, such that bracket matching works as expected.