themes

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 17, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package themes ports the desktop app's color schemes to the terminal: the registry of built-in themes, the --z-* tokens each one defines, and the custom themes users drop under <config>/themes. It knows nothing about how the terminal UI paints; it only resolves a selection to a palette.

Index

Constants

View Source
const CustomPrefix = "custom-"

CustomPrefix turns a custom theme's folder name into its theme id.

View Source
const DefaultID = "dark-hard"

DefaultID is the theme a fresh install starts on, as on the desktop.

View Source
const FamilyCustom = "custom"

FamilyCustom is the family of the themes users author themselves.

Variables

View Source
var Builtin = []Option{
	{ID: "apple-light", Label: "Apple · Light", Family: "apple"},
	{ID: "apple-dark", Label: "Apple · Dark", Family: "apple", Dark: true},

	{ID: "light-hard", Label: "Gruvbox · Light Hard", Family: "gruvbox", Variant: "hard"},
	{ID: "light-medium", Label: "Gruvbox · Light Medium", Family: "gruvbox", Variant: "medium"},
	{ID: "light-soft", Label: "Gruvbox · Light Soft", Family: "gruvbox", Variant: "soft"},
	{ID: "dark-hard", Label: "Gruvbox · Dark Hard", Family: "gruvbox", Dark: true, Variant: "hard"},
	{ID: "dark-medium", Label: "Gruvbox · Dark Medium", Family: "gruvbox", Dark: true, Variant: "medium"},
	{ID: "dark-soft", Label: "Gruvbox · Dark Soft", Family: "gruvbox", Dark: true, Variant: "soft"},

	{ID: "catppuccin-latte", Label: "Catppuccin · Latte", Family: "catppuccin", Variant: "latte"},
	{ID: "catppuccin-frappe", Label: "Catppuccin · Frappé", Family: "catppuccin", Dark: true, Variant: "frappe"},
	{ID: "catppuccin-macchiato", Label: "Catppuccin · Macchiato", Family: "catppuccin", Dark: true, Variant: "macchiato"},
	{ID: "catppuccin-mocha", Label: "Catppuccin · Mocha", Family: "catppuccin", Dark: true, Variant: "mocha"},

	{ID: "github-light", Label: "GitHub · Light", Family: "github", Variant: "default"},
	{ID: "github-light-high-contrast", Label: "GitHub · Light High Contrast", Family: "github", Variant: "high-contrast"},
	{ID: "github-dark", Label: "GitHub · Dark", Family: "github", Dark: true, Variant: "default"},
	{ID: "github-dark-dimmed", Label: "GitHub · Dark Dimmed", Family: "github", Dark: true, Variant: "dimmed"},
	{ID: "github-dark-high-contrast", Label: "GitHub · Dark High Contrast", Family: "github", Dark: true, Variant: "high-contrast"},

	{ID: "solarized-light", Label: "Solarized · Light", Family: "solarized"},
	{ID: "solarized-dark", Label: "Solarized · Dark", Family: "solarized", Dark: true},

	{ID: "one-light", Label: "One · Light", Family: "one"},
	{ID: "one-dark", Label: "One · Dark", Family: "one", Dark: true},

	{ID: "nord-light", Label: "Nord · Light", Family: "nord"},
	{ID: "nord-dark", Label: "Nord · Dark", Family: "nord", Dark: true},

	{ID: "tokyo-night-day", Label: "Tokyo Night · Day", Family: "tokyo-night"},
	{ID: "tokyo-night-storm", Label: "Tokyo Night · Storm", Family: "tokyo-night", Dark: true},

	{ID: "kanagawa-wave", Label: "Kanagawa · Wave", Family: "kanagawa", Dark: true, Variant: "wave"},
	{ID: "kanagawa-dragon", Label: "Kanagawa · Dragon", Family: "kanagawa", Dark: true, Variant: "dragon"},
	{ID: "kanagawa-paper-ink", Label: "Kanagawa · Paper Ink", Family: "kanagawa", Dark: true, Variant: "paper-ink"},
	{ID: "kanagawa-lotus", Label: "Kanagawa · Lotus", Family: "kanagawa", Variant: "lotus"},

	{ID: "black-metal", Label: "Black Metal · Black", Family: "black-metal", Dark: true},
	{ID: "black-metal-day", Label: "Black Metal · Day", Family: "black-metal"},

	{ID: "rose-pine-main", Label: "Rosé Pine · Main", Family: "rose-pine", Dark: true, Variant: "main"},
	{ID: "rose-pine-moon", Label: "Rosé Pine · Moon", Family: "rose-pine", Dark: true, Variant: "moon"},
	{ID: "rose-pine-dawn", Label: "Rosé Pine · Dawn", Family: "rose-pine", Variant: "dawn"},
}

Builtin mirrors THEMES in the desktop's lib/themes.ts, in its order.

View Source
var TokenNames = []string{
	"bg", "bg-softer", "bg-1", "bg-2", "bg-3", "bg-4",
	"fg", "fg-1", "fg-2",
	"grey-2", "grey-1", "grey-0", "grey-dim",
	"accent", "accent-soft", "accent-muted",
	"red", "green", "yellow", "blue", "purple", "aqua",
}

TokenNames lists the color tokens in the order the desktop writes them.

Functions

func Contrast

func Contrast(a, b RGB) float64

Contrast is the WCAG contrast ratio of two colors, from 1 to 21.

func CustomSlug

func CustomSlug(id string) (string, bool)

CustomSlug extracts the folder name from a `custom-<slug>` id.

func Families

func Families() []string

Families lists the built-in families in registry order.

func FlattenBuiltin

func FlattenBuiltin(desktopCSS, source string) (string, error)

FlattenBuiltin turns the desktop's stylesheet into the builtin.css this package embeds: one block per registry theme, every color token spelled out. On the desktop the tokens cascade (the bare :root holds Gruvbox Light, the three Gruvbox darks share a block, each variant overrides a few); flattening keeps that cascade out of the terminal. It fails when a registry theme is missing a token, so a desktop change cannot slip in half-applied. The gen command is its only caller.

func IsFamily

func IsFamily(name string) bool

IsFamily reports whether name is a built-in family.

func Luminance

func Luminance(c RGB) float64

Luminance is the WCAG relative luminance.

func NormalizeMode

func NormalizeMode(mode string) string

NormalizeMode maps a theme_mode onto light, dark or auto. The terminal has long called auto "system", so both names mean the same.

func ResolveAuto

func ResolveAuto(family string, dark bool, currentID string) string

ResolveAuto picks a family's light or dark variant, the desktop's resolveAuto: the current theme's variant carries across the mode flip (Gruvbox Hard stays Hard), else the family's canonical default wins.

Types

type Custom

type Custom struct {
	Slug string
	Name string
	// Modes is light, dark or both. A single-mode theme pins its mode.
	Modes string
	// contains filtered or unexported fields
}

Custom is a theme a user authored: a folder under <config>/themes holding a theme.css and, optionally, a manifest.json. The desktop app owns the format; the terminal reads the same folder.

func ListCustom

func ListCustom(dir string) []Custom

ListCustom returns every loadable theme folder, by name.

func LoadCustom

func LoadCustom(dir, slug string) (Custom, error)

LoadCustom reads one custom theme. The only hard requirement is a readable theme.css; a missing or broken manifest names the theme after its folder and assumes both modes.

func (Custom) ID

func (c Custom) ID() string

ID is the theme id the desktop saves for this theme.

func (Custom) Palette

func (c Custom) Palette(wantDark bool) Palette

Palette resolves the theme for the wanted mode. Unscoped rules apply to both modes; [data-theme-mode] rules are more specific, so they win over them whatever the order in the file.

type Option

type Option struct {
	ID      string
	Label   string
	Family  string
	Dark    bool
	Variant string
}

Option is one built-in theme variant, the desktop's ThemeOption.

func Find

func Find(id string) (Option, bool)

Find looks a built-in theme up by id.

type Palette

type Palette struct {
	ID     string
	Name   string
	Family string
	Dark   bool
	Tokens Tokens
}

Palette is a theme resolved to one mode.

func BuiltinPalette

func BuiltinPalette(id string) (Palette, error)

BuiltinPalette is the palette of a built-in theme.

func Resolve

func Resolve(sel Selection, systemDark bool, customDir string) (Palette, error)

Resolve turns a selection into the palette to draw with. systemDark answers "auto"; customDir is where custom themes live. A selection that cannot be honored (a custom theme that is gone) still returns a usable palette, together with the reason.

func (*Palette) ApplyTweaks

func (p *Palette) ApplyTweaks(tweaks map[string]string)

ApplyTweaks overlays the desktop's Quick tweaks ([tweaks] in config.toml): the accent and the six syntax hues, keyed by slug.

type RGB

type RGB struct{ R, G, B uint8 }

RGB is one opaque color.

func EnsureContrast

func EnsureContrast(fg, bg, anchor RGB, ratio float64) RGB

EnsureContrast nudges fg toward anchor until it reads against bg at the wanted ratio. Palettes tuned for a backlit app window keep their hue; only the colors a terminal would render too faint move, and only as far as needed.

func Mix

func Mix(a, b RGB, t float64) RGB

Mix blends linearly from a to b: t=0 is a, t=1 is b.

func ParseColor

func ParseColor(input string) (RGB, bool)

ParseColor reads `#rgb`, `#rrggbb`, `rgb(r, g, b)` or the bare `r g b` triplet the desktop's tokens are written in.

func (RGB) Hex

func (c RGB) Hex() string

Hex formats the color the way lipgloss takes it.

type Selection

type Selection struct {
	Family string // theme_family
	Mode   string // theme_mode: light | dark | auto
	ID     string // theme_id: a built-in id or custom-<slug>
}

Selection is what config.toml says about the theme: the three [appearance] keys the desktop app writes.

func Select

func Select(name string, current Selection, customDir string) (Selection, error)

Select reads what a user typed after `:theme`, or wrote in [terminal] theme, against the current selection: a mode, a family, a built-in id, or a custom theme by id or folder name.

type Tokens

type Tokens struct {
	Bg, BgSofter, Bg1, Bg2, Bg3, Bg4 RGB
	Fg, Fg1, Fg2                     RGB
	Grey2, Grey1, Grey0, GreyDim     RGB
	Accent, AccentSoft, AccentMuted  RGB
	Red, Green, Yellow, Blue, Purple RGB
	Aqua                             RGB
}

Tokens are the desktop's --z-* color tokens, one field per token.

Directories

Path Synopsis
Command gen rebuilds internal/themes/builtin.css from the desktop app's stylesheet.
Command gen rebuilds internal/themes/builtin.css from the desktop app's stylesheet.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL