main e86dbd6

chroma-css.go RawHistoryFolder

1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3//go:build ignore
4
5// chroma-css writes internal/adapters/web/static/css/56-chroma.css: the
6// chroma token classes mapped to the --syn-* custom properties of the design
7// tokens (the Despair hues, dark and light). Colours are not in the file, so
8// the theme follows the colour scheme; only bold and italic come from chroma
9// (its "bw" style, as in the mockup).
10//
11//	go run scripts/chroma-css.go > internal/adapters/web/static/css/56-chroma.css
12package main
13
14import (
15	"fmt"
16	"os"
17	"sort"
18	"strings"
19
20	"github.com/alecthomas/chroma/v2"
21	"github.com/alecthomas/chroma/v2/formatters/html"
22	"github.com/alecthomas/chroma/v2/styles"
23)
24
25// synVar maps a token type to the name of a --syn-* property, "" for none.
26func synVar(t chroma.TokenType) string {
27	switch {
28	case t == chroma.KeywordType, t == chroma.NameClass, t == chroma.NameBuiltin, t == chroma.NameBuiltinPseudo,
29		t == chroma.NameException, t == chroma.NameNamespace:
30		return "type"
31	case t.InCategory(chroma.Keyword):
32		return "keyword"
33	case t.InSubCategory(chroma.LiteralString):
34		return "string"
35	case t.InCategory(chroma.Comment):
36		return "comment"
37	case t.InSubCategory(chroma.LiteralNumber):
38		return "number"
39	case t.InSubCategory(chroma.NameFunction), t == chroma.NameDecorator:
40		return "func"
41	case t.InCategory(chroma.Punctuation), t.InCategory(chroma.Operator):
42		return "punct"
43	}
44	return ""
45}
46
47func main() {
48	// Learn the classes chroma emits, so that every one is covered.
49	var learned strings.Builder
50	if err := html.New(html.WithClasses(true)).WriteCSS(&learned, styles.Get("bw")); err != nil {
51		fmt.Fprintln(os.Stderr, err)
52		os.Exit(1)
53	}
54	types := map[string]chroma.TokenType{}
55	for t, c := range chroma.StandardTypes {
56		if c != "" && t > 0 {
57			types[c] = t
58		}
59	}
60	bw := styles.Get("bw")
61	var classes []string
62	for _, l := range strings.Split(learned.String(), "\n") {
63		i := strings.Index(l, ".chroma .")
64		if i < 0 {
65			continue
66		}
67		c := l[i+len(".chroma ."):]
68		c = c[:strings.IndexAny(c, " {")]
69		if t, ok := types[c]; ok && synVar(t) != "" {
70			classes = append(classes, c)
71		}
72	}
73	sort.Strings(classes)
74
75	fmt.Println("/* Syntax colours of the code view. Generated by scripts/chroma-css.go from")
76	fmt.Println("   chroma's token classes; the colours are the --syn-* properties of")
77	fmt.Println("   00-tokens.css (the Despair hues, dark and light), none is defined here. */")
78	fmt.Println("@layer components {")
79	fmt.Println("  .chroma { color: var(--syn-plain); }")
80	for _, c := range classes {
81		t := types[c]
82		decl := "color: var(--syn-" + synVar(t) + ")"
83		e := bw.Get(t)
84		if e.Bold == chroma.Yes {
85			decl += "; font-weight: bold"
86		}
87		if e.Italic == chroma.Yes {
88			decl += "; font-style: italic"
89		}
90		fmt.Printf("  .chroma .%s { %s }\n", c, decl)
91	}
92	fmt.Println("  .chroma .line { display: block; }")
93	fmt.Println(`
94  /* an invisible character in code, shown instead of applied (Trojan Source) */
95  .chroma .ctl {
96    color: var(--red); font-weight: bold; font-style: normal; font-size: var(--fs-s);
97    outline: 1px solid var(--red); outline-offset: -1px; padding: 0 .25ch;
98  }
99  .img-view { margin-top: var(--lh); & img { max-width: 100%; height: auto; } }
100}`)
101}

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 42

↑↓ moveenter openesc close