{"_id":"@codincod/codemirror-lang-odin","_rev":"4-41acecf6299e9b6681b1c99b3aa50472","name":"@codincod/codemirror-lang-odin","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@codincod/codemirror-lang-odin","version":"0.1.0","keywords":["editor","code","odin","codemirror"],"author":{"name":"CodinCod","email":"hello@codincod.com"},"license":"MIT","_id":"@codincod/codemirror-lang-odin@0.1.0","maintainers":[{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"}],"dist":{"shasum":"78da92593df6eddc53ec35aa048dfdf2177de711","tarball":"https://registry.npmjs.org/@codincod/codemirror-lang-odin/-/codemirror-lang-odin-0.1.0.tgz","fileCount":14,"integrity":"sha512-A0yGzJtkP5C+BNRskqrW8rEIt9B1pztzDX9MkuUw6uHaGvigstf9hQ5jYgWCsnNhpSSRz9hQPd9sqXRftiGLEg==","signatures":[{"sig":"MEQCIB+/yof+lwXTLeeCrH70WjSlboi0LhGGb4/KG+itlYLQAiAWyq567EN+u3CWTgyc/zD3H8H+QnEbBff202rCqe1LUw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":259445},"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":"08bac197afd1aebdce3f553866abbb9d95e03039","scripts":{"test":"npm run build && node --test \"test/*.test.ts\"","build":"rm -rf dist && lezer-generator src/odin.grammar -o src/parser.js && cm-buildhelper src/odin.ts","corpus":"npm run build && node test/corpus.ts","prepare":"npm run build","build-debug":"lezer-generator src/odin.grammar --names -o src/parser.js && cm-buildhelper src/odin.ts"},"_npmUser":{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"},"repository":{"url":"git+https://codeberg.org/reeven/codemirror-lang-odin.git","type":"git"},"_npmVersion":"11.6.2","description":"Odin 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-odin_0.1.0_1785186808930_0.18154959797542425","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@codincod/codemirror-lang-odin","version":"0.1.1","keywords":["editor","code","odin","codemirror"],"author":{"name":"CodinCod","email":"hello@codincod.com"},"license":"MIT","_id":"@codincod/codemirror-lang-odin@0.1.1","maintainers":[{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"}],"homepage":"https://codincod.com/","dist":{"shasum":"4f4f98153a1d75856e1f1cfb293c533a022fd3e7","tarball":"https://registry.npmjs.org/@codincod/codemirror-lang-odin/-/codemirror-lang-odin-0.1.1.tgz","fileCount":14,"integrity":"sha512-F+F8E/6W5065/jkgyIBfwmwYXshBSA1YpOXCQVKk82XMb16hKp/RSEyMUXV0YOuVognJaPn1EbCy3UtlLlUV+w==","signatures":[{"sig":"MEUCIQCetiEtlVlEuDZgWypGVvK6JxLwxDG5RCqAkjW5nym3KwIgPWHehb4zh6aKpfZXJ+6zq54Su7GOILYpL8loW8Sb8l4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":259624},"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":"9a955e6a28c2394ef0fbc51f356b4f766f617042","scripts":{"test":"npm run build && node --test \"test/*.test.ts\"","build":"rm -rf dist && lezer-generator src/odin.grammar -o src/parser.js && cm-buildhelper src/odin.ts","corpus":"npm run build && node test/corpus.ts","prepare":"npm run build","build-debug":"lezer-generator src/odin.grammar --names -o src/parser.js && cm-buildhelper src/odin.ts"},"_npmUser":{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"},"repository":{"url":"git+https://codeberg.org/reeven/codemirror-lang-odin.git","type":"git"},"_npmVersion":"11.6.2","description":"Odin 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-odin_0.1.1_1785286870449_0.8809433281289496","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@codincod/codemirror-lang-odin","version":"0.1.2","keywords":["editor","code","odin","codemirror"],"author":{"name":"CodinCod","email":"hello@codincod.com"},"license":"MIT","_id":"@codincod/codemirror-lang-odin@0.1.2","maintainers":[{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"}],"homepage":"https://codincod.com/","dist":{"shasum":"98d55381bd2f9e99e761436f9def810b1a8a110f","tarball":"https://registry.npmjs.org/@codincod/codemirror-lang-odin/-/codemirror-lang-odin-0.1.2.tgz","fileCount":14,"integrity":"sha512-2NNYAPuSHARg4dNDkf9IpG8Hcc1n2wcUB6c0+CjeH6pOV0resczQrp6/CFetFc6s3zSql16+YS8sSoCGiCXjeQ==","signatures":[{"sig":"MEYCIQDKoYHGBDYtW2gjcf2gxddIMbaGbWzM58tnAXX1lMqkMQIhAKFI2KjOBUR6xoXx5FvH+baXxIA3M5tGUkLUFP8l4zsi","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":259735},"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":"bdfef4122a89b9c07446b35e11b0fa72bab04628","scripts":{"gaps":"npm run build && node ../lezer-survey/src/cli.ts gaps --group parent","test":"npm run build && node --test \"test/*.test.ts\"","build":"rm -rf dist && lezer-generator src/odin.grammar -o src/parser.js && cm-buildhelper src/odin.ts","corpus":"npm run build && node ../lezer-survey/src/cli.ts measure --group parent","prepare":"npm run build","build-debug":"lezer-generator src/odin.grammar --names -o src/parser.js && cm-buildhelper src/odin.ts"},"_npmUser":{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"},"repository":{"url":"https://codeberg.org/reeven/codemirror-lang-odin","type":"git"},"_npmVersion":"11.6.2","description":"Odin 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-odin_0.1.2_1785970753191_0.22304867970657005","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@codincod/codemirror-lang-odin","version":"0.2.0","description":"Odin language support for the CodeMirror code editor","keywords":["editor","code","odin","codemirror"],"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/odin.grammar -o src/parser.js && cm-buildhelper src/odin.ts","build-debug":"lezer-generator src/odin.grammar --names -o src/parser.js && cm-buildhelper src/odin.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 parent","fuzz":"npm run build && node ../lezer-survey/src/cli.ts fuzz","gaps":"npm run build && node ../lezer-survey/src/cli.ts gaps --group parent"},"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-odin"},"gitHead":"cf27902da4196e99905f53cb840179a0b1a8263e","_id":"@codincod/codemirror-lang-odin@0.2.0","_nodeVersion":"25.0.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-PI3+VCW2PMUplTUkEVsi7fD7fo5ODQfAjSOQ3BHWuOinoL/4NZiEQjNJ+vw+4oWc4s5Nb3t8f/jhu9djPDkn3w==","shasum":"af8259bc76ac5f0616ec92cf50f0d9c42086c30c","tarball":"https://registry.npmjs.org/@codincod/codemirror-lang-odin/-/codemirror-lang-odin-0.2.0.tgz","fileCount":14,"unpackedSize":259774,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCGlglZ65LwWHMjXp/aPBOdkAoHq+6xoLFddnaj76vxXQIhAKIp5aE86jLpgH1GAcJCgxs/0EF+IIt1cbsYcKglqW2O"}]},"_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-odin_0.2.0_1786760287643_0.7989808622146253"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-27T21:13:28.723Z","modified":"2026-08-15T02:18:07.962Z","0.1.0":"2026-07-27T21:13:29.116Z","0.1.1":"2026-07-29T01:01:10.621Z","0.1.2":"2026-08-05T22:59:13.338Z","0.2.0":"2026-08-15T02:18:07.785Z"},"author":{"name":"CodinCod","email":"hello@codincod.com"},"license":"MIT","homepage":"https://codincod.com/","keywords":["editor","code","odin","codemirror"],"repository":{"type":"git","url":"https://codeberg.org/reeven/codemirror-lang-odin"},"description":"Odin language support for the CodeMirror code editor","maintainers":[{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"}],"readme":"# @codincod/codemirror-lang-odin [![NPM version](https://img.shields.io/npm/v/@codincod/codemirror-lang-odin.svg)](https://www.npmjs.org/package/@codincod/codemirror-lang-odin)\n\n[ [**CHANGELOG**](https://codeberg.org/reeven/codemirror-lang-odin/src/branch/master/CHANGELOG.md) ]\n\nThis package implements Odin language support for the\n[CodeMirror](https://codemirror.net/) code editor, using a\n[Lezer](https://lezer.codemirror.net/) grammar written for this package.\n\nCodeMirror has never shipped Odin, and there is no stream mode from CodeMirror 5\nto fall back on either, so an Odin file in a CodeMirror 6 editor has until now\nbeen plain text. No Lezer grammar for Odin existed anywhere before this one.\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-odin/src/branch/master/LICENSE).\n\n## Usage\n\n```javascript\nimport {EditorView, basicSetup} from \"codemirror\"\nimport {odin} from \"@codincod/codemirror-lang-odin\"\n\nconst view = new EditorView({\n  parent: document.body,\n  doc: `package main\n\nimport \"core:fmt\"\n\nPoint :: struct {\n\tx, y: f32,\n}\n\nmain :: proc() {\n\tp := Point{x = 1, y = 2}\n\tfmt.println(p)\n}\n`,\n  extensions: [basicSetup, odin()]\n})\n```\n\n## Coverage\n\nOdin dev-2025-04. Declarations of every kind (`::` for procedures, types and\nconstants, `:=` for variables), structs with tags and parapoly parameters,\nunions, enums, bit sets, bit fields, matrices, `#soa` and `#simd` types,\nprocedure groups, polymorphic types (`$T`, `$T/Spec`) with `where` clauses,\nforeign blocks and foreign imports, attributes, compile-time `when`, the whole\ndirective vocabulary, `or_return` and its family, both ternaries, type\nassertions, ranges, labels, and the automatic semicolons that make almost all of\nthis readable without one.\n\nMeasured against the 1090 files of the standard library that ships with the\ncompiler, 99.91% parse with no error node. The one file left is `base:builtin`,\nwhich describes the compiler's built-in procedures in a notation Odin's own\nparser rejects as well (`-> (A, B, C, ...)`), and which the compiler never reads\nas ordinary Odin.\n\nThe corpus does not ship with this package. It is BSD-3 and belongs to the Odin\nproject, so `npm run corpus` takes the path to your own copy of it.\n\n## What a tokenizer has to settle\n\nAlmost all of Odin can be written down as a grammar. Seven things cannot, and\nthey are the whole of `tokens.ts`.\n\n**A newline can end a statement.** Odin inserts a semicolon at a line break when\nthe token in front of it could end one, which is why almost no Odin source\nwrites a semicolon. Whether the break ends the statement depends on the token\nbehind it and on what stands after it: a brace where a body could stand, an\n`else`, or a `where` all take the semicolon back.\n\n**A brace is two different things.** `if x == Foo {` opens a body and\n`x := Foo{}` opens a compound literal, and the same character spells either.\nOdin settles it by where the brace stands, so the tokenizer asks the parser\nwhether a body could stand here and lets the answer decide. That is Odin's own\nrule: its parser refuses a compound literal in the head of an `if`, a `for` or a\n`switch` unless it is parenthesised, and those heads are exactly the places\nwhere a body could stand instead.\n\n**A name is not an expression.** `x, y := f()` and `x, y = f()` are the same two\nnames and the same comma, and only the operator behind them differs. Odin's\nparser reads the list and then looks for the colon; an LR parser cannot hold\nboth readings open that long, so the tokenizer does the same lookahead one word\nearlier and hands the parser a different token for a name being declared. The\nsame lookahead separates `loop: for {}` from `x: int`.\n\n**`::` says what is being declared.** `main :: proc() {}` declares a procedure,\n`Point :: struct {}` a type and `MAX :: 100` a constant. The three read\nidentically until the value is over, which is far too late to name the node a\nhighlighter wants, so the tokenizer looks one word past the `::` and hands the\nparser three different tokens. That is what makes a procedure name look like a\nprocedure name before its body has been read.\n\n**`in` walks or asks.** `for x in xs` walks a map or an array, and `x in xs`\nasks whether a set holds something. Odin turns the operator off while it reads\nthe head of a `for`, and the tokenizer does the same by handing a range clause\nan `in` of its own, where only a range clause could stand.\n\n**A number may end in its point.** `1.` is a float and `1..<n` is a range from\n1. A token rule reads as far as it can and would take the range's first dot for\nthe point of the number, so numbers are scanned by hand, where the character\nbehind the dot can be looked at first. Odin's own scanner does the same, and the\none here is a reading of it, down to the letters that count as digits in `0z`\nand `0h`.\n\n**Block comments nest.** `/* /* */ */` is one comment in Odin rather than two,\nwhich no regular token can count.\n\n## What the tree does not say\n\n**Types are expressions.** That is not a simplification: Odin's own AST has no\nseparate type node, because `Point :: struct {}` really is a value bound to a\nname and `[4]int` really is an expression. So `struct`, `[]T`, `map[K]V` and\n`proc()` are alternatives of `expression` in the grammar, exactly as they are in\nthe compiler.\n\n**One field rule does three jobs.** Struct fields, procedure parameters and\nresults are written the same way, down to the `using` in front and the string\ntag behind, so one rule shape serves all three. It accepts a tag where only a\nstruct may carry one, which is the usual trade: a grammar that is wrong about\nwhat the compiler will reject and right about what it will accept.\n\n**A `do` body on a procedure literal is left out.** `f :: proc() do g()` is\nlegal and appears nowhere in the standard library. Letting an unbraced statement\nend where a procedure literal may stand is what the parser generator runs out of\nmemory over, so the one form the grammar refuses is the one nobody writes.\n","readmeFilename":"README.md"}