A CLI-first git forge.

cli forge git self-hosted

https://gitbay.org

Commit 846b17ebe7

846b17ebe7687ac4d34c9bffc2276da0a38ce28e

parent: cf58aba82d

Verified · cmc ci/build: success

cmc <hello@cleberg.net> · 2026-08-26T22:56:28Z

web: diff syntax highlighting was never applying

chroma scopes every token rule under .chroma, and the per-line markup
has no wrapper of its own, so the token classes matched nothing and each
line inherited one flat colour. The cell is the wrapper now.

That flat colour came from details.difffold .add/.del, meant for the
+N/-M counts in the fold summary but also matching tr.add/tr.del; those
are scoped to the summary.

The old test asserted the token classes existed, which they did — the
new one checks the cell is a chroma wrapper and that the stylesheet has
rules to match.
e2e/diffweb_test.go +20
@@ -82,6 +82,15 @@ func TestDiffRendering(t *testing.T) {
8282 if !strings.Contains(body, "class=\"k\"") && !strings.Contains(body, "class=\"kd\"") {
8383 t.Error("diff content is not syntax highlighted")
8484 }
85 // Token classes alone prove nothing: chroma scopes every colour rule
86 // under .chroma, and the per-line markup has no wrapper of its own, so
87 // the cell has to be that wrapper or the classes are inert.
88 if !strings.Contains(body, `<td class="src chroma">`) {
89 t.Error("diff cell is not a chroma wrapper, so token classes go unstyled")
90 }
91 if !strings.Contains(stylesheet(t, inst), ".chroma .k") {
92 t.Error("stylesheet has no chroma token rules to match")
93 }
8594 // The +/- markers are CSS, so a copied selection is real source.
8695 if strings.Contains(body, `<td class="src">+`) {
8796 t.Error("diff markers are in the markup, not the stylesheet")
@@ -107,3 +116,14 @@ func jsonField(blob, name string) string {
107116 }
108117 return rest[:j]
109118 }
119
120// stylesheet fetches the served CSS, so a test can check that a rule the
121// markup depends on actually exists.
122func stylesheet(t *testing.T, inst *instance) string {
123 t.Helper()
124 status, body := inst.get(t, "/static/style.css")
125 if status != 200 {
126 t.Fatalf("stylesheet: %d", status)
127 }
128 return body
129}
internal/web/static/style.css +2 −2
@@ -917,8 +917,8 @@ details.difffold summary:hover { background: var(--fill-subtle); }
917917 summary .fpath { font-family: var(--mono); overflow-wrap: anywhere; }
918918 summary .fpath .was { color: var(--muted); }
919919 summary .fstat { margin-left: auto; font-family: var(--mono); white-space: nowrap; }
920details.difffold .add { color: var(--ok); }
921details.difffold .del { color: var(--bad); }
920details.difffold summary .add { color: var(--ok); }
921details.difffold summary .del { color: var(--bad); }
922922 details.difffold > .none { padding: var(--sp-3); margin: 0; }
923923 details.difffold .tablewrap { border-radius: 0 0 var(--r-md) var(--r-md); }
924924
internal/web/templates/layout.html +1 −1
@@ -128,7 +128,7 @@
128128 {{else}}<div class="tablewrap"><table class="difftable">
129129 {{range .Lines}}{{if eq .Class "hunk"}}<tr class="hunk"><td class="ln" colspan="2"></td><td class="src">{{.Text}}</td></tr>
130130 {{else if eq .Class "meta"}}<tr class="dmeta"><td class="ln" colspan="2"></td><td class="src">{{.Text}}</td></tr>
131 {{else}}<tr class="{{.Class}}"><td class="ln">{{if .OldLine}}{{.OldLine}}{{end}}</td><td class="ln">{{if .NewLine}}{{.NewLine}}{{end}}</td><td class="src">{{if .Code}}{{.Code}}{{else}}{{.Content}}{{end}}</td></tr>
131 {{else}}<tr class="{{.Class}}"><td class="ln">{{if .OldLine}}{{.OldLine}}{{end}}</td><td class="ln">{{if .NewLine}}{{.NewLine}}{{end}}</td><td class="src chroma">{{if .Code}}{{.Code}}{{else}}{{.Content}}{{end}}</td></tr>
132132 {{end}}{{range .Threads}}<tr class="threadrow"><td colspan="3"><div class="thread{{if .Resolved}} resolved{{end}}">{{if .Resolved}}<p class="threadstate">resolved by {{.Resolved}}</p>{{end}}{{range .Comments}}<p class="commenthead"><strong>{{.Author}}</strong> <span class="when">{{when .CreatedAt}}</span></p><div class="rendered">{{.BodyHTML}}</div>{{end}}{{template "threadact" dict "ID" .ID "Resolved" .Resolved "Base" $base "Can" $can}}</div></td></tr>
133133 {{end}}{{end}}
134134 </table></div>{{end}}