{"_id":"@codincod/codemirror-lang-gleam","name":"@codincod/codemirror-lang-gleam","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@codincod/codemirror-lang-gleam","version":"0.1.0","description":"Gleam language support for the CodeMirror code editor","keywords":["editor","code","gleam","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"},"types":"dist/index.d.ts","module":"dist/index.js","sideEffects":false,"scripts":{"build":"cm-buildhelper src/index.ts","corpus":"npm run build && node ../lezer-survey/src/cli.ts measure --ext .gleam --group top","fuzz":"npm run build && node ../lezer-survey/src/cli.ts fuzz --ext .gleam","gaps":"npm run build && node ../lezer-survey/src/cli.ts gaps --ext .gleam --group top","prepare":"npm run build","test":"npm run build && node --test test/*.test.js"},"dependencies":{"@codemirror/autocomplete":"^6.0.0","@codemirror/language":"^6.0.0","@lezer/common":"^1.0.0","@lezer/highlight":"^1.0.0","@lezer/lr":"^1.0.0"},"devDependencies":{"@codemirror/buildhelper":"^1.0.0","@codemirror/state":"^6.0.0","@codemirror/view":"^6.0.0","@lezer/generator":"^1.0.0"},"homepage":"https://codincod.com/","repository":{"type":"git","url":"https://codeberg.org/reeven/codemirror-lang-gleam"},"gitHead":"ede159ec6fb8eff4b643ef537f9bea3953d1f3ee","_id":"@codincod/codemirror-lang-gleam@0.1.0","_nodeVersion":"25.0.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-z/NXbxfvFI+Cao3I2mpVrjwgNFyNTIlXFNdOQrFj5NwyNIupCG0o2r96+nl/RLlxxwKN9w5e1l5pfNXXr3bkQg==","shasum":"2ad0bc17791bdefa148288128bf6f29a9c253651","tarball":"https://registry.npmjs.org/@codincod/codemirror-lang-gleam/-/codemirror-lang-gleam-0.1.0.tgz","fileCount":12,"unpackedSize":87427,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDsaDqj65I6Pm9vQM1bA4gdsnC2b0DEFkYYAROZCH6ETwIgPGE245XozqyDebo8SLD/j2zd2rnHTj+WPochp0tajHk="}]},"_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-gleam_0.1.0_1786529750106_0.18797753645442383"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-12T10:15:49.875Z","0.1.0":"2026-08-12T10:15:50.263Z","modified":"2026-08-12T10:15:50.631Z"},"maintainers":[{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"}],"description":"Gleam language support for the CodeMirror code editor","homepage":"https://codincod.com/","keywords":["editor","code","gleam","codemirror"],"repository":{"type":"git","url":"https://codeberg.org/reeven/codemirror-lang-gleam"},"author":{"name":"CodinCod","email":"hello@codincod.com"},"license":"MIT","readme":"# @codincod/codemirror-lang-gleam\n\n[Gleam](https://gleam.run) language support for the\n[CodeMirror](https://codemirror.net/) code editor.\n\nThis provides a self-contained [Lezer](https://lezer.codemirror.net/) grammar\nfor Gleam (built with `@lezer/generator`, not a WASM build of the official\ntree-sitter grammar) plus the CodeMirror 6 wiring — syntax highlighting,\nindentation, code folding, and a handful of snippet completions.\n\n## Usage\n\n```javascript\nimport { EditorView, basicSetup } from \"codemirror\";\nimport { gleam } from \"@codincod/codemirror-lang-gleam\";\n\nconst view = new EditorView({\n  doc: 'pub fn main() {\\n  io.println(\"Hello, Gleam!\")\\n}\\n',\n  extensions: [basicSetup, gleam()],\n  parent: document.body,\n});\n```\n\nThe package also exports the bare `gleamLanguage` (an `LRLanguage`, useful if\nyou want the syntax tree without the editor extensions) and `parser` (the raw\n`@lezer/lr` parser).\n\n```javascript\nimport { gleamLanguage, parser } from \"@codincod/codemirror-lang-gleam\";\n```\n\n## What's supported\n\nModules and imports, `pub`/`opaque`, functions (including labelled and\ndiscarded parameters), custom types and type aliases, constants, `let`,\n`let assert`, `use`, `assert`, `case` (with guards and or-patterns), all of\nGleam's binary operators with correct precedence, anonymous functions, record\nconstruction and update syntax, field/tuple access, pipes, bit arrays,\n`todo`/`panic`/`echo`, and the three comment forms (`//`, `///`, `////`).\n\nAlso the parts of the language a grammar written from the tree-sitter one\nmisses: functions and types declared with no body under an `@external`\nattribute, the `label:` shorthand in a call or a record update, `as` naming a\npiece of a string-prefix pattern, a bit array segment sized by an expression,\nand the rule that decides whether a minus sign belongs to the number after it\nor to the expression before it.\n\n### Known simplifications\n\nThis grammar favours accepting a permissive superset of valid Gleam over\nstrictly enforcing the language spec, which is normal for editor tooling\n(rejecting valid-looking code while the user is still typing is worse than\noccasionally accepting something the compiler wouldn't):\n\n- constant values, pattern literals, and `case` guards reuse the general\n  expression grammar rather than Gleam's more restricted subsets for those\n  positions;\n- an identifier that starts with `_` always parses as a discard rather than\n  an ordinary (if unused) bound name;\n- the deprecated `if erlang { ... }` / `if javascript { ... }` target blocks\n  and `external fn` / `external type` (removed in Gleam v0.30) aren't\n  supported;\n- the pre-v0.30 `todo(\"message\")` / `panic(\"message\")` call syntax isn't\n  supported — use `todo as \"message\"` / `panic as \"message\"`;\n- a name written in capitals directly against a negative number, `Foo-1`,\n  reads as a subtraction where the compiler reads it as two values. Both are\n  errors a line later, and telling them apart costs a scan back over the\n  whole word;\n- an expression built out of several hundred operators is abandoned partway\n  by `@lezer/lr`, which gives up on a stack rather than growing it without\n  limit. One file in the corpus below is long enough to hit that.\n\n## Measured\n\nAgainst 22242 published `.gleam` files, gathered from the 1154 GitHub\nrepositories with two stars or more that GitHub reports as Gleam: **98.84%\nparse with no error node.**\n\nWhat the rest of that number is matters more than the number. The Gleam\ncompiler was run over the same corpus as an oracle (`gleam format --stdin`,\nv1.18.1, which parses without type checking), and it rejects 352 of those\nfiles outright — they are Gleam from before v1.0, written with `external fn`,\n`try`, `assert Ok(x) = ...` and `if erlang { ... }`, none of which today's\ncompiler will read either:\n\n| | files |\n| --- | --- |\n| corpus | 22242 |\n| rejected by the Gleam compiler | 352 |\n| **valid Gleam** | **21890** |\n| of those, parsed with no error node | 21889 (99.995%) |\n\nThe single exception is the operator chain above. Every file cut short at\n136535 places, the way a file is while it is being typed, parsed without the\ngrammar throwing.\n\n## Developing\n\n```\nnpm install\nnpm run build    # compiles src/syntax.grammar + src/index.ts into dist/\nnpm test         # builds, then runs the grammar tests in test/\nnpm run corpus <dir>   # the share of a directory of Gleam that parses clean\nnpm run gaps <dir>     # what is left, grouped by the shape of the failure\n```\n\nThe corpus scripts want [lezer-survey](https://codeberg.org/reeven/lezer-survey)\nchecked out beside this package.\n\nThe grammar (`src/syntax.grammar`) started from the language described by the\nofficial [tree-sitter-gleam](https://github.com/gleam-lang/tree-sitter-gleam)\ngrammar, restructured for Lezer's LR/GLR generator, and was then settled\nagainst the compiler itself: `compiler-core/src/parse/lexer.rs` for the\ntokens, `parse.rs` for the shape of a declaration. Two decisions the parser\ncannot make live in `src/tokens.ts`, both of them ported from that lexer: a\nminus sign against a digit is part of the number unless a name or another\nnumber ends right against it, and `echo` at the end of a pipe takes no\nargument.\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-e58124d9d8286e3c18c31b4032e39218"}