diff options
-rw-r--r-- | app.go | 11 | ||||
-rw-r--r-- | config.go | 12 | ||||
-rw-r--r-- | doc/senpai.5.scd | 7 | ||||
-rw-r--r-- | ui/buffers.go | 56 | ||||
-rw-r--r-- | ui/editor.go | 5 | ||||
-rw-r--r-- | ui/ui.go | 29 |
6 files changed, 81 insertions, 39 deletions
@@ -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) } } } @@ -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, } } @@ -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++ { |