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
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"
|
|
}
|
|
|