styles

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Oct 2, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package styles holds the styles of transit, which give a color and a font to each capture name of a highlight query (D65). rline and usql take their colors from it, so that the two draw the same code in the same colors.

A style is one JSON file, and the package embeds the files. The files in chroma/ are the styles of chroma, which the command test/cmd/chromastyles of the test module converts. The files in themes/ are styles that a person makes by hand. A consumer can read a style file of its own with Parse.

A style file has four keys:

{
  "name": "monokai",
  "source": "chroma v2.27.0 styles/monokai.xml (MIT), taken from Pygments (BSD-2-Clause)",
  "default": "#f8f8f2 bg:#272822",
  "captures": {
    "comment": "#75715e",
    "keyword": "#66d9ef",
    "keyword.import": "#f92672"
  }
}

Each value is a style string, a subset of the style strings of chroma. ParseEntry describes the words. Lookup gives the entry of a capture name. It tries the whole name, then each shorter prefix by dots, and then the default entry. An entry is whole. It takes nothing from the entry of a prefix.

The background of the default entry is the background of the style. Lookup does not give it, because a line editor usually keeps the background of the terminal. A consumer that draws the background uses Background for each entry that has no background of its own.

A color keeps the kind that the file writes: one of the 16 ANSI colors, one of the 256 colors of a terminal, or an RGB color. The consumer chooses the color depth of its terminal, and it reduces a color with To256 or To16. The package does not look at the terminal.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Names

func Names() []string

Names returns the names of the bundled styles, sorted.

Example

This example lists the names of the bundled styles, which come sorted.

package main

import (
	"fmt"
	"slices"

	"github.com/xo/transit/styles"
)

func main() {
	names := styles.Names()
	fmt.Println(slices.Contains(names, "monokai"), slices.IsSorted(names))
}
Output:
true true

Types

type Color

type Color struct {
	Kind  ColorKind
	Value uint32
}

Color is a color of a style entry. The zero Color is not set.

func (Color) IsSet

func (c Color) IsSet() bool

IsSet reports whether the color is set.

func (Color) RGB

func (c Color) RGB() (r, g, b uint8)

RGB returns the red, green and blue parts of the color. An ANSI color and one of the 256 colors take the values of the default palette of xterm. A color that is not set is black.

func (Color) String

func (c Color) String() string

String returns the color as a style string writes it: #rrggbb, #ansi and the name of an ANSI color, or #ansi and the number of one of the 256 colors. It returns "" for a color that is not set.

func (Color) To16

func (c Color) To16() Color

To16 reduces the color to the 16 ANSI colors. One of the first 16 of the 256 colors becomes the ANSI color of the same number. Another of the 256 colors and an RGB color become the nearest ANSI color in the default palette of xterm. An ANSI color and a color that is not set come back as they are.

Example

This example reduces an RGB color, and one of the 256 colors, for a terminal of 16 colors.

package main

import (
	"fmt"
	"log"

	"github.com/xo/transit/styles"
)

func main() {
	e, err := styles.ParseEntry("#f92672 bg:#ansi236")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(e.Fg, e.Fg.To16())
	fmt.Println(e.Bg, e.Bg.To16())
}
Output:
#f92672 #ansipurple
#ansi236 #ansiblack

func (Color) To256

func (c Color) To256() Color

To256 reduces the color to the 256 colors of a terminal. An RGB color becomes the nearest of the colors 16 to 255, because a terminal can change the first 16. Any other color comes back as it is.

Example

This example reduces an RGB color for a terminal of 256 colors.

package main

import (
	"fmt"
	"log"

	"github.com/xo/transit/styles"
)

func main() {
	e, err := styles.ParseEntry("#f92672")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(e.Fg, e.Fg.To256())
}
Output:
#f92672 #ansi197

type ColorKind

type ColorKind uint8

ColorKind is the kind of a color: none, one of the 16 ANSI colors, one of the 256 colors of a terminal, or an RGB color.

const (
	// ColorNone is the kind of a color that is not set.
	ColorNone ColorKind = iota
	// ColorANSI is one of the 16 ANSI colors. Its value is 0 to 15.
	ColorANSI
	// Color256 is one of the 256 colors of a terminal. Its value is 0 to
	// 255.
	Color256
	// ColorRGB is an RGB color. Its value is 0xrrggbb.
	ColorRGB
)

The kinds of a color.

type Entry

type Entry struct {
	Fg        Color
	Bg        Color
	Bold      bool
	Italic    bool
	Underline bool
}

Entry is the style of one capture name: a foreground color, a background color, and the font. An entry is whole. A field that it leaves out does not come from another entry.

func ParseEntry

func ParseEntry(s string) (Entry, error)

ParseEntry reads a style string. The words of the string are separated by spaces, and a later word wins over an earlier one. A word is one of these:

  • bold, italic or underline, which turns the font on
  • nobold, noitalic or nounderline, which turns it off
  • a color, which is the foreground color
  • bg: and a color, which is the background color

A color is #rgb or #rrggbb, #ansi and the name of one of the 16 ANSI colors of chroma, such as #ansired or #ansidarkblue, or #ansi and the number of one of the 256 colors of a terminal, such as #ansi208. The empty string is the zero Entry.

func (Entry) String

func (e Entry) String() string

String returns the entry as a style string, in the order of chroma: the font, the foreground color, and the background color. ParseEntry reads it back to the same entry.

type Error

type Error string

Error is an error of the package.

const ErrSyntax Error = "invalid style"

ErrSyntax is the error of a style string or a style file that the package cannot read. The error that comes back wraps it, and says what is wrong.

func (Error) Error

func (e Error) Error() string

Error returns the text of the error.

type Style

type Style struct {
	// Name is the name of the style, such as "monokai".
	Name string
	// Source says where the colors of the style come from, and under which
	// license.
	Source string
	// Default is the entry of text that no capture names. Its background is
	// the background of the style.
	Default Entry
	// Captures holds the entry of each capture name that the style gives.
	Captures map[string]Entry
}

Style is a style: an entry for each capture name that it gives, and the default entry.

func Get

func Get(name string) (*Style, bool)

Get returns the bundled style of a name, such as "monokai". It returns false when the package has no style of that name. Each call reads the file again, so the caller can change the style that comes back.

Example

This example gets a bundled style, and finds the entry of some capture names of a highlight query. A name that the style gives, such as keyword.operator, has its own entry. A name that the style does not give, such as keyword.function.builtin, takes the entry of its longest prefix. A name with no prefix in the style takes the default entry without its background, because a line editor keeps the background of the terminal.

package main

import (
	"fmt"
	"log"

	"github.com/xo/transit/styles"
)

func main() {
	style, ok := styles.Get("monokai")
	if !ok {
		log.Fatal("no style monokai")
	}
	for _, capture := range []string{"keyword", "keyword.operator", "keyword.function.builtin", "string", "no.such.name"} {
		fmt.Printf("%-25s %s\n", capture, style.Lookup(capture))
	}
	fmt.Println("background", style.Background())
}
Output:
keyword                   #66d9ef
keyword.operator          #f92672
keyword.function.builtin  #66d9ef
string                    #e6db74
no.such.name              #f8f8f2
background #272822

func Parse

func Parse(data []byte) (*Style, error)

Parse reads a style file. The file is a JSON object with the keys name, source, default and captures. The name must not be empty, and each value of default and captures is a style string that ParseEntry reads.

Example

This example reads a style file of a user. The file has the form of a bundled style. Each value is a style string, which ParseEntry reads.

package main

import (
	"fmt"
	"log"

	"github.com/xo/transit/styles"
)

func main() {
	data := []byte(`{
  "name": "mine",
  "source": "made by hand",
  "default": "#d0d0d0 bg:#1c1c1c",
  "captures": {
    "comment": "italic #808080",
    "keyword": "bold #ansiblue",
    "string": "#ansi114",
    "error": "#ffffff bg:#d70000"
  }
}`)
	style, err := styles.Parse(data)
	if err != nil {
		log.Fatal(err)
	}
	for _, capture := range []string{"comment", "keyword.operator", "string.special.key", "error", "variable"} {
		fmt.Printf("%-18s %s\n", capture, style.Lookup(capture))
	}
}
Output:
comment            italic #808080
keyword.operator   bold #ansiblue
string.special.key #ansi114
error              #ffffff bg:#d70000
variable           #d0d0d0

func (*Style) Background

func (s *Style) Background() Color

Background returns the background of the style, which is the background of the default entry.

func (*Style) Lookup

func (s *Style) Lookup(capture string) Entry

Lookup returns the entry of a capture name, such as "keyword.function". It tries the whole name, then each shorter prefix by dots, such as "keyword", and then the default entry. It leaves out the background of the default entry, which is the background of the style.

Jump to

Keyboard shortcuts

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