summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app.go85
-rw-r--r--config.go24
-rw-r--r--ui/buffers.go18
-rw-r--r--ui/ui.go33
-rw-r--r--window.go16
5 files changed, 127 insertions, 49 deletions
diff --git a/app.go b/app.go
index cc4137b..14c3885 100644
--- a/app.go
+++ b/app.go
@@ -144,8 +144,11 @@ func NewApp(cfg Config) (app *App, err error) {
app.mergeLine(former, addition)
},
Colors: ui.ConfigColors{
- Unread: cfg.Colors.Unread,
- Nicks: cfg.Colors.Nicks,
+ Unread: cfg.Colors.Unread,
+ Nicks: cfg.Colors.Nicks,
+ ServerForeground: cfg.Colors.ServerForeground,
+ ChanForegroundInactive: cfg.Colors.ChanForegroundInactive,
+ ChanForegroundActive: cfg.Colors.ChanForegroundActive,
},
})
if err != nil {
@@ -347,8 +350,10 @@ func (app *App) ircLoop(netID string) {
content: nil,
}
app.queueStatusLine(netID, ui.Line{
- Head: "!!",
+ Head: ":(",
+ HeadTag: ":(",
HeadColor: tcell.ColorRed,
+ Temporary: true,
Body: ui.PlainString("Connection lost"),
})
}
@@ -356,8 +361,11 @@ func (app *App) ircLoop(netID string) {
func (app *App) connect(netID string) net.Conn {
app.queueStatusLine(netID, ui.Line{
- Head: "--",
- Body: ui.PlainSprintf("Connecting to %s...", app.cfg.Addr),
+ Head: "﹒﹒﹒",
+ HeadTag: "﹒﹒﹒",
+ HeadColor: tcell.ColorOrange,
+ Temporary: true,
+ Body: ui.PlainSprintf("Connecting to %s…", app.cfg.Addr),
})
conn, err := app.tryConnect()
if err == nil {
@@ -365,7 +373,9 @@ func (app *App) connect(netID string) net.Conn {
}
app.queueStatusLine(netID, ui.Line{
Head: "!!",
+ HeadTag: "!!",
HeadColor: tcell.ColorRed,
+ Temporary: true,
Body: ui.PlainSprintf("Connection failed: %v", err),
})
return nil
@@ -751,10 +761,11 @@ func (app *App) handleIRCEvent(netID string, ev interface{}) {
if s.Nick() != app.cfg.Nick {
body = fmt.Sprintf("Connected to the server as %s", s.Nick())
}
- app.addStatusLine(netID, ui.Line{
- At: msg.TimeOrNow(),
- Head: "--",
- Body: ui.PlainString(body),
+ app.addTemporaryStatusLine(netID, ui.Line{
+ At: msg.TimeOrNow(),
+ Head: ":)",
+ HeadColor: tcell.ColorGreen,
+ Body: ui.PlainString(body),
})
for target := range app.monitor[s.NetID()] {
// TODO: batch MONITOR +
@@ -768,7 +779,7 @@ func (app *App) handleIRCEvent(netID string, ev interface{}) {
body.AddStyle(0, textStyle)
body.AddStyle(len(ev.FormerNick), arrowStyle)
body.AddStyle(body.Len()-len(s.Nick()), textStyle)
- app.addStatusLine(netID, ui.Line{
+ app.addTemporaryStatusLine(netID, ui.Line{
At: msg.TimeOrNow(),
Head: "--",
HeadColor: tcell.ColorGray,
@@ -991,32 +1002,55 @@ func (app *App) handleIRCEvent(netID string, ev interface{}) {
}
if ev.Code == "372" {
app.win.AddLine(netID, "", ui.Line{
- At: msg.TimeOrNow(),
- Head: "MOTD --",
- Body: ui.PlainString(ev.Message),
+ At: msg.TimeOrNow(),
+ Head: "MOTD",
+ HeadTag: "motd",
+ HeadColor: tcell.ColorWhiteSmoke,
+ Body: ui.PlainString(ev.Message),
+ })
+ break
+ }
+ if ev.Code == "396" {
+ app.win.AddLine(netID, "", ui.Line{
+ At: msg.TimeOrNow(),
+ Head: "server",
+ HeadTag: "server",
+ HeadColor: tcell.ColorGray,
+ Body: ui.PlainString(ev.Message),
})
break
}
var head string
var body string
+ headColor := tcell.ColorGray
+ statusLine := false
switch ev.Severity {
case irc.SeverityFail:
head = "--"
+ headColor = tcell.ColorRed
body = fmt.Sprintf("Error (code %s): %s", ev.Code, ev.Message)
case irc.SeverityWarn:
head = "--"
+ headColor = tcell.ColorYellow
body = fmt.Sprintf("Warning (code %s): %s", ev.Code, ev.Message)
case irc.SeverityNote:
- head = ev.Code + " --"
+ head = ev.Code
body = ev.Message
default:
panic("unreachable")
}
- app.addStatusLine(netID, ui.Line{
- At: msg.TimeOrNow(),
- Head: head,
- Body: ui.PlainString(body),
- })
+ line := ui.Line{
+ At: msg.TimeOrNow(),
+ Head: head,
+ HeadTag: head,
+ HeadColor: headColor,
+ Body: ui.PlainString(body),
+ }
+ if statusLine {
+ app.addStatusLine(netID, line)
+ } else {
+ app.win.AddLine(netID, "", line)
+ }
}
}
@@ -1091,7 +1125,7 @@ func (app *App) notifyHighlight(buffer, nick, content string) {
// if default path unreachable, simple bail
if app.cfg.OnHighlightPath != "" {
body := fmt.Sprintf("Unable to find on-highlight command at path: %q", path)
- app.addStatusLine(netID, ui.Line{
+ app.addTemporaryStatusLine(netID, ui.Line{
At: time.Now(),
Head: "!!",
HeadColor: tcell.ColorRed,
@@ -1323,7 +1357,8 @@ func (app *App) formatMessage(s *irc.Session, ev irc.MessageEvent) (buffer strin
head := ev.User
headColor := tcell.ColorWhite
if isAction || isNotice {
- head = "*"
+ head = "﹡"
+ headColor = ui.IdentColor(app.cfg.Colors.Nicks, ev.User)
} else {
headColor = ui.IdentColor(app.cfg.Colors.Nicks, head)
}
@@ -1338,11 +1373,12 @@ func (app *App) formatMessage(s *irc.Session, ev irc.MessageEvent) (buffer strin
body.WriteStyledString(ui.IRCString(content))
} else if isAction {
color := ui.IdentColor(app.cfg.Colors.Nicks, ev.User)
- body.SetStyle(tcell.StyleDefault.Foreground(color))
+ body.SetStyle(tcell.StyleDefault.Italic(true).Foreground(color))
body.WriteString(ev.User)
- body.SetStyle(tcell.StyleDefault)
+ body.SetStyle(tcell.StyleDefault.Italic(true))
body.WriteString(" ")
body.WriteStyledString(ui.IRCString(content))
+ body.SetStyle(tcell.StyleDefault)
} else {
body.WriteStyledString(ui.IRCString(content))
}
@@ -1350,6 +1386,7 @@ func (app *App) formatMessage(s *irc.Session, ev irc.MessageEvent) (buffer strin
line = ui.Line{
At: ev.Time,
Head: head,
+ HeadTag: head,
HeadColor: headColor,
Notify: notification,
Body: body.StyledString(),
@@ -1496,6 +1533,7 @@ func (app *App) printTopic(netID, buffer string) (ok bool) {
At: time.Now(),
Head: "topic",
HeadColor: tcell.ColorGray,
+ HeadTag: "topic",
Body: ui.Styled(topic, tcell.StyleDefault.Foreground(tcell.ColorWhite)),
})
if who != nil {
@@ -1507,6 +1545,7 @@ func (app *App) printTopic(netID, buffer string) (ok bool) {
At: time.Now(),
Head: "—",
HeadColor: tcell.ColorGray,
+ HeadTag: "topicby",
Body: ui.Styled(body, tcell.StyleDefault.Foreground(tcell.ColorGray)),
})
return true
diff --git a/config.go b/config.go
index beebf7a..b212bc2 100644
--- a/config.go
+++ b/config.go
@@ -48,9 +48,12 @@ func parseColor(s string, c *tcell.Color) error {
}
type ConfigColors struct {
- Prompt tcell.Color
- Unread tcell.Color
- Nicks ui.ColorScheme
+ Prompt tcell.Color
+ Unread tcell.Color
+ Nicks ui.ColorScheme
+ ServerForeground tcell.Color
+ ChanForegroundInactive tcell.Color
+ ChanForegroundActive tcell.Color
}
type Config struct {
@@ -109,9 +112,12 @@ func Defaults() (cfg Config, err error) {
MemberColEnabled: true,
TextMaxWidth: 0,
Colors: ConfigColors{
- Prompt: tcell.ColorDefault,
- Unread: tcell.ColorDefault,
- Nicks: ui.ColorSchemeBase,
+ Prompt: tcell.ColorDefault,
+ Unread: tcell.ColorDefault,
+ Nicks: ui.ColorSchemeBase,
+ ServerForeground: tcell.ColorDarkGray,
+ ChanForegroundInactive: tcell.ColorGray,
+ ChanForegroundActive: tcell.ColorWhite,
},
Debug: false,
}
@@ -345,6 +351,12 @@ func unmarshal(filename string, cfg *Config) (err error) {
cfg.Colors.Prompt = color
case "unread":
cfg.Colors.Unread = color
+ case "server":
+ cfg.Colors.ServerForeground = color
+ case "channel":
+ cfg.Colors.ChanForegroundInactive = color
+ case "channel-active":
+ cfg.Colors.ChanForegroundActive = color
default:
return fmt.Errorf("unknown directive %q", child.Name)
}
diff --git a/ui/buffers.go b/ui/buffers.go
index 3a17b18..703fd1a 100644
--- a/ui/buffers.go
+++ b/ui/buffers.go
@@ -37,6 +37,7 @@ type Line struct {
Highlight bool
Readable bool
Mergeable bool
+ Temporary bool
Data interface{}
splitPoints []point
@@ -392,9 +393,12 @@ func (bs *BufferList) AddLine(netID, title string, line Line) {
} else {
if n != 0 {
l := &b.lines[n-1]
- if l.Head == line.Head || l.HeadTag == line.Head {
+ if l.Temporary {
+ b.lines = b.lines[:n-1]
+ }
+ if line.HeadTag == l.HeadTag || l.Head == line.Head || l.HeadTag == line.Head {
line.HeadTag = line.Head
- line.Head = ""
+ line.Head = "│"
}
}
line.computeSplitPoints()
@@ -435,9 +439,9 @@ func (bs *BufferList) AddLines(netID, title string, before, after []Line) {
}
if len(lines) > 0 {
l := &lines[len(lines)-1]
- if l.Head == line.Head || l.HeadTag == line.Head {
+ if line.HeadTag == l.HeadTag || l.Head == line.Head || l.HeadTag == line.Head {
line.HeadTag = line.Head
- line.Head = ""
+ line.Head = "│"
}
}
lines = append(lines, line)
@@ -595,6 +599,8 @@ func (bs *BufferList) DrawVerticalBufferList(screen tcell.Screen, x0, y0, width,
st := tcell.StyleDefault
if b.unread {
st = st.Bold(true).Foreground(bs.colors.Unread)
+ } else {
+ st = st.Foreground(bs.colors.ChanForegroundInactive)
}
if bi == bs.current || bi == bs.clicked {
st = st.Reverse(true)
@@ -609,6 +615,7 @@ func (bs *BufferList) DrawVerticalBufferList(screen tcell.Screen, x0, y0, width,
var title string
if b.title == "" {
title = b.netName
+ st.Foreground(bs.colors.ServerForeground)
} else {
if bi == bs.current || bi == bs.clicked {
screen.SetContent(x, y, ' ', nil, tcell.StyleDefault.Reverse(true))
@@ -708,6 +715,7 @@ func (bs *BufferList) DrawHorizontalBufferList(screen tcell.Screen, x0, y0, widt
break
}
st := tcell.StyleDefault
+ st = st.Foreground(bs.colors.ChanForegroundInactive)
if b.unread {
st = st.Bold(true).Foreground(bs.colors.Unread)
} else if i == bs.current {
@@ -719,7 +727,7 @@ func (bs *BufferList) DrawHorizontalBufferList(screen tcell.Screen, x0, y0, widt
var title string
if b.title == "" {
- st = st.Dim(true)
+ st = st.Dim(true).Foreground(bs.colors.ServerForeground)
title = b.netName
} else {
title = b.title
diff --git a/ui/ui.go b/ui/ui.go
index 859f32a..d37c495 100644
--- a/ui/ui.go
+++ b/ui/ui.go
@@ -11,21 +11,26 @@ import (
)
type Config struct {
- NickColWidth int
- ChanColWidth int
- ChanColEnabled bool
- MemberColWidth int
- MemberColEnabled bool
- TextMaxWidth int
- AutoComplete func(cursorIdx int, text []rune) []Completion
- Mouse bool
- MergeLine func(former *Line, addition Line)
- Colors ConfigColors
+ NickColWidth int
+ ChanColWidth int
+ ChanColEnabled bool
+ MemberColWidth int
+ MemberColEnabled bool
+ TextMaxWidth int
+ AutoComplete func(cursorIdx int, text []rune) []Completion
+ Mouse bool
+ MergeLine func(former *Line, addition Line)
+ Colors ConfigColors
+ HideMultiLineNickEnabled bool
+ HideMultiLineNickChar string
}
type ConfigColors struct {
- Unread tcell.Color
- Nicks ColorScheme
+ Unread tcell.Color
+ Nicks ColorScheme
+ ServerForeground tcell.Color
+ ChanForegroundInactive tcell.Color
+ ChanForegroundActive tcell.Color
}
type UI struct {
@@ -58,6 +63,10 @@ func New(config Config) (ui *UI, err error) {
ui.memberWidth = config.MemberColWidth
}
+ if config.HideMultiLineNickEnabled && config.HideMultiLineNickChar == "" {
+ config.HideMultiLineNickChar = "│"
+ }
+
ui.screen, err = tcell.NewScreen()
if err != nil {
return
diff --git a/window.go b/window.go
index 76e703d..c629136 100644
--- a/window.go
+++ b/window.go
@@ -44,6 +44,16 @@ func (app *App) addStatusLine(netID string, line ui.Line) {
app.win.AddLine(netID, "", line)
}
+func (app *App) addTemporaryStatusLine(netID string, line ui.Line) {
+ currentNetID, buffer := app.win.CurrentBuffer()
+ if currentNetID == netID && buffer != "" {
+ currentLine := line
+ currentLine.Temporary = true
+ app.win.AddLine(netID, buffer, currentLine)
+ }
+ app.win.AddLine(netID, "", line)
+}
+
func (app *App) setStatus() {
netID, buffer := app.win.CurrentBuffer()
s := app.sessions[netID]
@@ -53,11 +63,11 @@ func (app *App) setStatus() {
ts := s.Typings(buffer)
status := ""
if 3 < len(ts) {
- status = "several people are typing..."
+ status = "several people are typing…"
} else {
- verb := " is typing..."
+ verb := " is typing…"
if 1 < len(ts) {
- verb = " are typing..."
+ verb = " are typing…"
status = strings.Join(ts[:len(ts)-1], ", ") + " and "
}
if 0 < len(ts) {