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 ¶
Color is a color of a style entry. The zero Color is not set.
func (Color) RGB ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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.
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.
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 ¶
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 ¶
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 ¶
Background returns the background of the style, which is the background of the default entry.