Documentation
¶
Overview ¶
Package nanorc reads GNU nano's syntax-highlighting definitions so nem can colour the languages it has no hand-written lexer for.
nano ships around forty .nanorc files describing C, Python, Rust, shell, YAML and more. They are read from the system at runtime, exactly as nano reads them. Nothing from them is copied into this repository: they are GPL, and vendoring them would put nem's own licensing at issue. A machine without nano installed simply gets no extra languages.
Why the colours are thrown away ¶
A .nanorc rule names a colour - "color brightcyan" - while nem's renderer maps a semantic syntax.Class to a theme style. That indirection is what lets nem carry a light and a dark palette; taking nano's colour literally would hard-code a dark-terminal choice into every rule.
The obvious fix is a colour-to-class table, and it does not work. Measuring the corpus, nano's colours carry no shared meaning across files: strings are red in java.nanorc and green in rust.nanorc, and every common colour is used for keywords in one file and something else in the next. They are per-file aesthetic choices.
So the class is inferred from what a rule's pattern MATCHES rather than from the colour it was given. A pattern listing bare words between word boundaries is keywords; one wrapping a character class in quotes is strings; one running a comment introducer to end-of-line is comments. That is language-agnostic and does not depend on a convention that turns out not to exist.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DefaultDirs ¶
func DefaultDirs() []string
DefaultDirs are searched in order, with later directories winning.
The user's own directory comes last so a hand-written definition replaces the system one for the same language rather than competing with it.
Types ¶
type Lexer ¶
type Lexer struct {
// contains filtered or unexported fields
}
Lexer applies one Syntax's rules to a line at a time.
It satisfies syntax.Lexer, so a nanorc-described language plugs into the same incremental highlight cache the hand-written lexers use.
func (Lexer) Lex ¶
Lex classifies one line.
Rules are applied in the order the .nanorc lists them and each paints over whatever came before, which is nano's own precedence. Painting into a per-rune array rather than collecting spans is what makes that exact: regex matches in these files overlap constantly, and resolving overlaps after the fact would need the same array anyway.
type Set ¶
type Set struct {
// contains filtered or unexported fields
}
Set is the loaded collection of language definitions.
The zero Set matches nothing, which is what a machine without nano installed gets - and is why every caller can use a Set without checking for nil.
func Load ¶
Load reads every .nanorc in the given directories.
A missing directory is not an error: most machines will have some of these and not others. Problems with individual files and individual patterns are returned rather than raised, so a caller can report them without one bad file costing the user every other language.
func (*Set) For ¶
For returns a lexer for a file, or nil if no definition matches.
firstLine is matched against header patterns, which is how a script with no extension gets highlighted from its shebang. Pass "" when it is not known; extension matching still works.
It returns nil rather than a plain lexer so a caller can tell "no nanorc covers this" from "this is plain text", and keep its own lexers in front.
type Syntax ¶
type Syntax struct {
Name string
// Comment is the line-comment introducer the file declares, kept because a
// future comment-toggle command needs it and nothing else records it.
Comment string
// contains filtered or unexported fields
}
Syntax is one language's rules.
func Parse ¶
Parse reads one .nanorc file.
A pattern that will not compile is skipped on its own: nano's files are third party and a single unsupported regex must not cost a language its other twelve rules. The skipped patterns are returned so a caller can report them without the failure being silent.