detached 3ed7469

perf(web): lex markdown code blocks without chroma coalescing and drop results past the deadline

commit
3ed746903cd6a04584ae699b9d178cd5e6d53513
author
brice · · 2026-10-20 14:42 UTC
parent
008636c
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
checks
7/8
2 files · +18 -8
M internal/adapters/web/highlight.go +3 -1
@@ -166,7 +166,9 @@ func tokeniseInto(ctx context.Context, lx chroma.Lexer, src string, buf []chroma
166166 }
167167 toks = append(toks, t)
168168 }
169- if !tokensMatch(toks, src) {
169+ // The last tokens may have run past the deadline: the result is then
170+ // dropped, as promised. One iterator call itself cannot be preempted.
171+ if ctx.Err() != nil || !tokensMatch(toks, src) {
170172 return nil, false
171173 }
172174 return toks, true
@@ -166,7 +166,9 @@ func tokeniseInto(ctx context.Context, lx chroma.Lexer, src string, buf []chroma
166 }166 }
167 toks = append(toks, t)167 toks = append(toks, t)
168 }168 }
169- if !tokensMatch(toks, src) {169+ // The last tokens may have run past the deadline: the result is then
170+ // dropped, as promised. One iterator call itself cannot be preempted.
171+ if ctx.Err() != nil || !tokensMatch(toks, src) {
170 return nil, false172 return nil, false
171 }173 }
172 return toks, true174 return toks, true
M internal/adapters/web/markdown_highlight.go +15 -7
@@ -69,6 +69,9 @@ func (fencedRenderer) RegisterFuncs(r renderer.NodeRendererFuncRegisterer) {
6969 line := n.Lines().At(i)
7070 remaining += len(line.Value(source))
7171 }
72+ // The tokens are not coalesced (chroma's coalescer copies strings
73+ // quadratically): adjacent tokens of one class share a span here.
74+ open := ""
7275 for _, tk := range toks {
7376 v := tk.Value
7477 if len(v) > remaining {
@@ -78,14 +81,19 @@ func (fencedRenderer) RegisterFuncs(r renderer.NodeRendererFuncRegisterer) {
7881 if v == "" {
7982 continue
8083 }
81- c := tokenClass(tk.Type)
82- if c != "" {
83- _, _ = w.WriteString(`<span class="` + c + `">`)
84+ if c := tokenClass(tk.Type); c != open {
85+ if open != "" {
86+ _, _ = w.WriteString(`</span>`)
87+ }
88+ if c != "" {
89+ _, _ = w.WriteString(`<span class="` + c + `">`)
90+ }
91+ open = c
8492 }
8593 writeMarked(w, v)
86- if c != "" {
87- _, _ = w.WriteString(`</span>`)
88- }
94+ }
95+ if open != "" {
96+ _, _ = w.WriteString(`</span>`)
8997 }
9098 _, _ = w.WriteString("</code></pre>\n")
9199 return ast.WalkSkipChildren, nil
@@ -152,6 +160,6 @@ func markdownTokens(n *ast.FencedCodeBlock, source []byte) ([]chroma.Token, stri
152160 }
153161 ctx, cancel := context.WithDeadline(context.Background(), budget.deadline)
154162 defer cancel()
155- toks, ok := tokenise(ctx, chroma.Coalesce(lx), code.String())
163+ toks, ok := tokenise(ctx, lx, code.String())
156164 return toks, lang, ok
157165 }
@@ -69,6 +69,9 @@ func (fencedRenderer) RegisterFuncs(r renderer.NodeRendererFuncRegisterer) {
69 line := n.Lines().At(i)69 line := n.Lines().At(i)
70 remaining += len(line.Value(source))70 remaining += len(line.Value(source))
71 }71 }
72+ // The tokens are not coalesced (chroma's coalescer copies strings
73+ // quadratically): adjacent tokens of one class share a span here.
74+ open := ""
72 for _, tk := range toks {75 for _, tk := range toks {
73 v := tk.Value76 v := tk.Value
74 if len(v) > remaining {77 if len(v) > remaining {
@@ -78,14 +81,19 @@ func (fencedRenderer) RegisterFuncs(r renderer.NodeRendererFuncRegisterer) {
78 if v == "" {81 if v == "" {
79 continue82 continue
80 }83 }
81- c := tokenClass(tk.Type)84+ if c := tokenClass(tk.Type); c != open {
82- if c != "" {85+ if open != "" {
83- _, _ = w.WriteString(`<span class="` + c + `">`)86+ _, _ = w.WriteString(`</span>`)
87+ }
88+ if c != "" {
89+ _, _ = w.WriteString(`<span class="` + c + `">`)
90+ }
91+ open = c
84 }92 }
85 writeMarked(w, v)93 writeMarked(w, v)
86- if c != "" {94+ }
87- _, _ = w.WriteString(`</span>`)95+ if open != "" {
88- }96+ _, _ = w.WriteString(`</span>`)
89 }97 }
90 _, _ = w.WriteString("</code></pre>\n")98 _, _ = w.WriteString("</code></pre>\n")
91 return ast.WalkSkipChildren, nil99 return ast.WalkSkipChildren, nil
@@ -152,6 +160,6 @@ func markdownTokens(n *ast.FencedCodeBlock, source []byte) ([]chroma.Token, stri
152 }160 }
153 ctx, cancel := context.WithDeadline(context.Background(), budget.deadline)161 ctx, cancel := context.WithDeadline(context.Background(), budget.deadline)
154 defer cancel()162 defer cancel()
155- toks, ok := tokenise(ctx, chroma.Coalesce(lx), code.String())163+ toks, ok := tokenise(ctx, lx, code.String())
156 return toks, lang, ok164 return toks, lang, ok
157 }165 }

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 2

Tags 43

↑↓ moveenter openesc close