chat.Color->chat.Style, highlighting works.

This commit is contained in:
Andrey Petrov 2015-01-17 13:26:26 -08:00
parent 3c4e6994c2
commit 838285ba43
4 changed files with 75 additions and 20 deletions

View File

@ -2,6 +2,7 @@ package chat
import (
"fmt"
"regexp"
"strings"
"time"
)
@ -101,6 +102,15 @@ func (m *PublicMsg) Render(t *Theme) string {
return fmt.Sprintf("%s: %s", t.ColorName(m.from), m.body)
}
func (m *PublicMsg) RenderHighlighted(t *Theme, highlight *regexp.Regexp) string {
if highlight == nil || t == nil {
return m.Render(t)
}
body := highlight.ReplaceAllString(m.body, t.Highlight("${1}"))
return fmt.Sprintf("%s: %s", t.ColorName(m.from), body)
}
func (m *PublicMsg) String() string {
return fmt.Sprintf("%s: %s", m.from.Name(), m.body)
}
@ -212,7 +222,7 @@ type CommandMsg struct {
*PublicMsg
command string
args []string
room *Room
room *Room
}
func (m *CommandMsg) Command() string {

View File

@ -28,12 +28,24 @@ const (
Newline = "\r\n"
)
// Interface for Colors
type Color interface {
// 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
@ -62,12 +74,12 @@ func (c Color0) Format(s string) string {
// Container for a collection of colors
type Palette struct {
colors []Color
colors []Style
size int
}
// Get a color by index, overflows are looped around.
func (p Palette) Get(i int) Color {
func (p Palette) Get(i int) Style {
return p.colors[i%(p.size-1)]
}
@ -85,10 +97,11 @@ func (p Palette) String() string {
// Collection of settings for chat
type Theme struct {
id string
sys Color
pm Color
names *Palette
id string
sys Style
pm Style
highlight Style
names *Palette
}
func (t Theme) Id() string {
@ -122,6 +135,14 @@ func (t Theme) ColorSys(s string) string {
return t.sys.Format(s)
}
// Highlight a matched string, usually name
func (t Theme) Highlight(s string) string {
if t.highlight == nil {
return s
}
return t.highlight.Format(s)
}
// List of initialzied themes
var Themes []Theme
@ -131,7 +152,7 @@ var DefaultTheme *Theme
func readableColors256() *Palette {
size := 247
p := Palette{
colors: make([]Color, size),
colors: make([]Style, size),
size: size,
}
j := 0
@ -151,10 +172,11 @@ func init() {
Themes = []Theme{
Theme{
id: "colors",
names: palette,
sys: palette.Get(8), // Grey
pm: palette.Get(7), // White
id: "colors",
names: palette,
sys: palette.Get(8), // Grey
pm: palette.Get(7), // White
highlight: style(Bold + "\033[48;5;11m\033[38;5;16m"), // Yellow highlight
},
Theme{
id: "mono",

View File

@ -2,13 +2,16 @@ package chat
import (
"errors"
"fmt"
"io"
"math/rand"
"regexp"
"sync"
"time"
)
const messageBuffer = 20
const reHighlight = `\b(%s)\b`
var ErrUserClosed = errors.New("user closed")
@ -100,9 +103,28 @@ func (u *User) ConsumeOne(out io.Writer) {
u.HandleMsg(<-u.msg, out)
}
// SetHighlight sets the highlighting regular expression to match string.
func (u *User) SetHighlight(s string) error {
re, err := regexp.Compile(fmt.Sprintf(reHighlight, s))
if err != nil {
return err
}
u.Config.Highlight = re
return nil
}
func (u User) render(m Message) string {
switch m := m.(type) {
case *PublicMsg:
return m.RenderHighlighted(u.Config.Theme, u.Config.Highlight) + Newline
default:
return m.Render(u.Config.Theme) + Newline
}
}
func (u *User) HandleMsg(m Message, out io.Writer) {
s := m.Render(u.Config.Theme)
_, err := out.Write([]byte(s + Newline))
r := u.render(m)
_, err := out.Write([]byte(r))
if err != nil {
logger.Printf("Write failed to %s, closing: %s", u.Name(), err)
u.Close()
@ -127,7 +149,7 @@ func (u *User) Send(m Message) error {
// Container for per-user configurations.
type UserConfig struct {
Highlight bool
Highlight *regexp.Regexp
Bell bool
Quiet bool
Theme *Theme
@ -138,9 +160,8 @@ var DefaultUserConfig *UserConfig
func init() {
DefaultUserConfig = &UserConfig{
Highlight: true,
Bell: false,
Quiet: false,
Bell: true,
Quiet: false,
}
// TODO: Seed random?

View File

@ -92,6 +92,7 @@ func (h *Host) Connect(term *sshd.Terminal) {
// Successfully joined.
term.SetPrompt(GetPrompt(user))
user.SetHighlight(user.Name())
h.count++
// Should the user be op'd on join?
@ -119,6 +120,7 @@ func (h *Host) Connect(term *sshd.Terminal) {
// FIXME: This is hacky, how do we improve the API to allow for
// this? Chat module shouldn't know about terminals.
term.SetPrompt(GetPrompt(user))
user.SetHighlight(user.Name())
}
}