You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
1.6 KiB

package style
import (
"errors"
"fmt"
"strings"
"sync"
)
//nolint: gochecknoglobals
var (
styles = map[string]Style{
"error": {Foreground: White, Background: Red},
"info": {Foreground: Green},
"comment": {Foreground: Yellow},
"question": {Foreground: Black, Background: Cyan},
}
stylesMu sync.Mutex
empty = Style{}
)
var (
ErrNotFound = errors.New("console: style not found")
ErrDuplicateStyle = errors.New("console: Register called twice")
)
func Empty() Style {
return empty
}
func Find(name string) (Style, error) {
if st, has := styles[name]; has {
return st, nil
}
return empty, ErrNotFound
}
func Register(name string, style Style) error {
stylesMu.Lock()
defer stylesMu.Unlock()
if _, has := styles[name]; has {
return fmt.Errorf("%w for style %s", ErrDuplicateStyle, name)
}
styles[name] = style
return nil
}
func MustRegister(name string, style Style) {
if err := Register(name, style); err != nil {
panic(err)
}
}
type Style struct {
Background Color
Foreground Color
Options []Option
}
func (s Style) Apply(msg string) string {
return s.Set(ActionSet) + msg + s.Set(ActionUnset)
}
func (s Style) Set(action int) string {
style := make([]string, 0, len(s.Options))
if s.Foreground != "" {
style = append(style, "3"+s.Foreground.Apply(action))
}
if s.Background != "" {
style = append(style, "4"+s.Background.Apply(action))
}
for _, opt := range s.Options {
style = append(style, opt.Apply(action))
}
if len(style) == 0 {
return ""
}
return "\033[" + strings.Join(style, ";") + "m"
}