{"_id":"@dekobon/tree-sitter-groovy","_rev":"4-12ba8421fa6b201b56a4d35abc36b40d","name":"@dekobon/tree-sitter-groovy","dist-tags":{"latest":"0.3.0"},"versions":{"0.2.0":{"name":"@dekobon/tree-sitter-groovy","version":"0.2.0","keywords":["tree-sitter","parser","lexer","groovy","jenkins","gradle","spock","incremental","parsing"],"author":{"name":"Elijah Zupancic","email":"elijah@zupancic.name"},"license":"Apache-2.0 OR MIT","_id":"@dekobon/tree-sitter-groovy@0.2.0","maintainers":[{"name":"ez24","email":"elijah@zupancic.name"}],"homepage":"https://github.com/dekobon/tree-sitter-groovy","bugs":{"url":"https://github.com/dekobon/tree-sitter-groovy/issues"},"dist":{"shasum":"57b5e25d8408be406f5f21a38932fe6d76abb1e4","tarball":"https://registry.npmjs.org/@dekobon/tree-sitter-groovy/-/tree-sitter-groovy-0.2.0.tgz","fileCount":27,"integrity":"sha512-YEnLlU22WRt1fyH6k91REtGuffLvSIkRh3JpTAUEVYAA7yFOsUFKB1VECOqlG0HOMd7rQ+Td9Ik5VgJ5cT/1Og==","signatures":[{"sig":"MEQCIENfyTy9V0XbOYGNJ5DrNjx0c8Sg2hTnmphC/ZcYtJqmAiBzsix0NVrUcjsYq0XzRp1G/4b6K6IKwJuFnES3+nn78Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":8857479},"main":"bindings/node","types":"bindings/node","engines":{"node":">=20"},"gitHead":"05ba5384034d1a45240b6babc0d8bd5ef60214c9","scripts":{"lint":"eslint .","test":"node --test bindings/node/*_test.js","start":"tree-sitter playground","install":"node-gyp-build","prestart":"tree-sitter build --wasm","prebuildify":"prebuildify --napi --strip"},"_npmUser":{"name":"ez24","email":"elijah@zupancic.name"},"repository":{"url":"git+https://github.com/dekobon/tree-sitter-groovy.git","type":"git"},"_npmVersion":"11.12.1","description":"Apache Groovy grammar for tree-sitter (dekobon fork)","directories":{},"tree-sitter":[{"scope":"source.groovy","file-types":["groovy","gradle","gvy","gy","jenkinsfile"],"injection-regex":"^groovy$"}],"_nodeVersion":"25.9.0","dependencies":{"node-addon-api":"^8.7.0","node-gyp-build":"^4.8.4"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.39.4","prebuildify":"^6.0.1","tree-sitter-cli":"^0.25.10","eslint-config-treesitter":"^1.0.2"},"peerDependencies":{"tree-sitter":"^0.25.0"},"peerDependenciesMeta":{"tree-sitter":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/tree-sitter-groovy_0.2.0_1779567760177_0.8543670119061417","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@dekobon/tree-sitter-groovy","version":"0.2.1","keywords":["tree-sitter","parser","lexer","groovy","jenkins","gradle","spock","incremental","parsing"],"author":{"name":"Elijah Zupancic","email":"elijah@zupancic.name"},"license":"Apache-2.0 OR MIT","_id":"@dekobon/tree-sitter-groovy@0.2.1","maintainers":[{"name":"ez24","email":"elijah@zupancic.name"}],"homepage":"https://github.com/dekobon/tree-sitter-groovy","bugs":{"url":"https://github.com/dekobon/tree-sitter-groovy/issues"},"dist":{"shasum":"059a02e20dc5c1347109c8beed623fd741dcb123","tarball":"https://registry.npmjs.org/@dekobon/tree-sitter-groovy/-/tree-sitter-groovy-0.2.1.tgz","fileCount":27,"integrity":"sha512-rtdxp6WobPvXDaAXMqwV7dj93TUK8H42JLrk15MJzjhA3W++8ZnYKXMBFkvhyt7KmXq57VSSCgbHJE6mEvoesg==","signatures":[{"sig":"MEUCIFwaQHL8WudUvLV8uGL790OUVYbFfhDjML8kLMpXWuCrAiEA4qvDclJFHPrrdtDfTWrfAMtKtYgUuPCgNSYgKPUhi5c=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@dekobon%2ftree-sitter-groovy@0.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":8860307},"main":"bindings/node","types":"bindings/node","engines":{"node":">=20"},"gitHead":"3e1d97cbf1b162ff0e9e61484ca0358f72911acc","scripts":{"lint":"eslint .","test":"node --test bindings/node/*_test.js","start":"tree-sitter playground","install":"node-gyp-build","prestart":"tree-sitter build --wasm","prebuildify":"prebuildify --napi --strip"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7c7966cd-27f9-4458-9137-d7325f7c2afb"}},"repository":{"url":"git+https://github.com/dekobon/tree-sitter-groovy.git","type":"git"},"_npmVersion":"11.12.1","description":"Apache Groovy grammar for tree-sitter (dekobon fork)","directories":{},"tree-sitter":[{"scope":"source.groovy","file-types":["groovy","gradle","gvy","gy","jenkinsfile"],"injection-regex":"^groovy$"}],"_nodeVersion":"24.15.0","dependencies":{"node-addon-api":"^8.7.0","node-gyp-build":"^4.8.4"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.39.4","prebuildify":"^6.0.1","tree-sitter-cli":"^0.26.9","eslint-config-treesitter":"^1.0.2"},"peerDependencies":{"tree-sitter":"^0.25.0"},"peerDependenciesMeta":{"tree-sitter":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/tree-sitter-groovy_0.2.1_1779681229713_0.12662514158472749","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@dekobon/tree-sitter-groovy","version":"0.2.2","keywords":["tree-sitter","parser","lexer","groovy","jenkins","gradle","spock","incremental","parsing"],"author":{"name":"Elijah Zupancic","email":"elijah@zupancic.name"},"license":"Apache-2.0 OR MIT","_id":"@dekobon/tree-sitter-groovy@0.2.2","maintainers":[{"name":"ez24","email":"elijah@zupancic.name"}],"homepage":"https://github.com/dekobon/tree-sitter-groovy","bugs":{"url":"https://github.com/dekobon/tree-sitter-groovy/issues"},"dist":{"shasum":"160748eca228d3f8627cf26f3fa8f6a71ec6df4b","tarball":"https://registry.npmjs.org/@dekobon/tree-sitter-groovy/-/tree-sitter-groovy-0.2.2.tgz","fileCount":27,"integrity":"sha512-849xRvERL3ac7KAqUVgwHWcCA2JGSgRpnEVo1lxr7cnyZCqVAl3k9WDQ8i1Jsk9H6AwtrfpzOoK/mCfYXnl7Ew==","signatures":[{"sig":"MEUCIAnkaZmR2O2flt6ecElaB7lLj03hjdpI3s3fj9Ci6GB4AiEA+sPFezCULGngGrON3wytgR7N/Td+PXHonK58MruvJZs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@dekobon%2ftree-sitter-groovy@0.2.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":9368893},"main":"bindings/node","types":"bindings/node","engines":{"node":">=20"},"gitHead":"8c70dc650be128673efd6f53bdc0ffba3ba4ce7d","scripts":{"lint":"eslint .","test":"node --test bindings/node/*_test.js","start":"tree-sitter playground","install":"node-gyp-build","prestart":"tree-sitter build --wasm","prebuildify":"prebuildify --napi --strip"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7c7966cd-27f9-4458-9137-d7325f7c2afb"}},"repository":{"url":"git+https://github.com/dekobon/tree-sitter-groovy.git","type":"git"},"_npmVersion":"11.13.0","description":"Apache Groovy grammar for tree-sitter (dekobon fork)","directories":{},"tree-sitter":[{"scope":"source.groovy","file-types":["groovy","gradle","gvy","gy","jenkinsfile"],"injection-regex":"^groovy$"}],"_nodeVersion":"24.16.0","dependencies":{"node-addon-api":"^8.7.0","node-gyp-build":"^4.8.4"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.39.4","prebuildify":"^6.0.1","tree-sitter-cli":"^0.26.9","eslint-config-treesitter":"^1.0.2"},"peerDependencies":{"tree-sitter":"^0.25.0"},"peerDependenciesMeta":{"tree-sitter":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/tree-sitter-groovy_0.2.2_1780593044735_0.6411418083171847","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@dekobon/tree-sitter-groovy","version":"0.3.0","description":"Apache Groovy grammar for tree-sitter (dekobon fork)","main":"bindings/node","types":"bindings/node","keywords":["tree-sitter","parser","lexer","groovy","jenkins","gradle","spock","incremental","parsing"],"homepage":"https://github.com/dekobon/tree-sitter-groovy","bugs":{"url":"https://github.com/dekobon/tree-sitter-groovy/issues"},"repository":{"type":"git","url":"git+https://github.com/dekobon/tree-sitter-groovy.git"},"scripts":{"install":"node-gyp-build","prestart":"tree-sitter build --wasm","start":"tree-sitter playground","test":"node --test bindings/node/*_test.js","lint":"eslint .","prebuildify":"prebuildify --napi --strip"},"author":{"name":"Elijah Zupancic","email":"elijah@zupancic.name"},"license":"Apache-2.0 OR MIT","publishConfig":{"access":"public"},"engines":{"node":">=20"},"dependencies":{"node-addon-api":"^8.7.0","node-gyp-build":"^4.8.4"},"peerDependencies":{"tree-sitter":"^0.25.0"},"peerDependenciesMeta":{"tree-sitter":{"optional":true}},"devDependencies":{"eslint":"^9.39.4","eslint-config-treesitter":"^1.0.2","prebuildify":"^6.0.1","tree-sitter-cli":"^0.26.13"},"tree-sitter":[{"scope":"source.groovy","injection-regex":"^groovy$","file-types":["groovy","gradle","gvy","gy","jenkinsfile"]}],"gitHead":"654e4c2d736571dbc512043a1dc26017c7aedc85","_id":"@dekobon/tree-sitter-groovy@0.3.0","_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-TpuQiLHwnV0JVcj25pq35WxqsJJDx7/j+5Pgq1/0lPGDLKh8TWuFw3xsmMyY6ujNICmPE8TnVEQStAoxovnheA==","shasum":"83ee5c9c84c7cb6ebc7b02db3e2b4c0d688bbe82","tarball":"https://registry.npmjs.org/@dekobon/tree-sitter-groovy/-/tree-sitter-groovy-0.3.0.tgz","fileCount":27,"unpackedSize":9369590,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@dekobon%2ftree-sitter-groovy@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCIimSh/oFQaZvoxFvysyF6+r5rOLupnIevtBlD2tiyhwIhAPBqCXafeoXVh4HUGFPIW+s/NfDQHZZJwkmx59X+Ccr4"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7c7966cd-27f9-4458-9137-d7325f7c2afb"}},"directories":{},"maintainers":[{"name":"ez24","email":"elijah@zupancic.name"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/tree-sitter-groovy_0.3.0_1788115844262_0.3563870862271048"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-23T20:22:40.074Z","modified":"2026-08-30T18:50:44.781Z","0.2.0":"2026-05-23T20:22:40.515Z","0.2.1":"2026-05-25T03:53:49.939Z","0.2.2":"2026-06-04T17:10:44.937Z","0.3.0":"2026-08-30T18:50:44.463Z"},"bugs":{"url":"https://github.com/dekobon/tree-sitter-groovy/issues"},"author":{"name":"Elijah Zupancic","email":"elijah@zupancic.name"},"license":"Apache-2.0 OR MIT","homepage":"https://github.com/dekobon/tree-sitter-groovy","keywords":["tree-sitter","parser","lexer","groovy","jenkins","gradle","spock","incremental","parsing"],"repository":{"type":"git","url":"git+https://github.com/dekobon/tree-sitter-groovy.git"},"description":"Apache Groovy grammar for tree-sitter (dekobon fork)","maintainers":[{"name":"ez24","email":"elijah@zupancic.name"}],"readme":"# tree-sitter-groovy\n\n[![CI](https://github.com/dekobon/tree-sitter-groovy/actions/workflows/ci.yml/badge.svg)](https://github.com/dekobon/tree-sitter-groovy/actions/workflows/ci.yml)\n[![CodeQL](https://github.com/dekobon/tree-sitter-groovy/actions/workflows/codeql.yml/badge.svg)](https://github.com/dekobon/tree-sitter-groovy/actions/workflows/codeql.yml)\n[![npm](https://img.shields.io/npm/v/@dekobon/tree-sitter-groovy)](https://www.npmjs.com/package/@dekobon/tree-sitter-groovy)\n[![crates.io](https://img.shields.io/crates/v/dekobon-tree-sitter-groovy)](https://crates.io/crates/dekobon-tree-sitter-groovy)\n[![PyPI](https://img.shields.io/pypi/v/dekobon-tree-sitter-groovy)](https://pypi.org/project/dekobon-tree-sitter-groovy/)\n\nTree-sitter grammar for [Apache Groovy](https://groovy-lang.org/) —\nthe JVM scripting language used in Jenkins pipelines, Gradle build\nfiles, and Spock test specifications.\n\n**Published as**: `@dekobon/tree-sitter-groovy` on npm,\n`dekobon-tree-sitter-groovy` on crates.io and PyPI,\n`github.com/dekobon/tree-sitter-groovy` as a Go module / Swift package.\nThe unscoped name belongs to the upstream comparison grammar linked\nbelow; the C library (no naming conflict) still ships as\n`libtree-sitter-groovy`.\n\nThis grammar is **purpose-built** for Groovy (it does not extend the\n`tree-sitter-java` grammar). It synthesises the best ideas from the\ntwo existing community grammars while closing every operator and\nstatement gap they left open:\n\n- [`amaanq/tree-sitter-groovy`](https://github.com/amaanq/tree-sitter-groovy)\n  — clean precedence table and shebang handling, but mis-shapes\n  Groovy-specific syntax (Elvis `?:`, safe navigation `?.`, spread\n  operators, regex `=~` / `==~`, traits, exclusive ranges, identity\n  `===` / `!==`, spaceship `<=>`, etc.) as Java-shaped parse trees.\n- [`murtaza64/tree-sitter-groovy`](https://github.com/murtaza64/tree-sitter-groovy)\n  — purpose-built for Groovy, broad operator coverage and slashy\n  strings, but has open bugs around empty block comments, multi-catch,\n  multi-assignment, enums, switch-arrow, and a `pipeline`-at-EOF\n  constraint.\n\nThe full design is in [`SPECIFICATION.md`](SPECIFICATION.md).\n\n## Status\n\nFully functional Groovy 2.x--4.x parser with complete operator\ncoverage, GString interpolation, generics, closures, command chains,\nand six language bindings. See [Known limitations](#known-limitations)\nfor deferred items.\n\n## Operator coverage\n\nEvery Groovy operator emits a **distinct named node** so downstream\ntooling can identify each by node kind alone — no `MISSING`-child\ninspection, no tree-shape heuristics. This is the contract that\ncloses\n[`dekobon/big-code-analysis#246`](https://github.com/dekobon/big-code-analysis/issues/246)\n(Elvis short-circuit counting) and\n[`dekobon/big-code-analysis#247`](https://github.com/dekobon/big-code-analysis/issues/247)\n(all Groovy-specific operator gaps).\n\n| Category | Operators |\n|---|---|\n| Arithmetic | `+` `-` `*` `/` `%` `**` `++` `--` |\n| Relational | `<` `<=` `>` `>=` `==` `!=` `<=>` (spaceship) |\n| Identity | `===` `!==` |\n| Regex | `=~` (find) `==~` (match) |\n| Logical | `&&` `\\|\\|` `!` `==>` (implication) |\n| Bitwise | `&` `\\|` `^` `~` `<<` `>>` `>>>` |\n| Conditional | `? :` (ternary) `?:` (Elvis) |\n| Assignment | `=` `+=` `-=` `*=` `/=` `%=` `**=` `<<=` `>>=` `>>>=` `&=` `^=` `\\|=` `?=` (Elvis assign) |\n| Range | `..` `..<` `<..` `<..<` |\n| Member access | `.` `?.` `??.` (safe chain dot) `*.` (spread-dot) `.&` (method pointer) `.@` (direct field) `::` (method reference) |\n| Subscript | `[]` `?[]` (safe index) |\n| Spread | `*args` `*:` (spread-map) |\n| Membership | `in` `!in` `instanceof` `!instanceof` |\n| Coercion | `as` |\n\n## Editor support\n\nTree-sitter queries (`queries/groovy/highlights.scm`,\n`folds.scm`, `indents.scm`, `injections.scm`) are provided for editor\nintegration. Slashy and dollar-slashy string bodies inject as `regex`\nfor nested regex highlighting.\n\nRecognized file extensions: `.groovy`, `.gradle`, `.gvy`, `.gy`, and\n`Jenkinsfile`.\n\n### Filetype detection\n\nThe repo ships `ftdetect/groovy.lua` and `ftplugin/groovy.lua` for\nNeovim. Neovim's built-in filetype detection already maps `*.groovy`,\n`*.gradle`, and the bare filename `Jenkinsfile` to filetype `groovy`;\nthe shipped `ftdetect/groovy.lua` fills the gaps by mapping:\n\n- `*.gvy` and `*.gy` — declared in `tree-sitter.json` but not in\n  Neovim's defaults.\n- `*.jenkinsfile` — uncommon (the canonical name is `Jenkinsfile`) but\n  declared in `tree-sitter.json` and used by some teams as an\n  editor-detection hook.\n- `Jenkinsfile.*` variants (`Jenkinsfile.ci`, `Jenkinsfile.release`,\n  …) — common in repos with multiple pipelines, not handled by\n  Neovim's built-in detection.\n\nThe existing `ftplugin/groovy.lua` then calls `vim.treesitter.start()`.\nHighlighting only renders once the parser binary and\n`queries/groovy/highlights.scm` are registered with `nvim-treesitter`\n(or equivalent) — without that, the `start()` call is a no-op and the\nbuffer falls back to non-treesitter highlighting.\n\nFor files that don't match any of those (e.g. a hand-named\n`build-pipeline` with no extension), opt in with one of:\n\n- **Modeline** at the top of the file:\n  `// vim: set filetype=groovy :`\n- **Per-project autocmd** in `.nvim.lua` (sourced after `:cd` into the\n  project via Neovim's `'exrc'`). Note `vim.fn.getcwd()` is evaluated\n  when the autocmd is *defined*, so this snippet belongs in a\n  per-project config, not a global `init.lua`:\n\n  ```lua\n  vim.api.nvim_create_autocmd({ \"BufRead\", \"BufNewFile\" }, {\n    pattern = vim.fn.getcwd() .. \"/jenkins/*\",\n    callback = function() vim.bo.filetype = \"groovy\" end,\n  })\n  ```\n\nOther editors follow the same pattern: rely on built-in detection for\nthe common extensions and override per-directory or via a header\ncomment for the rest.\n\n## Building\n\n```bash\nnpm install\nmake build\nmake test\n```\n\n## Bindings\n\nAvailable bindings: C, Go, Node.js, Python, Rust, Swift. See\n`bindings/` for binding-specific READMEs and tests.\n\nFor Rust consumers:\n\n```toml\n[dependencies]\ndekobon-tree-sitter-groovy = \"0.1\"\ntree-sitter = \"0.25\"\n```\n\n```rust\nlet mut parser = tree_sitter::Parser::new();\nlet language = dekobon_tree_sitter_groovy::LANGUAGE;\nparser.set_language(&language.into()).expect(\"Error loading Groovy parser\");\nlet tree = parser.parse(source, None).unwrap();\n```\n\n## Known limitations\n\nThese are documented in detail in\n[`docs/divergences-from-spec.md`](docs/divergences-from-spec.md).\n\n- **Groovy 5 contextual keywords** (`val`, `async`, `await`, `defer`)\n  are not yet exposed as keyword tokens. They parse as plain\n  identifiers, matching Groovy 2.x--4.x compiler behavior.\n- **Typed local declarations require an initializer** -- `String x`\n  is ambiguous with `String(x)` (method call). Use `String x = ...`\n  or `def x` instead.\n- **Leading-operator line continuation** -- `a\\n+ b` greedily joins\n  as `a + b` rather than splitting into two statements. Idiomatic\n  Groovy places continuation operators at the end of the previous\n  line.\n\n## Contributing\n\nSee [`CONTRIBUTING.md`](CONTRIBUTING.md) for how to build, test, and\nsubmit changes. [`AGENTS.md`](AGENTS.md) covers project conventions\n(commit messages, versioning, validation gates) and\n[`SPECIFICATION.md`](SPECIFICATION.md) is the authoritative grammar\ndesign document.\n\n## Acknowledgements\n\nWe are grateful for the work done in the [murtaza64/tree-sitter-groovy](https://github.com/murtaza64/tree-sitter-groovy)\nand [amaanq/tree-sitter-groovy](https://github.com/amaanq/tree-sitter-groovy). These projects served as inspiration\nfor some of the approaches in this project\n\n## License\n\nDual-licensed under [Apache License 2.0](LICENSE-APACHE) or\n[MIT](LICENSE-MIT).\n","readmeFilename":"README.md"}