1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
// Package theme is glint's single source of color truth. Every styled span in
// every theme gets an explicit foreground — no terminal-default fallbacks — so
// the editor reads cleanly on both light and dark terminals.
package theme
import "github.com/charmbracelet/lipgloss"
// Theme holds every color glint paints, plus its name and the glamour style the
// read-preview should use to stay visually in sync.
type Theme struct {
Name string
GlamourStyle string
// Markdown element colors.
Text lipgloss.Color // base prose
Emphasis lipgloss.Color // bold/italic — higher contrast than Text
Heading lipgloss.Color // heading text (bold)
Code lipgloss.Color // inline + fenced code
Link lipgloss.Color // links, URLs, and wikilink targets
Wikilink lipgloss.Color // retained == Link (kept for the all-colors check)
ListMarker lipgloss.Color // list bullets / numbers
Blockquote lipgloss.Color // blockquote marker + border (muted tone)
Comment lipgloss.Color // HTML / %% comments — visible, not dimmed
Accent lipgloss.Color // frontmatter keys, selection
Highlight lipgloss.Color // ==highlight== background tint
Spell lipgloss.Color // misspelled-word undercurl (red)
// UI colors.
Background lipgloss.Color
Muted lipgloss.Color // markup punctuation, dimmed
StatusFg lipgloss.Color
StatusBg lipgloss.Color
SelFg lipgloss.Color
SelBg lipgloss.Color
Pointer lipgloss.Color
}
// CycleOrder is the order Ctrl+T steps through themes.
var CycleOrder = []string{"flexoki-light", "flexoki-dark", "charm"}
func registry() map[string]Theme {
return map[string]Theme{
"flexoki-light": FlexokiLight(),
"flexoki-dark": FlexokiDark(),
"charm": Charm(),
}
}
// ByName looks up a registered theme.
func ByName(name string) (Theme, bool) {
t, ok := registry()[name]
return t, ok
}
// Next returns the theme after name in CycleOrder, wrapping around. An unknown
// name yields the first theme in the cycle.
func Next(name string) Theme {
idx := 0
for i, n := range CycleOrder {
if n == name {
idx = (i + 1) % len(CycleOrder)
break
}
}
t, _ := ByName(CycleOrder[idx])
return t
}
// Resolve picks a theme from a config value: "auto"/"" → OS detection; a known
// name → that theme; an unknown name → OS detection. It never errors and never
// returns an empty theme.
func Resolve(configValue string) Theme {
if configValue == "" || configValue == "auto" {
t, _ := ByName(Detect())
return t
}
if t, ok := ByName(configValue); ok {
return t
}
t, _ := ByName(Detect())
return t
}
|