{"_id":"@codincod/codemirror-lang-jq","_rev":"4-f358f7cf98ab4ec7c1e7ebe5db74202a","name":"@codincod/codemirror-lang-jq","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"@codincod/codemirror-lang-jq","version":"0.1.0","keywords":["codemirror","code","editor","jq","json"],"author":{"name":"CodinCod","email":"hello@codincod.com"},"license":"MIT","_id":"@codincod/codemirror-lang-jq@0.1.0","maintainers":[{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"}],"homepage":"https://codincod.com/","dist":{"shasum":"6eda8becbeaf5ae02bc22455ad72941930f48c93","tarball":"https://registry.npmjs.org/@codincod/codemirror-lang-jq/-/codemirror-lang-jq-0.1.0.tgz","fileCount":12,"integrity":"sha512-AVRocNPzCacZg9p0zgApPDQ5QHoA7qQdTkUYRFyrkrmlaqZG6ysujWW1r4WSjMQxi8OSdPkMXyNZAAX2VWjfPQ==","signatures":[{"sig":"MEQCIFHhEQICl2aECI0oFZIS/iCfQMyspQcYgqCsIVCroOWhAiBe9bVEuqW/dMGdLKN/uMLwqMoDb4OFoaLPaNwYWfbcAQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":90508},"main":"dist/index.cjs","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{"import":"./dist/index.js","require":"./dist/index.cjs"},"gitHead":"3d2c3a62f3d89088843215c1112e362cdb2c6e67","scripts":{"gaps":"npm run build && node ../lezer-survey/src/cli.ts gaps --group top","test":"npm run build && node --test \"test/*.test.ts\"","build":"rm -rf dist && lezer-generator src/jq.grammar -o src/parser.js && cm-buildhelper src/jq.ts","corpus":"npm run build && node ../lezer-survey/src/cli.ts measure --group top","prepare":"npm run build","build-debug":"lezer-generator src/jq.grammar --names -o src/parser.js && cm-buildhelper src/jq.ts"},"_npmUser":{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"},"repository":{"url":"git+https://codeberg.org/reeven/codemirror-lang-jq.git","type":"git"},"_npmVersion":"11.6.2","description":"jq language support for the CodeMirror code editor","directories":{},"sideEffects":false,"_nodeVersion":"25.0.0","dependencies":{"@lezer/lr":"^1.0.0","@lezer/common":"^1.0.0","@lezer/highlight":"^1.0.0","@codemirror/language":"^6.0.0","@codemirror/autocomplete":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@lezer/generator":"^1.7.0","@codemirror/state":"^6.7.1","@codemirror/buildhelper":"^1.0.2"},"_npmOperationalInternal":{"tmp":"tmp/codemirror-lang-jq_0.1.0_1785964470423_0.4689163771748397","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@codincod/codemirror-lang-jq","version":"0.1.1","keywords":["codemirror","code","editor","jq","json"],"author":{"name":"CodinCod","email":"hello@codincod.com"},"license":"MIT","_id":"@codincod/codemirror-lang-jq@0.1.1","maintainers":[{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"}],"homepage":"https://codincod.com/","dist":{"shasum":"5ff3de5b02094a7e30a1eeafc6d14f0428852833","tarball":"https://registry.npmjs.org/@codincod/codemirror-lang-jq/-/codemirror-lang-jq-0.1.1.tgz","fileCount":12,"integrity":"sha512-rKjKmz569Bsqxnj+dXJXsYUqICbvUiw+KesGSCxk7HeA6l/pk2S97YmP8j54CmRt30qB6BHSFT/GTCj4ga67eg==","signatures":[{"sig":"MEUCIDet2+DGVkRx6+Z7MOyHMGFUf2kVKNL8Gx3CECLOMaPWAiEA0f5ABhdhiS6/n5iccGlGEbc7vbhlTtfCQBuViK7X4sU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":90500},"main":"dist/index.cjs","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{"import":"./dist/index.js","require":"./dist/index.cjs"},"gitHead":"3d2c3a62f3d89088843215c1112e362cdb2c6e67","scripts":{"gaps":"npm run build && node ../lezer-survey/src/cli.ts gaps --group top","test":"npm run build && node --test \"test/*.test.ts\"","build":"rm -rf dist && lezer-generator src/jq.grammar -o src/parser.js && cm-buildhelper src/jq.ts","corpus":"npm run build && node ../lezer-survey/src/cli.ts measure --group top","prepare":"npm run build","build-debug":"lezer-generator src/jq.grammar --names -o src/parser.js && cm-buildhelper src/jq.ts"},"_npmUser":{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"},"repository":{"url":"https://codeberg.org/reeven/codemirror-lang-jq","type":"git"},"_npmVersion":"11.6.2","description":"jq language support for the CodeMirror code editor","directories":{},"sideEffects":false,"_nodeVersion":"25.0.0","dependencies":{"@lezer/lr":"^1.0.0","@lezer/common":"^1.0.0","@lezer/highlight":"^1.0.0","@codemirror/language":"^6.0.0","@codemirror/autocomplete":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@lezer/generator":"^1.7.0","@codemirror/state":"^6.7.1","@codemirror/buildhelper":"^1.0.2"},"_npmOperationalInternal":{"tmp":"tmp/codemirror-lang-jq_0.1.1_1785970486783_0.21548599760457932","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@codincod/codemirror-lang-jq","version":"0.2.0","keywords":["codemirror","code","editor","jq","json"],"author":{"name":"CodinCod","email":"hello@codincod.com"},"license":"MIT","_id":"@codincod/codemirror-lang-jq@0.2.0","maintainers":[{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"}],"homepage":"https://codincod.com/","dist":{"shasum":"efb5742d51f9d42108b2c084a139c48d954f2817","tarball":"https://registry.npmjs.org/@codincod/codemirror-lang-jq/-/codemirror-lang-jq-0.2.0.tgz","fileCount":12,"integrity":"sha512-bcNZKYO5GQsaC09eV85dxGBulNWClmHGtkkMBNJCvfsKGrRl9tZgIo5xLyJQPkZZT9QHqOGwYY3ITgHezhE7DA==","signatures":[{"sig":"MEUCIQDvYyF+z9o180A2EQYYDvMyeEcrHVRSxwXU7O2ggDQgUwIgdbqLHJYxfSe6HzoHhwOsAfVIqn7VtYv9U4mKJS5rdhY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":91124},"main":"dist/index.cjs","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{"import":"./dist/index.js","require":"./dist/index.cjs"},"gitHead":"89f07ec5cc2537cfa39b46ed93b5f7a161cc79ef","scripts":{"fuzz":"npm run build && node ../lezer-survey/src/cli.ts fuzz","gaps":"npm run build && node ../lezer-survey/src/cli.ts gaps --group top","test":"npm run build && node --test \"test/*.test.ts\"","build":"rm -rf dist && lezer-generator src/jq.grammar -o src/parser.js && cm-buildhelper src/jq.ts","measure":"npm run build && node ../lezer-survey/src/cli.ts measure --group top","prepare":"npm run build","build-debug":"lezer-generator src/jq.grammar --names -o src/parser.js && cm-buildhelper src/jq.ts"},"_npmUser":{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"},"repository":{"url":"https://codeberg.org/reeven/codemirror-lang-jq","type":"git"},"_npmVersion":"11.6.2","description":"jq language support for the CodeMirror code editor","directories":{},"sideEffects":false,"_nodeVersion":"25.0.0","dependencies":{"@lezer/lr":"^1.0.0","@lezer/highlight":"^1.0.0","@codemirror/language":"^6.0.0","@codemirror/autocomplete":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@lezer/generator":"^1.7.0","@codemirror/state":"^6.7.1","@codemirror/buildhelper":"^1.0.2"},"_npmOperationalInternal":{"tmp":"tmp/codemirror-lang-jq_0.2.0_1786659592558_0.8194892828241322","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@codincod/codemirror-lang-jq","version":"0.3.0","description":"jq language support for the CodeMirror code editor","keywords":["codemirror","code","editor","jq","json"],"author":{"name":"CodinCod","email":"hello@codincod.com"},"license":"MIT","type":"module","main":"dist/index.cjs","exports":{"import":"./dist/index.js","require":"./dist/index.cjs"},"module":"dist/index.js","types":"dist/index.d.ts","sideEffects":false,"scripts":{"build":"rm -rf dist && lezer-generator src/jq.grammar -o src/parser.js && cm-buildhelper src/jq.ts","build-debug":"lezer-generator src/jq.grammar --names -o src/parser.js && cm-buildhelper src/jq.ts","prepare":"npm run build","test":"npm run build && node --test \"test/*.test.ts\"","measure":"npm run build && node ../lezer-survey/src/cli.ts measure --group top","fuzz":"npm run build && node ../lezer-survey/src/cli.ts fuzz","gaps":"npm run build && node ../lezer-survey/src/cli.ts gaps --group top"},"dependencies":{"@codemirror/autocomplete":"^6.0.0","@codemirror/language":"^6.0.0","@lezer/highlight":"^1.0.0","@lezer/lr":"^1.0.0"},"devDependencies":{"@codemirror/buildhelper":"^1.0.2","@codemirror/state":"^6.7.1","@lezer/generator":"^1.7.0","typescript":"^5.6.0"},"homepage":"https://codincod.com/","repository":{"type":"git","url":"https://codeberg.org/reeven/codemirror-lang-jq"},"gitHead":"89f07ec5cc2537cfa39b46ed93b5f7a161cc79ef","_id":"@codincod/codemirror-lang-jq@0.3.0","_nodeVersion":"25.0.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-uJZtPk4m8eUO+EurQ5JYEW4vsxXLLRSHUufxu7gvFOHcV2hvIJ89Z0oMIiPBHOhwVvSD+0CE3DjFMWFq65tuqw==","shasum":"c5da8c879e8a5aae0e581cc91731e3a40c092b75","tarball":"https://registry.npmjs.org/@codincod/codemirror-lang-jq/-/codemirror-lang-jq-0.3.0.tgz","fileCount":12,"unpackedSize":91124,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDzVyf1SpIsdbZRMWiyJyNLQMB/2BlOQqeTdXKSvqZeywIhANXAAqDk0747Hi1NhA5qg2lyZxPiPphcItQruNMFw38L"}]},"_npmUser":{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"},"directories":{},"maintainers":[{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/codemirror-lang-jq_0.3.0_1786759703113_0.7999213139622787"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-05T21:14:30.283Z","modified":"2026-08-15T02:08:23.462Z","0.1.0":"2026-08-05T21:14:30.593Z","0.1.1":"2026-08-05T22:54:46.934Z","0.2.0":"2026-08-13T22:19:52.709Z","0.3.0":"2026-08-15T02:08:23.259Z"},"author":{"name":"CodinCod","email":"hello@codincod.com"},"license":"MIT","homepage":"https://codincod.com/","keywords":["codemirror","code","editor","jq","json"],"repository":{"type":"git","url":"https://codeberg.org/reeven/codemirror-lang-jq"},"description":"jq language support for the CodeMirror code editor","maintainers":[{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"}],"readme":"# @codincod/codemirror-lang-jq\n\nThis package implements [jq](https://jqlang.org/) language support for the\n[CodeMirror](https://codemirror.net/) code editor: a\n[Lezer](https://lezer.codemirror.net/) grammar, highlighting, indentation,\nfolding and completion for the builtins.\n\nThe grammar is written from scratch, following jq's own `src/parser.y`. There\nwas a `codemirror-lang-jq` on npm before this one, and its author says plainly\nthat it looks for keywords, numbers and strings rather than tokenizing for\nvalid syntax. That shows up in the tree it builds: a program is a flat run of\ntokens with brackets grouped, so nothing in it says what a pipeline is, where a\ndefinition ends, or which of two dots is a field.\n\nIt reads the three implementations people write, not only the first. Where\n[gojq](https://github.com/itchyny/gojq), [fq](https://github.com/wader/fq) and\n[jaq](https://github.com/01mf02/jaq) take something jq rejects, this takes it\ntoo, and the four places that happens are listed below.\n\nWritten in part for [CodinCod](https://codincod.com/), a competitive coding\nplatform, where it colours the editor people solve puzzles in.\n\nThis code is released under an\n[MIT license](https://codeberg.org/reeven/codemirror-lang-jq/src/branch/master/LICENSE).\n\n## Usage\n\n```javascript\nimport {EditorView, basicSetup} from \"codemirror\"\nimport {jq} from \"@codincod/codemirror-lang-jq\"\n\nconst view = new EditorView({\n  parent: document.body,\n  doc: `def counts:\n  reduce .[] as $x ({}; .[$x] |= (. // 0) + 1);\n\n.items\n| map(select(.price > 10) | .name)\n| counts\n| to_entries\n| sort_by(-.value)\n| .[]\n| \"\\\\(.key): \\\\(.value)\"\n`,\n  extensions: [basicSetup, jq()]\n})\n```\n\n## What it reads\n\nTwo corpora, and they answer different questions.\n\nThe first is 195 files and 0.37 MiB of jq written by people who write jq: jq's\nown `src/builtin.jq` and test modules, fq's interpreter, gojq's and jaq's\nbuiltins, [JBOL](https://github.com/fadado/JBOL), and\n[jqjq](https://github.com/wader/jqjq), which is jq written in jq. **95.90%** of\nthose files parse with no error node, against **59.49%** for the package this\nreplaces. The average byte is placed 7.80 nodes deep rather than 1.81, across\n87 kinds of node rather than 49; a grammar that agrees with everything sits\nunder two.\n\nThe second is CodinCod's language-guessing pool, 1706 snippets of jq from\nRosetta Code. **88.69%** parse with no error node against **57.15%**, and\n**99.91%** of the text carries a highlighting tag against **59.09%**, over 11\ncolours rather than 8.\n\nThe gap between those two numbers is the pool rather than the grammar, and jq\nitself says so. Compiling all 1706 snippets with jq 1.8.2 and comparing verdicts\nfile by file:\n\n| | Snippets |\n| --- | --: |\n| jq compiles it, this parses it clean | 1511 |\n| jq rejects it, this reports an error | 193 |\n| jq rejects it, this parses it clean | 2 |\n| **jq compiles it, this reports an error** | **0** |\n\nThere is no jq program in either corpus that jq accepts and this rejects. What\nthe pool's remaining 11% holds is snippets that are not jq programs: 102 of\nthem are shell transcripts with the `jq` invocation still around the filter,\nand the rest are listings of several programs at once, prose, and entries with\na stray semicolon in them. jq will not compile any of them either.\n\n## What is jq's, and what is not\n\nFour things here are read that jq rejects. Each is written by one of the other\nimplementations, and none of them can change how a program jq accepts is read,\nbecause jq has no other meaning for the syntax.\n\n* **Hexadecimal numbers**, `0xff`, which fq takes.\n* **Backtick strings**, `` `\\d+` ``, which fq writes a pattern in.\n* **A format as a definition's name**, `def @json: …`, which is how jaq defines\n  one.\n* **A file of definitions with no query under it**, which is what a jq module\n  is, and which jq's own front end takes when it is imported rather than run.\n\n## What took the work\n\n* **A leading dot belongs to whatever reads furthest.** `..` recurses, `.5` is\n  a number, `.name` is a field, and a lone dot is the identity or the start of\n  `.\"name\"`. A field is one token, which is what makes `. name` not a field and\n  `.end` a field even though `end` closes a conditional.\n* **A comment ends where jq says it ends.** A backslash at the end of one\n  carries it onto the next line, which is jq's lexer reading the backslash and\n  the newline as two characters of comment. It costs a file in the corpus above,\n  a program written for jq 1.6 that jq 1.8 no longer compiles for exactly this\n  reason, and copying it is the point: an editor that disagreed with the\n  compiler would colour a broken program as though it worked.\n* **A suffix is read once, not twenty-four times.** jq's own grammar spells out\n  every combination of `.name`, `[…]`, `[:]` and the `?` that may follow each.\n  Reading a term and then a run of suffixes builds the same tree from a fifth of\n  the rules, and makes `.a[0]?` and `.a?[0]` both fall out.\n* **An object value takes a pipeline but not a comma.** `{a: .x | f, b: 1}` is\n  two keys, and a value that could hold a comma would make it one.\n* **A key is read before the language's own vocabulary is.** `{if: 1}` names a\n  key `if`, and so does every other word jq reserves.\n* **A string holds a query.** `\"\\(.a | f)\"` is parsed rather than skipped, so\n  what is inside an interpolation is coloured like the code it is.\n\n## What it does not read\n\nNothing jq compiles, as far as 1901 files of jq can say. The four extensions\nabove are the only places this is looser than jq, and they are deliberate.\n\n## Development\n\n```bash\nnpm install\nnpm test            # the parse specs and the editor behaviour\nnpm run corpus      # how much of a directory of jq parses clean\nnpm run gaps        # what it could not parse, grouped by shape\n```\n\n`corpus` and `gaps` delegate to\n[lezer-survey](https://codeberg.org/reeven/lezer-survey), which is expected to\nsit beside this checkout. Point either at a directory of `.jq` files.\n","readmeFilename":"README.md"}