fix(code-block): stop painting Go type names as function names #831

Merged
raisondetredev merged 1 commit from refs/pull/831/head into main 2026-08-08 20:37:19 +02:00
raisondetredev commented 2026-08-08 20:36:46 +02:00 (Migrated from codeberg.org)

In a Go block the same identifier came out two different colours depending
on which type expression it appeared in:

type Converter func(String)Score   // Score blue, as if it were a name
type TeamScores map[string]Score   // Score grey

The grey one is right. Go's grammar in the highlight package classifies
no user-defined name — not a struct, not a type alias — so every blue
identifier here is a false positive. Its function mode opens on the
keyword func and runs to { or end of line with a bare-identifier title
mode inside, and a title can match anywhere in that span, including after
the parameter list where Go puts the return type. The reported case is the
mildest one. It also titled the return type of ordinary declarations, and
func Greet(n string) string came back with the second string blue and
the first purple — one keyword, two colours, in one signature.

The region is narrowed to the only span that can hold a name. begin
becomes func not immediately followed by (, optionally plus a receiver
group: that skips anonymous funcs, which have no name to find, while
still admitting methods, whose name sits after the receiver. The parameter
list then ends the region, so nothing past the closing paren can be
titled, and the return type falls back to the top level where the language
keywords colour string and int properly again. Across a corpus of
declarations, methods, func types, func literals and multi-value returns,
exactly the declared names are titled and nothing else.

Not fixed the obvious way — a lookahead on the title itself — because the
engine re-tests a mode's begin against the matched lexeme in isolation
(Highlight._subMode), where the following ( is not there: the title
would match while scanning and then fail the re-test, and no title would
ever be produced. Only self-contained patterns survive that round trip. A
negative lookahead does, passing vacuously at end of input, which is why
the begin side works.

Built by copying rather than mutating. go is a package-level singleton
and compiling a grammar rewrites its Mode tree in place, so patching it
directly would leak into any other importer; if a package upgrade reshapes
the grammar past recognition, the unpatched grammar is used and colouring
stays as upstream ships it.

Separately, the language menu now writes each language the way it is
actually spelled — Go, Python, C#, C++, JavaScript, SQL — instead of the
bare tag. csharp is not a name anybody writes. The tag itself is
untouched: it is persisted on the node and keys the grammar lookup, so
this is presentation only, and a tag from outside the menu (imported decks
carry those) falls back to itself rather than being auto-capitalised into
a name its community doesn't use. The block's header label reads the same
way, since it is an echo of the menu choice.

Signed-off-by: Tizian 「ティツィアーン」 raisondetredev@pm.me

In a Go block the same identifier came out two different colours depending on which type expression it appeared in: type Converter func(String)Score // Score blue, as if it were a name type TeamScores map[string]Score // Score grey The grey one is right. Go's grammar in the `highlight` package classifies no user-defined name — not a struct, not a type alias — so every blue identifier here is a false positive. Its function mode opens on the keyword `func` and runs to `{` or end of line with a bare-identifier title mode inside, and a title can match anywhere in that span, including after the parameter list where Go puts the return type. The reported case is the mildest one. It also titled the return type of ordinary declarations, and `func Greet(n string) string` came back with the second `string` blue and the first purple — one keyword, two colours, in one signature. The region is narrowed to the only span that can hold a name. `begin` becomes `func` not immediately followed by `(`, optionally plus a receiver group: that skips anonymous `func`s, which have no name to find, while still admitting methods, whose name sits after the receiver. The parameter list then ends the region, so nothing past the closing paren can be titled, and the return type falls back to the top level where the language keywords colour `string` and `int` properly again. Across a corpus of declarations, methods, func types, func literals and multi-value returns, exactly the declared names are titled and nothing else. Not fixed the obvious way — a lookahead on the title itself — because the engine re-tests a mode's `begin` against the matched lexeme in isolation (`Highlight._subMode`), where the following `(` is not there: the title would match while scanning and then fail the re-test, and no title would ever be produced. Only self-contained patterns survive that round trip. A *negative* lookahead does, passing vacuously at end of input, which is why the `begin` side works. Built by copying rather than mutating. `go` is a package-level singleton and compiling a grammar rewrites its Mode tree in place, so patching it directly would leak into any other importer; if a package upgrade reshapes the grammar past recognition, the unpatched grammar is used and colouring stays as upstream ships it. Separately, the language menu now writes each language the way it is actually spelled — Go, Python, C#, C++, JavaScript, SQL — instead of the bare tag. `csharp` is not a name anybody writes. The tag itself is untouched: it is persisted on the node and keys the grammar lookup, so this is presentation only, and a tag from outside the menu (imported decks carry those) falls back to itself rather than being auto-capitalised into a name its community doesn't use. The block's header label reads the same way, since it is an echo of the menu choice. Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
project-halkyon/halkyon-learn!831
No description provided.