summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app.go11
-rw-r--r--config.go12
-rw-r--r--doc/senpai.5.scd7
-rw-r--r--ui/buffers.go56
-rw-r--r--ui/editor.go5
-rw-r--r--ui/ui.go29
6 files changed, 81 insertions, 39 deletions
diff --git a/app.go b/app.go
index bf86aa2..aa6a4c4 100644
--- a/app.go
+++ b/app.go
@@ -60,8 +60,9 @@ func NewApp(cfg Config) (app *App, err error) {
}
app.win, err = ui.New(ui.Config{
- NickColWidth: cfg.NickColWidth,
- ChanColWidth: cfg.ChanColWidth,
+ NickColWidth: cfg.NickColWidth,
+ ChanColWidth: cfg.ChanColWidth,
+ MemberColWidth: cfg.MemberColWidth,
AutoComplete: func(cursorIdx int, text []rune) []ui.Completion {
return app.completions(cursorIdx, text)
},
@@ -116,7 +117,11 @@ func (app *App) eventLoop() {
if !app.pasting {
app.setStatus()
app.updatePrompt()
- app.win.Draw()
+ var currentMembers []irc.Member
+ if app.s != nil {
+ currentMembers = app.s.Names(app.win.CurrentBuffer())
+ }
+ app.win.Draw(currentMembers)
}
}
}
diff --git a/config.go b/config.go
index 10656f4..a2f70b9 100644
--- a/config.go
+++ b/config.go
@@ -58,10 +58,11 @@ type Config struct {
NoTypings bool `yaml:"no-typings"`
Mouse *bool
- Highlights []string
- OnHighlight string `yaml:"on-highlight"`
- NickColWidth int `yaml:"nick-column-width"`
- ChanColWidth int `yaml:"chan-column-width"`
+ Highlights []string
+ OnHighlight string `yaml:"on-highlight"`
+ NickColWidth int `yaml:"nick-column-width"`
+ ChanColWidth int `yaml:"chan-column-width"`
+ MemberColWidth int `yaml:"member-column-width"`
Colors struct {
Prompt Color
@@ -93,6 +94,9 @@ func ParseConfig(buf []byte) (cfg Config, err error) {
if cfg.ChanColWidth <= 0 {
cfg.ChanColWidth = 16
}
+ if cfg.MemberColWidth <= 0 {
+ cfg.MemberColWidth = 16
+ }
return
}
diff --git a/doc/senpai.5.scd b/doc/senpai.5.scd
index b3edd18..6ad15ba 100644
--- a/doc/senpai.5.scd
+++ b/doc/senpai.5.scd
@@ -72,11 +72,14 @@ on-highlight: |
```
*nick-column-width*
- The number of cell that the column for nicknames occupies in the timeline.
+ The number of cells that the column for nicknames occupies in the timeline.
By default, 16.
*chan-column-width*
- The number of cell that the column for channels occupies. By default, 16.
+ The number of cells that the column for channels occupies. By default, 16.
+
+*member-column-width*
+ The number of cells that the column for members occupies. By default, 16.
*no-tls*
Disable TLS encryption. Defaults to false.
diff --git a/ui/buffers.go b/ui/buffers.go
index 4726447..94e2a4e 100644
--- a/ui/buffers.go
+++ b/ui/buffers.go
@@ -4,6 +4,8 @@ import (
"strings"
"time"
+ "git.sr.ht/~taiite/senpai/irc"
+
"github.com/gdamore/tcell/v2"
)
@@ -185,30 +187,24 @@ type BufferList struct {
current int
clicked int
- tlWidth int
+ tlInnerWidth int
tlHeight int
- nickColWidth int
}
-func NewBufferList(tlWidth, tlHeight, nickColWidth int) BufferList {
+// NewBufferList returns a new BufferList.
+// Call Resize() once before using it.
+func NewBufferList() BufferList {
return BufferList{
- list: []buffer{},
- clicked: -1,
- tlWidth: tlWidth,
- tlHeight: tlHeight,
- nickColWidth: nickColWidth,
+ list: []buffer{},
+ clicked: -1,
}
}
-func (bs *BufferList) ResizeTimeline(tlWidth, tlHeight, nickColWidth int) {
- bs.tlWidth = tlWidth
+func (bs *BufferList) ResizeTimeline(tlInnerWidth, tlHeight int) {
+ bs.tlInnerWidth = tlInnerWidth
bs.tlHeight = tlHeight
}
-func (bs *BufferList) tlInnerWidth() int {
- return bs.tlWidth - bs.nickColWidth - 9
-}
-
func (bs *BufferList) To(i int) {
if 0 <= i {
bs.current = i
@@ -284,7 +280,7 @@ func (bs *BufferList) AddLine(title string, notify NotifyType, line Line) {
line.computeSplitPoints()
b.lines = append(b.lines, line)
if idx == bs.current && 0 < b.scrollAmt {
- b.scrollAmt += len(line.NewLines(bs.tlInnerWidth())) + 1
+ b.scrollAmt += len(line.NewLines(bs.tlInnerWidth)) + 1
}
}
@@ -433,8 +429,34 @@ func (bs *BufferList) DrawVerticalBufferList(screen tcell.Screen, x0, y0, width,
}
}
+func (bs *BufferList) DrawVerticalMemberList(screen tcell.Screen, x0, y0, width, height int, members []irc.Member) {
+ st := tcell.StyleDefault
+
+ for y := y0; y < y0+height; y++ {
+ screen.SetContent(x0, y, 0x2502, nil, st)
+ for x := x0 + 1; x < x0+width; x++ {
+ screen.SetContent(x, y, ' ', nil, st)
+ }
+ }
+
+ for i, m := range members {
+ st = tcell.StyleDefault
+ x := x0 + 1
+ y := y0 + i
+
+ if m.PowerLevel != "" {
+ printString(screen, &x, y, Styled(string([]rune(m.PowerLevel)[0]), st.Foreground(tcell.ColorGreen)))
+ } else {
+ x += 1
+ }
+ name := truncate(m.Name.Name, width-(x-x0), "\u2026")
+ printString(screen, &x, y, Styled(name, st))
+ y++
+ }
+}
+
func (bs *BufferList) DrawTimeline(screen tcell.Screen, x0, y0, nickColWidth int) {
- for x := x0; x < x0+bs.tlWidth; x++ {
+ for x := x0; x < x0+bs.tlInnerWidth+nickColWidth+9; x++ {
for y := y0; y < y0+bs.tlHeight; y++ {
screen.SetContent(x, y, ' ', nil, tcell.StyleDefault)
}
@@ -450,7 +472,7 @@ func (bs *BufferList) DrawTimeline(screen tcell.Screen, x0, y0, nickColWidth int
x1 := x0 + 9 + nickColWidth
line := &b.lines[i]
- nls := line.NewLines(bs.tlInnerWidth())
+ nls := line.NewLines(bs.tlInnerWidth)
yi -= len(nls) + 1
if y0+bs.tlHeight <= yi {
continue
diff --git a/ui/editor.go b/ui/editor.go
index a714587..7e8c96e 100644
--- a/ui/editor.go
+++ b/ui/editor.go
@@ -37,11 +37,12 @@ type Editor struct {
autoCacheIdx int
}
-func NewEditor(width int, autoComplete func(cursorIdx int, text []rune) []Completion) Editor {
+// NewEditor returns a new Editor.
+// Call Resize() once before using it.
+func NewEditor(autoComplete func(cursorIdx int, text []rune) []Completion) Editor {
return Editor{
text: [][]rune{{}},
textWidth: []int{0},
- width: width,
autoComplete: autoComplete,
}
}
diff --git a/ui/ui.go b/ui/ui.go
index ef8fea6..fe18d0e 100644
--- a/ui/ui.go
+++ b/ui/ui.go
@@ -5,14 +5,17 @@ import (
"sync/atomic"
"time"
+ "git.sr.ht/~taiite/senpai/irc"
+
"github.com/gdamore/tcell/v2"
)
type Config struct {
- NickColWidth int
- ChanColWidth int
- AutoComplete func(cursorIdx int, text []rune) []Completion
- Mouse bool
+ NickColWidth int
+ ChanColWidth int
+ MemberColWidth int
+ AutoComplete func(cursorIdx int, text []rune) []Completion
+ Mouse bool
}
type UI struct {
@@ -46,7 +49,7 @@ func New(config Config) (ui *UI, err error) {
}
ui.screen.EnablePaste()
- w, h := ui.screen.Size()
+ _, h := ui.screen.Size()
ui.screen.Clear()
ui.screen.ShowCursor(0, h-2)
@@ -59,8 +62,8 @@ func New(config Config) (ui *UI, err error) {
}
}()
- ui.bs = NewBufferList(w, h, ui.config.NickColWidth)
- ui.e = NewEditor(w, ui.config.AutoComplete)
+ ui.bs = NewBufferList()
+ ui.e = NewEditor(ui.config.AutoComplete)
ui.Resize()
return
@@ -242,18 +245,20 @@ func (ui *UI) InputClear() bool {
func (ui *UI) Resize() {
w, h := ui.screen.Size()
- ui.e.Resize(w - 9 - ui.config.ChanColWidth - ui.config.NickColWidth)
- ui.bs.ResizeTimeline(w-ui.config.ChanColWidth, h-2, ui.config.NickColWidth)
+ innerWidth := w - 9 - ui.config.ChanColWidth - ui.config.NickColWidth - ui.config.MemberColWidth
+ ui.e.Resize(innerWidth)
+ ui.bs.ResizeTimeline(innerWidth, h-2)
}
-func (ui *UI) Draw() {
+func (ui *UI) Draw(members []irc.Member) {
w, h := ui.screen.Size()
ui.e.Draw(ui.screen, 9+ui.config.ChanColWidth+ui.config.NickColWidth, h-1)
ui.bs.DrawTimeline(ui.screen, ui.config.ChanColWidth, 0, ui.config.NickColWidth)
ui.bs.DrawVerticalBufferList(ui.screen, 0, 0, ui.config.ChanColWidth, h)
- ui.drawStatusBar(ui.config.ChanColWidth, h-2, w-ui.config.ChanColWidth)
+ ui.bs.DrawVerticalMemberList(ui.screen, w-ui.config.MemberColWidth, 0, ui.config.MemberColWidth, h, members)
+ ui.drawStatusBar(ui.config.ChanColWidth, h-2, w-ui.config.ChanColWidth-ui.config.MemberColWidth)
for x := ui.config.ChanColWidth; x < 9+ui.config.ChanColWidth+ui.config.NickColWidth; x++ {
ui.screen.SetContent(x, h-1, ' ', nil, tcell.StyleDefault)
@@ -264,6 +269,8 @@ func (ui *UI) Draw() {
}
func (ui *UI) drawStatusBar(x0, y, width int) {
+ width--
+
st := tcell.StyleDefault.Dim(true)
for x := x0; x < x0+width; x++ {