first commit

This commit is contained in:
2026-02-25 22:39:00 +03:00
commit 928d17af74
13 changed files with 1351 additions and 0 deletions

125
style/chalk.go Normal file
View File

@@ -0,0 +1,125 @@
package style
import (
"fmt"
"regexp"
"strconv"
"strings"
)
type Chalk struct {
enabled bool
codes []string
}
func New() Chalk {
return Chalk{enabled: true}
}
func Disabled() Chalk {
return Chalk{enabled: false}
}
func (c Chalk) WithEnabled(enabled bool) Chalk {
c.enabled = enabled
return c
}
func (c Chalk) cloneWith(code string) Chalk {
out := Chalk{enabled: c.enabled, codes: make([]string, 0, len(c.codes)+1)}
out.codes = append(out.codes, c.codes...)
out.codes = append(out.codes, code)
return out
}
func (c Chalk) code(v int) Chalk { return c.cloneWith(strconv.Itoa(v)) }
func (c Chalk) Bold() Chalk { return c.code(1) }
func (c Chalk) Dim() Chalk { return c.code(2) }
func (c Chalk) Italic() Chalk { return c.code(3) }
func (c Chalk) Underline() Chalk { return c.code(4) }
func (c Chalk) Inverse() Chalk { return c.code(7) }
func (c Chalk) Strikethrough() Chalk { return c.code(9) }
func (c Chalk) Black() Chalk { return c.code(30) }
func (c Chalk) Red() Chalk { return c.code(31) }
func (c Chalk) Green() Chalk { return c.code(32) }
func (c Chalk) Yellow() Chalk { return c.code(33) }
func (c Chalk) Blue() Chalk { return c.code(34) }
func (c Chalk) Magenta() Chalk { return c.code(35) }
func (c Chalk) Cyan() Chalk { return c.code(36) }
func (c Chalk) White() Chalk { return c.code(37) }
func (c Chalk) Gray() Chalk { return c.code(90) }
func (c Chalk) BrightBlack() Chalk { return c.code(90) }
func (c Chalk) BrightRed() Chalk { return c.code(91) }
func (c Chalk) BrightGreen() Chalk { return c.code(92) }
func (c Chalk) BrightYellow() Chalk { return c.code(93) }
func (c Chalk) BrightBlue() Chalk { return c.code(94) }
func (c Chalk) BrightMagenta() Chalk { return c.code(95) }
func (c Chalk) BrightCyan() Chalk { return c.code(96) }
func (c Chalk) BrightWhite() Chalk { return c.code(97) }
func (c Chalk) BgBlack() Chalk { return c.code(40) }
func (c Chalk) BgRed() Chalk { return c.code(41) }
func (c Chalk) BgGreen() Chalk { return c.code(42) }
func (c Chalk) BgYellow() Chalk { return c.code(43) }
func (c Chalk) BgBlue() Chalk { return c.code(44) }
func (c Chalk) BgMagenta() Chalk { return c.code(45) }
func (c Chalk) BgCyan() Chalk { return c.code(46) }
func (c Chalk) BgWhite() Chalk { return c.code(47) }
func (c Chalk) RGB(r, g, b uint8) Chalk {
return c.cloneWith(fmt.Sprintf("38;2;%d;%d;%d", r, g, b))
}
func (c Chalk) BgRGB(r, g, b uint8) Chalk {
return c.cloneWith(fmt.Sprintf("48;2;%d;%d;%d", r, g, b))
}
func (c Chalk) Hex(hex string) Chalk {
if r, g, b, ok := parseHexColor(hex); ok {
return c.RGB(r, g, b)
}
return c
}
func (c Chalk) BgHex(hex string) Chalk {
if r, g, b, ok := parseHexColor(hex); ok {
return c.BgRGB(r, g, b)
}
return c
}
func (c Chalk) Wrap(text string) string {
if !c.enabled || len(c.codes) == 0 || text == "" {
return text
}
return "\x1b[" + strings.Join(c.codes, ";") + "m" + text + "\x1b[0m"
}
func (c Chalk) Sprint(v ...any) string {
return c.Wrap(fmt.Sprint(v...))
}
func (c Chalk) Sprintf(format string, v ...any) string {
return c.Wrap(fmt.Sprintf(format, v...))
}
var ansiPattern = regexp.MustCompile(`\x1b\[[0-9;]*m`)
func StripANSI(s string) string {
return ansiPattern.ReplaceAllString(s, "")
}
func parseHexColor(hex string) (uint8, uint8, uint8, bool) {
h := strings.TrimSpace(strings.TrimPrefix(hex, "#"))
if len(h) != 6 {
return 0, 0, 0, false
}
v, err := strconv.ParseUint(h, 16, 32)
if err != nil {
return 0, 0, 0, false
}
return uint8(v >> 16), uint8((v >> 8) & 0xff), uint8(v & 0xff), true
}

59
style/theme.go Normal file
View File

@@ -0,0 +1,59 @@
package style
type Theme struct {
TimeKey Chalk
TimeValue Chalk
MsgKey Chalk
Debug Chalk
Info Chalk
Warn Chalk
Error Chalk
ErrKey Chalk
PlayerKey Chalk
WorldKey Chalk
}
func DefaultTheme() Theme {
return Theme{
TimeKey: New().Gray(),
TimeValue: New().BrightBlue(),
MsgKey: New().BrightWhite(),
Debug: New().Black().BgCyan().Bold(),
Info: New().Black().BgHex("#40E0D0").Bold(),
Warn: New().Black().BgYellow().Bold(),
Error: New().White().BgRed().Bold(),
ErrKey: New().White().BgRed().Bold(),
PlayerKey: New().BrightCyan(),
WorldKey: New().Magenta(),
}
}
func NordTheme() Theme {
return Theme{
TimeKey: New().Hex("#81A1C1"),
TimeValue: New().Hex("#88C0D0"),
MsgKey: New().Hex("#ECEFF4").Bold(),
Debug: New().Black().BgHex("#88C0D0").Bold(),
Info: New().Black().BgHex("#8FBCBB").Bold(),
Warn: New().Black().BgHex("#EBCB8B").Bold(),
Error: New().Hex("#ECEFF4").BgHex("#BF616A").Bold(),
ErrKey: New().Hex("#ECEFF4").BgHex("#D08770").Bold(),
PlayerKey: New().Hex("#B48EAD"),
WorldKey: New().Hex("#5E81AC"),
}
}
func SunsetTheme() Theme {
return Theme{
TimeKey: New().Hex("#F8C8DC"),
TimeValue: New().Hex("#F4A261"),
MsgKey: New().Hex("#FFF1E6"),
Debug: New().Black().BgHex("#9BF6FF").Bold(),
Info: New().Black().BgHex("#70E0C0").Bold(),
Warn: New().Black().BgHex("#FFD166").Bold(),
Error: New().Hex("#FFF1E6").BgHex("#FF6B6B").Bold(),
ErrKey: New().Hex("#FFF1E6").BgHex("#FF8FA3").Bold(),
PlayerKey: New().Hex("#CDB4DB"),
WorldKey: New().Hex("#A0C4FF"),
}
}