{"_id":"@codincod/codemirror-lang-kotlin","_rev":"2-dc1a2b54447598fe63a4e78956e45e0b","name":"@codincod/codemirror-lang-kotlin","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@codincod/codemirror-lang-kotlin","version":"0.1.0","keywords":["editor","code","kotlin","jvm","android","codemirror"],"author":{"name":"CodinCod","email":"hello@codincod.com"},"license":"MIT","_id":"@codincod/codemirror-lang-kotlin@0.1.0","maintainers":[{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"}],"homepage":"https://codincod.com/","dist":{"shasum":"68d67d8347ea23edc8371e851c568662cc14699b","tarball":"https://registry.npmjs.org/@codincod/codemirror-lang-kotlin/-/codemirror-lang-kotlin-0.1.0.tgz","fileCount":14,"integrity":"sha512-H6zhEl1PAnCKwWt4InDrX9M/U1Z01s6hJtmxKaL1WTIOJaGZkQLCoofzAoIb+4Gc4kI27iDJ3TT25pml9SpgaQ==","signatures":[{"sig":"MEUCID0GvQS652QLnZUzWuPjkTjv/3gdS/VrtmyDXtFST0KLAiEAnoT/UPpr0mnveMF4PgGLm+aSBkXVTBpTpfsk8Uit0Ao=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":303577},"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":"4aaed49f0695ce68d978bb481fa8bce38c9c26a1","scripts":{"test":"npm run build && node --test \"test/*.test.ts\"","build":"rm -rf dist && lezer-generator src/kotlin.grammar -o src/parser.js && cm-buildhelper src/kotlin.ts","corpus":"npm run build && node test/corpus.ts","prepare":"npm run build","build-debug":"lezer-generator src/kotlin.grammar --names -o src/parser.js && cm-buildhelper src/kotlin.ts"},"_npmUser":{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"},"repository":{"url":"git+https://codeberg.org/reeven/codemirror-lang-kotlin.git","type":"git"},"_npmVersion":"11.6.2","description":"Kotlin 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-kotlin_0.1.0_1785632046634_0.551359023981149","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@codincod/codemirror-lang-kotlin","version":"0.1.1","description":"Kotlin language support for the CodeMirror code editor","keywords":["editor","code","kotlin","jvm","android","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/kotlin.grammar -o src/parser.js && cm-buildhelper src/kotlin.ts","build-debug":"lezer-generator src/kotlin.grammar --names -o src/parser.js && cm-buildhelper src/kotlin.ts","prepare":"npm run build","test":"npm run build && node --test \"test/*.test.ts\"","corpus":"npm run build && node ../lezer-survey/src/cli.ts measure --group top","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/common":"^1.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-kotlin"},"gitHead":"c1bb11739497854352ce9a26f9d388b4f20b6b44","_id":"@codincod/codemirror-lang-kotlin@0.1.1","_nodeVersion":"25.0.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-wdSWLXJMn3oL8MBsROrnOSp8K5VD5b+6qyMipOFzeUye23wkoc/StTFnh91aPlCy08JlzSjUrlM0njBqR96wqQ==","shasum":"888225a1ea96fd4670b5221a791ee81d55a07f75","tarball":"https://registry.npmjs.org/@codincod/codemirror-lang-kotlin/-/codemirror-lang-kotlin-0.1.1.tgz","fileCount":14,"unpackedSize":303682,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCLIm3r1boZI0cczXirntw+8/aVLbEV+EuimZ3Zz5NKAAIgGBRrxMDqBapEl6UtDq5kikyRKtDPt6+ipc19Se7By0w="}]},"_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-kotlin_0.1.1_1785970503982_0.060654777292670436"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-02T00:54:06.538Z","modified":"2026-08-05T22:55:04.300Z","0.1.0":"2026-08-02T00:54:06.768Z","0.1.1":"2026-08-05T22:55:04.136Z"},"author":{"name":"CodinCod","email":"hello@codincod.com"},"license":"MIT","homepage":"https://codincod.com/","keywords":["editor","code","kotlin","jvm","android","codemirror"],"repository":{"type":"git","url":"https://codeberg.org/reeven/codemirror-lang-kotlin"},"description":"Kotlin language support for the CodeMirror code editor","maintainers":[{"name":"juicemitapfelndrin","email":"juicemitapfelndrin@gmail.com"}],"readme":"# @codincod/codemirror-lang-kotlin [![NPM version](https://img.shields.io/npm/v/@codincod/codemirror-lang-kotlin.svg)](https://www.npmjs.org/package/@codincod/codemirror-lang-kotlin)\n\n[ [**CHANGELOG**](https://codeberg.org/reeven/codemirror-lang-kotlin/src/branch/master/CHANGELOG.md) ]\n\nThis package implements Kotlin 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 6 has never shipped Kotlin, and no Lezer grammar for it existed\nbefore this one. What gets used instead is the C-family stream mode ported from\nCodeMirror 5, which colours a list of keywords and builds no tree, so nothing\nabove it can fold a function, indent a `when` or ask what the word under the\ncursor is. It also predates most of the language: string templates, raw\nstrings, labels and annotations all come out as plain text.\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-kotlin/src/branch/master/LICENSE).\n\n## Usage\n\n```javascript\nimport {EditorView, basicSetup} from \"codemirror\"\nimport {kotlin} from \"@codincod/codemirror-lang-kotlin\"\n\nconst view = new EditorView({\n  parent: document.body,\n  doc: `data class Greeter(val name: String) {\n    fun greet(): String = \"Hello, $name!\"\n}\n`,\n  extensions: [basicSetup, kotlin()]\n})\n```\n\n## Coverage\n\nKotlin 2.2. Classes, interfaces, objects and companions, data and value\nclasses, sealed hierarchies, enums, annotations and their use site targets,\ntypealiases, extension functions and properties, generics with variance and\n`where` clauses, delegation, property accessors and delegates, coroutines and\n`suspend`, lambdas and trailing lambdas, callable references, destructuring,\nlabels and labelled jumps, `when` with and without a subject, and every way\nKotlin writes a string, including the multi dollar raw strings 2.2 added.\n\nMeasured against 6 589 Kotlin files from six open source projects (ktor,\ndetekt, kotlinx.coroutines, Exposed, kotlinx.serialization and okio), which is\n26 MiB of code, of which 97.33% parse with no error node.\n\n## What the grammar cannot say\n\nFour things about Kotlin are settled in `src/tokens.ts` rather than in the\ngrammar, because no context free rule can decide them.\n\n**A newline ends a statement, except when it does not.** Kotlin has no\nsemicolons and no statement terminator, so `a\\nb` is two statements and `a +\\nb`\nis one. The tokenizer emits a zero width `insertSemi` when a line break stands\nbetween two things that could each begin a statement, and holds it back when\nthe next line opens with something that can only continue the one before: an\noperator, a dot, a closing bracket, `as`, `by`, `else`, `finally`, a `catch`\nfollowed by its parenthesis, a `where` followed by a constraint, or a `get` or\n`set` that turns out to be an accessor rather than a call. That last list is\nthe whole difficulty. `set.addAll(x)` at the start of a line is a call to a\nset, and `set(value) { }` under a property is an accessor, and only what\nfollows the word tells them apart.\n\n**A `<` is a comparison or a type argument list.** `a < b` and `Map<K, V>` are\nthe same two characters. When the parser could shift a comparison the tokenizer\nscans ahead over what a type argument list is allowed to contain, up to two\nhundred characters, and only emits the bracket tokens if it reaches a matching\n`>` followed by something that could stand after a type. A `*` inside the\nbrackets settles it immediately, because a star projection cannot be anything\nelse.\n\n**A string is four different languages.** `\"a\"`, `\"\"\"a\"\"\"`, `$\"a\"` and their\ntemplates disagree about what ends a string, what an escape is, and whether a\n`$` opens a hole. The tokenizer cuts each one into a start, its content and an\nend, and the grammar parses the expressions between the pieces. A raw string is\nread whole, because its content is whatever stands before three quotes.\n\n**A block comment nests.** `/* /* */ */` is one comment in Kotlin and two in\nmost of its relatives, so the tokenizer counts depth rather than searching for\nthe first `*/`.\n\nOne more is settled in the grammar, and is worth knowing about.\n\n**Casing decides what a name is.** After one identifier no amount of lookahead\nseparates a type from a variable, so the parser follows the convention every\nKotlin codebase keeps: `Foo` is read as a type, `FOO_BAR` as a constant, and\n`foo` as an ordinary name. Both readings stay alive where the grammar allows\neither, and the one that fits wins. The trick is\n[@lezer/java](https://github.com/lezer-parser/java)'s.\n\n## Known gaps\n\n`when` guards, the `if` that Kotlin 2.1 allows after a branch condition, are\nnot parsed. The guard and a branch whose condition is itself an `if` expression\nshare a prefix that an LR parser cannot tell apart, and resolving it in the\nguard's favour cost more real files than it fixed.\n\n## Testing\n\n```\nnpm test                       # the parse specs, then highlighting and indentation\nnpm run corpus -- path/to/code # error nodes over a directory of real Kotlin files\n```\n\nNo corpus ships with the package, because none of that code is ours to\nredistribute. `npm run corpus` takes a directory and reports the share of files\nthat parse with no error node, grouped by directory so that a project which\ndrags the total down names itself.\n","readmeFilename":"README.md"}