@codincod/codemirror-lang-raku
v0.1.1
Published
Raku language support for the CodeMirror code editor
Maintainers
Readme
@codincod/codemirror-lang-raku 
[ CHANGELOG ]
This package implements Raku language support for the CodeMirror code editor, using a Lezer grammar written for this package.
CodeMirror has never shipped Raku. CodeMirror 5 had a Perl 6 mode contributed in 2011 and dropped before version 6, and nothing replaced it, so a Raku file in a browser editor has been either plain text or Perl 5 with the wrong keywords.
Written in part for CodinCod, a competitive coding platform, where it colours the editor people solve puzzles in.
This code is released under an MIT license.
Usage
import {EditorView, basicSetup} from "codemirror"
import {raku} from "@codincod/codemirror-lang-raku"
const view = new EditorView({
parent: document.body,
doc: `say "Hello World!";`,
extensions: [basicSetup, raku()]
})Coverage
Statements, declarations, signatures and the expression grammar; classes, roles and grammars; phasers; the quoting constructs including heredocs; Pod; and the operator set with its meta-operators. Measured against 1614 Raku files from Rosetta Code, 83.83% parse with no error node.
Two things are deliberately left flat. The inside of an interpolated string is
one token rather than a tree, and so is the body of a token, rule or
regex: Raku's regex sublanguage is a language of its own and deserves its own
grammar rather than a corner of this one.
Three things Raku decides for itself
The operators are not written out in the grammar. Raku's operator set is
open, and its meta-operators build new ones out of old ones, so »+«, [+],
Z+ and R- are operators that nobody listed anywhere. The tokenizer reads a
run of operator characters, peels off the meta-operator wrappers and looks up
what is left, then hands the parser one of seventeen precedence classes. A
symbol it has never seen is an operator too, because anybody may write sub
infix:<∧> and then use it.
Nothing is reserved. hyper introduces a statement and is also a method
everybody calls; where is a trait and a perfectly good routine name. A word is
a keyword only where the parser has room for that keyword, so the same word
reads as a keyword in one column and as a name in the next.
A character means one thing where a value can follow and another where a value
has just been read. That one question settles / (a pattern or a division),
* (a whatever or a multiplication), < (a list of words or a comparison), x
(a variable or a repetition), and the rest. The parser is asked which of the two
it is in, and it answers by saying whether it has room for a multiplication yet.
Where even that is not enough, spacing decides, as it does in Raku itself: an
infix has space on both sides or on neither, so space on the left alone means a
term is starting. grep * %% 2, @a is a grep, and $exp +1 is an addition.
What it gives an editor
Syntax highlighting, folding for blocks, signatures and Pod, indentation that knows a brace closes a block and lines a signature up under its opening parenthesis, and completion for the keywords, the built-in types, the built-in routines and the dynamic variables.
rakuLanguage is exported for use with LanguageSupport, and parser for use
on its own.
Testing it on your own code
node test/corpus.ts path/to/your/rakuIt prints the files that failed, the first line of each that did, and the proportion that came out clean. The corpus itself is not included; Rosetta Code is CC BY-SA and cannot be redistributed under this licence.
