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:
; 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
(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
(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
Source: neovim/neovim