#27705·neovim

Treesitter query parser incorrectly parses predicate with many strings

Author: lucario387Created Mar 2, 2024Updated Sep 30, 2026
Labelsneeds:responsetreesitter

Problem

Having a predicate with enough strings breaks the tree. This doesn't happen with https://github.com/tree-sitter-grammars/tree-sitter-query so I believe the problem lies here.

Steps to reproduce

nvim --clean :edit "foo.scm"

  • foo.scm:
query
; Builtin functions
(function_call
  function: (identifier) @function.builtin
  (#any-of? @function.builtin
    "and" "or" "not" "eq" "ne" "lt" "le" "gt" "ge" "default" "required" "empty" "fail" "coalesce"
    "ternary" "print" "println" "printf" "trim" "trimAll" "trimPrefix" "trimSuffix" "lower" "upper"
    "title" "untitle" "repeat" "substr" "nospace" "trunc" "abbrev" "abbrevboth" "initials"
    "randAlphaNum" "randAlpha" "randNumeric" "randAscii" "wrap" "wrapWith" "contains" "hasPrefix"
    "hasSuffix" "quote" "squote" "cat" "indent" "nindent" "replace" "plural" "snakecase" "camelcase"
    "kebabcase" "swapcase" "shuffle" "toStrings" "toDecimal" "toJson" "mustToJson" "toPrettyJson"
    "mustToPrettyJson" "toRawJson" "mustToRawJson" "fromYaml" "fromJson" "fromJsonArray"
    "fromYamlArray" "toYaml" "regexMatch" "mustRegexMatch" "regexFindAll" "mustRegexFinDall"
    "regexFind" "mustRegexFind" "regexReplaceAll" "mustRegexReplaceAll" "regexReplaceAllLiteral"
    "mustRegexReplaceAllLiteral" "regexSplit" "mustRegexSplit" "sha1sum" "sha256sum" "adler32sum"
    "htpasswd" "derivePassword" "genPrivateKey" "buildCustomCert" "genCA" "genSelfSignedCert"
    "genSignedCert" "encryptAES" "decryptAES" "now" "ago" "date" "dateInZone" "duration"
    "durationRound" "unixEpoch" "dateModify" "mustDateModify" "htmlDate" "htmlDateInZone" "toDate"
    "mustToDate" "dict" "get" "set" "unset" "hasKey" "pluck" "dig" "merge" "mustMerge"
    "mergeOverwrite" "mustMergeOverwrite" "keys" "pick" "omit" "values" "deepCopy" "mustDeepCopy"
    "b64enc" "b64dec" "b32enc" "b32dec" "list" "first" "mustFirst" "rest" "mustRest" "last"
    "mustLast" "initial" "mustInitial" "append" "mustAppend" "prepend" "mustPrepend" "concat"
    "reverse" "mustReverse" "uniq" "mustUniq" "without" "mustWithout" "has" "mustHas" "compact"
    "mustCompact" "index" "slice" "mustSlice" "until" "untilStep" "seq" "add" "add1" "sub" "div"
    "mod" "mul" "max" "min" "len" "addf" "add1f" "subf" "divf" "mulf" "maxf" "minf" "floor" "ceil"
    "round" "getHostByName" "base" "dir" "clean" "ext" "isAbs" "kindOf" "kindIs" "typeOf" "typeIs"
    "typeIsLike" "deepequal" "semver" "semverCompare" "urlParse" "urlJoin" "urlquery" "lookup"
    "include")
  )
  • :InspectTree

Expected behavior

I expect the tree to be

scheme
(program [1, 0] - [29, 0]
  (comment [1, 0] - [1, 19])
  (named_node [2, 0] - [28, 3]
    name: (identifier [2, 1] - [2, 14])
    (field_definition [3, 2] - [3, 42]
      name: (identifier [3, 2] - [3, 10])
      (named_node [3, 12] - [3, 42]
        name: (identifier [3, 13] - [3, 23])
        (capture [3, 25] - [3, 42]
          name: (identifier [3, 26] - [3, 42]))))
    (predicate [4, 2] - [27, 14]
      name: (identifier [4, 4] - [4, 10])
      type: (predicate_type [4, 10] - [4, 11])
      parameters: (parameters [4, 12] - [27, 13]
        (capture [4, 12] - [4, 29]
          name: (identifier [4, 13] - [4, 29]))
        (string [5, 4] - [5, 9])
        ; bunch of strings here
        (string [27, 4] - [27, 13])))))

Instead, with Neovim, the result is

scheme
(program ; [0, 0] - [28, 0]
  (comment) ; [0, 0] - [0, 19]
  (list ; [1, 0] - [27, 3]
    (symbol) ; [1, 1] - [1, 14]
    (symbol) ; [2, 2] - [2, 11]
    (list ; [2, 12] - [2, 24]
      (symbol)) ; [2, 13] - [2, 23]
    (symbol) ; [2, 25] - [2, 42]
    (list ; [3, 2] - [26, 14]
      (ERROR) ; [3, 3] - [3, 11]
      (symbol) ; [3, 12] - [3, 29]
      (string) ; [4, 4] - [4, 9]
      ; bunch of strings
      (string)))) ; [26, 4] - [26, 13]

Neovim version (nvim -v)

0.10.0 commit 0d553c83474b8d024d74e9f66b77dc62380241ef

Vim (not Nvim) behaves the same?

No

Operating system/version

Linux 6.7.6

Terminal name/version

kitty 0.32.2

$TERM environment variable

xterm-kitty

Installation

build from source