tca-go

March 1, 2026 · View on GitHub

Go library for loading and using TCA terminal color themes.

Load TCA themes and resolve their colors in your Go terminal applications. Includes optional Lipgloss integration for ready-to-use styles.

Installation

go get github.com/carmiac/tca-go

Usage

Shared Theme Directory

TCA uses a shared directory for themes:

  • Linux/BSD: $XDG_DATA_HOME/tca/themes (default: ~/.local/share/tca/themes)
  • macOS: ~/Library/Application Support/tca/themes
  • Windows: %APPDATA%\tca\themes

Themes in this directory can be loaded by name from anywhere.

Basic Usage

package main

import (
	"fmt"
	"log"

	tca "github.com/carmiac/tca-go"
	"github.com/charmbracelet/lipgloss"
)

func main() {
	// Load from shared directory by name
	theme, err := tca.LoadTheme("dracula")
	if err != nil {
		log.Fatal(err)
	}
	
	// Or load from explicit path
	theme, err = tca.LoadTheme("/path/to/theme.toml")
	if err != nil {
		log.Fatal(err)
	}

	// Or parse directly from bytes (useful for embedded FS, HTTP responses, etc.)
	// theme, err := tca.ParseTheme(data)

	// Create application styles (includes semantic + UI colors)
	styles, err := theme.NewStyles()
	if err != nil {
		log.Fatal(err)
	}

	// Use semantic color styles
	fmt.Println(styles.Error.Render("✗ Error message"))
	fmt.Println(styles.Warning.Render("⚠ Warning message"))
	fmt.Println(styles.Success.Render("✓ Success message"))
	fmt.Println(styles.Info.Render("ℹ Info message"))
	fmt.Println(styles.Highlight.Render("★ Highlighted text"))
	fmt.Println(styles.Link.Render("🔗 Link text"))

	// Get ANSI colors as styles
	ansiStyles, _ := theme.NewANSIStyles()
	fmt.Println(ansiStyles.Red.Render("Red text"))
	fmt.Println(ansiStyles.BrightGreen.Render("Bright green text"))

	// Use UI element styles
	fmt.Println(styles.Title.Render("Title"))
	fmt.Println(styles.Subtitle.Render("Subtitle"))
	fmt.Println(styles.Muted.Render("Muted text"))

	// Use custom colors from palette
	color, _ := theme.Resolve("palette.blue.3")
	customStyle := lipgloss.NewStyle().Foreground(tca.ToLipglossColor(color))
	fmt.Println(customStyle.Render("Custom colored text"))
}

Loading All Themes from a Directory

entries, errs := tca.LoadThemesFromDir("/path/to/themes")
for _, e := range errs {
    log.Printf("warning: %v", e) // bad files are skipped, not fatal
}
for _, e := range entries {
    fmt.Println(e.Theme.Meta.Name, e.Path)
}

Listing Available Themes

package main

import (
	"fmt"
	tca "github.com/carmiac/tca-go"
)

func main() {
	// Get themes directory
	themesDir, _ := tca.GetThemesDir()
	fmt.Println("Themes directory:", themesDir)
	
	// List all available themes
	themes, _ := tca.ListThemeNames()
	for _, name := range themes {
		fmt.Println("  -", name)
	}
}

Checking Dark/Light Mode

// Explicit: reads theme.meta.dark from the TOML file
// Auto-detect: compares luminance of ui.bg.primary vs ui.fg.primary
if theme.IsDark() {
    fmt.Println("dark theme")
}

Palette Ramps

// Get a named palette ramp as resolved hex strings
ramp, err := theme.GetPaletteRamp("neutral")
// ramp = ["#000000", "#404040", "#808080", "#c0c0c0", "#ffffff"]

Styles Struct

The NewStyles() method returns a complete Styles struct with all semantic and UI colors:

styles, _ := theme.NewStyles()

// Semantic color styles
styles.Error      // Error messages
styles.Warning    // Warnings
styles.Success    // Success messages
styles.Info       // Informational messages
styles.Highlight  // Highlighted text
styles.Link       // Links

// UI element styles
styles.Title      // Primary foreground, bold
styles.Subtitle   // Primary foreground
styles.Muted      // Muted foreground
styles.Border     // Border color
styles.Background // Background with padding

ANSI Colors

Get all 16 ANSI colors as pre-configured Lipgloss styles:

ansiStyles, _ := theme.NewANSIStyles()

// Normal colors
ansiStyles.Black
ansiStyles.Red
ansiStyles.Green
ansiStyles.Yellow
ansiStyles.Blue
ansiStyles.Magenta
ansiStyles.Cyan
ansiStyles.White

// Bright colors
ansiStyles.BrightBlack
ansiStyles.BrightRed
ansiStyles.BrightGreen
ansiStyles.BrightYellow
ansiStyles.BrightBlue
ansiStyles.BrightMagenta
ansiStyles.BrightCyan
ansiStyles.BrightWhite

Direct Color Resolution

Resolve colors to hex strings for custom styling:

// Resolve all ANSI colors at once
ansi, _ := theme.ResolveANSI()
fmt.Println(ansi.Red)   // "#ff5555"

// Resolve all semantic colors
semantic, _ := theme.ResolveSemantic()
fmt.Println(semantic.Error)    // "#ff5555"
fmt.Println(semantic.Success)  // "#50fa7b"

// Resolve all UI colors
ui, _ := theme.ResolveUI()
fmt.Println(ui.BGPrimary)      // "#282a36"
fmt.Println(ui.FGPrimary)      // "#f8f8f2"

// Resolve any palette reference
hexColor, _ := theme.Resolve("palette.blue.3")

Examples

See the examples directory:

# Preview a single theme
go run ./examples/basic path/to/theme.toml

# List all themes in a directory
go run ./examples/basic path/to/themes/

# Interactive theme picker (← / → to navigate, q to quit)
go run ./examples/theme-picker path/to/themes/

API Reference

Loader Functions

  • LoadThemesFromDir(dir string) ([]ThemeEntry, []error) - Load all .toml themes from a directory; bad files are skipped
  • GetDataDir() (string, error) - Get TCA data directory path (creates if absent)
  • GetThemesDir() (string, error) - Get themes directory path (creates if absent)
  • DataDirPath() string - Get TCA data directory path (no side effects)
  • ThemesDirPath() string - Get themes directory path (no side effects)
  • ListThemes() ([]string, error) - List all theme file paths
  • ListThemeNames() ([]string, error) - List theme names (without extensions)
  • FindTheme(name string) (string, error) - Find theme by name
  • LoadThemeFile(pathOrName string) (string, error) - Find theme file path
  • LoadTheme(pathOrName string) (*Theme, error) - Load and parse theme from file
  • ParseTheme(data []byte) (*Theme, error) - Parse theme from bytes
  • ReadTheme(r io.Reader) (*Theme, error) - Parse theme from reader

Theme Loading

Type Definitions

Theme types with all fields properly structured:

// Theme metadata
type ThemeMeta struct {
    Name, Slug, Author, Version, Description string
    Dark *bool  // nil = not set; use IsDark() for dark/light detection
}
type ANSI struct {
    Black, Red, Green, Yellow, Blue, Magenta, Cyan, White         string
    BrightBlack, BrightRed, BrightGreen, BrightYellow,
    BrightBlue, BrightMagenta, BrightCyan, BrightWhite           string
}

// Semantic colors
type Semantic struct {
    Error, Warning, Info, Success, Highlight, Link                string
}

// UI colors (nested structs matching TOML layout)
type UI struct {
    BG        UIBackground  // primary, secondary
    FG        UIForeground  // primary, secondary, muted
    Border    UIBorder      // primary, muted
    Cursor    UICursor      // primary, muted
    Selection UISelection   // bg, fg
}

// Base16 colors
type Base16 struct {
    Base00, Base01, Base02, Base03, Base04, Base05, Base06, Base07 string
    Base08, Base09, Base0A, Base0B, Base0C, Base0D, Base0E, Base0F string
}

Color Resolution

Methods that return structured color data:

  • IsDark() bool - Report whether the theme is dark (explicit TOML field, or auto-detected via luminance)
  • GetPaletteRamp(name string) ([]string, error) - Get resolved hex strings for a named palette ramp
  • Resolve(ref string) (string, error) - Resolve palette reference to hex string (e.g., "palette.blue.3")
  • ResolveANSI() (*ResolvedANSI, error) - Resolve all 16 ANSI colors to hex strings
  • ResolveSemantic() (*ResolvedSemantic, error) - Resolve all 6 semantic colors to hex strings
  • ResolveUI() (*ResolvedUI, error) - Resolve all 11 UI colors to hex strings

Lipgloss Integration

High-level methods that return ready-to-use Lipgloss styles:

  • NewStyles() (*Styles, error) - Create complete application styles (semantic + UI)
  • NewANSIStyles() (*ANSIStyles, error) - Get all 16 ANSI colors as Lipgloss styles
  • ToLipglossColor(hex string) lipgloss.Color - Convert hex string to Lipgloss color

TCA Specification

For the full TCA specification and theme format, see the tca-themes repository.

License

MIT