mirror of
https://github.com/shazow/ssh-chat.git
synced 2025-04-12 23:27:17 +03:00
261 lines
5.1 KiB
Go
261 lines
5.1 KiB
Go
package message
|
|
|
|
import (
|
|
"fmt"
|
|
)
|
|
|
|
const (
|
|
// Reset resets the color
|
|
Reset = "\033[0m"
|
|
|
|
// Bold makes the following text bold
|
|
Bold = "\033[1m"
|
|
|
|
// Dim dims the following text
|
|
Dim = "\033[2m"
|
|
|
|
// Italic makes the following text italic
|
|
Italic = "\033[3m"
|
|
|
|
// Underline underlines the following text
|
|
Underline = "\033[4m"
|
|
|
|
// Blink blinks the following text
|
|
Blink = "\033[5m"
|
|
|
|
// Invert inverts the following text
|
|
Invert = "\033[7m"
|
|
|
|
// Newline
|
|
Newline = "\r\n"
|
|
|
|
// BEL
|
|
Bel = "\007"
|
|
)
|
|
|
|
// Interface for Styles
|
|
type Style interface {
|
|
String() string
|
|
Format(string) string
|
|
}
|
|
|
|
// General hardcoded style, mostly used as a crutch until we flesh out the
|
|
// framework to support backgrounds etc.
|
|
type style string
|
|
|
|
func (c style) String() string {
|
|
return string(c)
|
|
}
|
|
|
|
func (c style) Format(s string) string {
|
|
return c.String() + s + Reset
|
|
}
|
|
|
|
// 256 color type, for terminals who support it
|
|
type Color256 uint8
|
|
|
|
// String version of this color
|
|
func (c Color256) String() string {
|
|
return fmt.Sprintf("38;05;%d", c)
|
|
}
|
|
|
|
// Return formatted string with this color
|
|
func (c Color256) Format(s string) string {
|
|
return "\033[" + c.String() + "m" + s + Reset
|
|
}
|
|
|
|
func Color256Palette(colors ...uint8) *Palette {
|
|
size := len(colors)
|
|
p := make([]Style, 0, size)
|
|
for _, color := range colors {
|
|
p = append(p, Color256(color))
|
|
}
|
|
return &Palette{
|
|
colors: p,
|
|
size: size,
|
|
}
|
|
}
|
|
|
|
// No color, used for mono theme
|
|
type Color0 struct{}
|
|
|
|
// No-op for Color0
|
|
func (c Color0) String() string {
|
|
return ""
|
|
}
|
|
|
|
// No-op for Color0
|
|
func (c Color0) Format(s string) string {
|
|
return s
|
|
}
|
|
|
|
// Container for a collection of colors
|
|
type Palette struct {
|
|
colors []Style
|
|
size int
|
|
}
|
|
|
|
// Get a color by index, overflows are looped around.
|
|
func (p Palette) Get(i int) Style {
|
|
if p.size == 1 {
|
|
return p.colors[0]
|
|
}
|
|
return p.colors[i%(p.size-1)]
|
|
}
|
|
|
|
func (p Palette) Len() int {
|
|
return p.size
|
|
}
|
|
|
|
func (p Palette) String() string {
|
|
r := ""
|
|
for _, c := range p.colors {
|
|
r += c.Format("X")
|
|
}
|
|
return r
|
|
}
|
|
|
|
// Collection of settings for chat
|
|
type Theme struct {
|
|
id string
|
|
sys Style
|
|
pm Style
|
|
highlight Style
|
|
names *Palette
|
|
}
|
|
|
|
func (theme Theme) ID() string {
|
|
return theme.id
|
|
}
|
|
|
|
// Colorize name string given some index
|
|
func (theme Theme) ColorName(u *User) string {
|
|
if theme.names == nil {
|
|
return u.Name()
|
|
}
|
|
|
|
return theme.names.Get(u.colorIdx).Format(u.Name())
|
|
}
|
|
|
|
// Colorize the PM string
|
|
func (theme Theme) ColorPM(s string) string {
|
|
if theme.pm == nil {
|
|
return s
|
|
}
|
|
|
|
return theme.pm.Format(s)
|
|
}
|
|
|
|
// Colorize the Sys message
|
|
func (theme Theme) ColorSys(s string) string {
|
|
if theme.sys == nil {
|
|
return s
|
|
}
|
|
|
|
return theme.sys.Format(s)
|
|
}
|
|
|
|
// Highlight a matched string, usually name
|
|
func (theme Theme) Highlight(s string) string {
|
|
if theme.highlight == nil {
|
|
return s
|
|
}
|
|
return theme.highlight.Format(s)
|
|
}
|
|
|
|
// Timestamp colorizes the timestamp.
|
|
func (theme Theme) Timestamp(s string) string {
|
|
return theme.sys.Format(s)
|
|
}
|
|
|
|
// List of initialzied themes
|
|
var Themes []Theme
|
|
|
|
// Default theme to use
|
|
var DefaultTheme *Theme
|
|
|
|
func allColors256() *Palette {
|
|
colors := []uint8{}
|
|
var i uint8
|
|
for i = 0; i < 255; i++ {
|
|
colors = append(colors, i)
|
|
}
|
|
return Color256Palette(colors...)
|
|
}
|
|
|
|
func readableColors256() *Palette {
|
|
colors := []uint8{}
|
|
var i uint8
|
|
for i = 0; i < 255; i++ {
|
|
if i == 0 || i == 7 || i == 8 || i == 15 || i == 16 || i == 17 || i > 230 {
|
|
// Skip 31 Shades of Grey, and one hyperintelligent shade of blue.
|
|
continue
|
|
}
|
|
colors = append(colors, i)
|
|
}
|
|
return Color256Palette(colors...)
|
|
}
|
|
|
|
func init() {
|
|
Themes = []Theme{
|
|
{
|
|
id: "colors",
|
|
names: readableColors256(),
|
|
sys: Color256(245), // Grey
|
|
pm: Color256(7), // White
|
|
highlight: style(Bold + "\033[48;5;11m\033[38;5;16m"), // Yellow highlight
|
|
},
|
|
{
|
|
id: "solarized",
|
|
names: Color256Palette(1, 2, 3, 4, 5, 6, 7, 9, 13),
|
|
sys: Color256(11), // Yellow
|
|
pm: Color256(15), // White
|
|
highlight: style(Bold + "\033[48;5;3m\033[38;5;94m"), // Orange highlight
|
|
},
|
|
{
|
|
id: "hacker",
|
|
names: Color256Palette(82), // Green
|
|
sys: Color256(22), // Another green
|
|
pm: Color256(28), // More green, slightly lighter
|
|
highlight: style(Bold + "\033[48;5;22m\033[38;5;46m"), // Green on dark green
|
|
},
|
|
{
|
|
id: "mono",
|
|
},
|
|
}
|
|
|
|
DefaultTheme = &Themes[0]
|
|
|
|
/* Some debug helpers for your convenience:
|
|
|
|
// Debug for palettes
|
|
printPalette(allColors256())
|
|
|
|
// Debug for themes
|
|
for _, t := range Themes {
|
|
printTheme(t)
|
|
}
|
|
|
|
*/
|
|
}
|
|
|
|
func printTheme(t Theme) {
|
|
fmt.Println("Printing theme:", t.ID())
|
|
if t.names != nil {
|
|
for i, color := range t.names.colors {
|
|
fmt.Printf("%s ", color.Format(fmt.Sprintf("name%d", i)))
|
|
}
|
|
fmt.Println("")
|
|
}
|
|
fmt.Println(t.ColorSys("SystemMsg"))
|
|
fmt.Println(t.ColorPM("PrivateMsg"))
|
|
fmt.Println(t.Highlight("Highlight"))
|
|
fmt.Println("")
|
|
}
|
|
|
|
func printPalette(p *Palette) {
|
|
for i, color := range p.colors {
|
|
fmt.Printf("%d\t%s\n", i, color.Format(color.String()+" "))
|
|
}
|
|
}
|