▍ humdrum codex / glint v1.0.2
license AGPL-3.0
2.6 KB raw
 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
}