commit 85482b9
Hubert Hirtz
·
2021-12-06 10:30:48 +0000 UTC
parent ee21112
Merge redundant events
3 files changed,
+112,
-18
M
app.go
+87,
-1
1@@ -124,6 +124,9 @@ func NewApp(cfg Config) (app *App, err error) {
2 return app.completions(cursorIdx, text)
3 },
4 Mouse: mouse,
5+ MergeLine: func(former *ui.Line, addition ui.Line) {
6+ app.mergeLine(former, addition)
7+ },
8 })
9 if err != nil {
10 return
11@@ -955,13 +958,13 @@ func (app *App) formatEvent(ev irc.Event) ui.Line {
12 body.AddStyle(0, textStyle)
13 body.AddStyle(len(ev.FormerNick), arrowStyle)
14 body.AddStyle(body.Len()-len(ev.User), textStyle)
15-
16 return ui.Line{
17 At: ev.Time,
18 Head: "--",
19 HeadColor: tcell.ColorGray,
20 Body: body.StyledString(),
21 Mergeable: true,
22+ Data: []interface{}{ev},
23 }
24 case irc.UserJoinEvent:
25 var body ui.StyledStringBuilder
26@@ -976,6 +979,7 @@ func (app *App) formatEvent(ev irc.Event) ui.Line {
27 HeadColor: tcell.ColorGray,
28 Body: body.StyledString(),
29 Mergeable: true,
30+ Data: []interface{}{ev},
31 }
32 case irc.UserPartEvent:
33 var body ui.StyledStringBuilder
34@@ -990,6 +994,7 @@ func (app *App) formatEvent(ev irc.Event) ui.Line {
35 HeadColor: tcell.ColorGray,
36 Body: body.StyledString(),
37 Mergeable: true,
38+ Data: []interface{}{ev},
39 }
40 case irc.UserQuitEvent:
41 var body ui.StyledStringBuilder
42@@ -1004,6 +1009,7 @@ func (app *App) formatEvent(ev irc.Event) ui.Line {
43 HeadColor: tcell.ColorGray,
44 Body: body.StyledString(),
45 Mergeable: true,
46+ Data: []interface{}{ev},
47 }
48 case irc.TopicChangeEvent:
49 topic := ui.IRCString(ev.Topic).String()
50@@ -1022,6 +1028,7 @@ func (app *App) formatEvent(ev irc.Event) ui.Line {
51 HeadColor: tcell.ColorGray,
52 Body: ui.Styled(body, tcell.StyleDefault.Foreground(tcell.ColorGray)),
53 Mergeable: true,
54+ Data: []interface{}{ev},
55 }
56 default:
57 return ui.Line{}
58@@ -1105,6 +1112,85 @@ func (app *App) formatMessage(s *irc.Session, ev irc.MessageEvent) (buffer strin
59 return
60 }
61
62+func (app *App) mergeLine(former *ui.Line, addition ui.Line) {
63+ partQuitUser := func(ev interface{}) string {
64+ if ev, ok := ev.(irc.UserQuitEvent); ok {
65+ return ev.User
66+ }
67+ if ev, ok := ev.(irc.UserPartEvent); ok {
68+ return ev.User
69+ }
70+ panic("unreachable")
71+ }
72+
73+ changed := false
74+Outer:
75+ for _, addedEvent := range addition.Data {
76+ switch addedEvent := addedEvent.(type) {
77+ case irc.UserNickEvent:
78+ for i := len(former.Data) - 1; i >= 0; i-- {
79+ switch ev := former.Data[i].(type) {
80+ case irc.UserNickEvent:
81+ if ev.User == addedEvent.FormerNick && ev.FormerNick == addedEvent.User {
82+ former.Data = append(former.Data[:i], former.Data[i+1:]...)
83+ changed = true
84+ continue Outer
85+ }
86+ }
87+ }
88+ former.Data = append(former.Data, addedEvent)
89+ case irc.UserJoinEvent:
90+ for i := len(former.Data) - 1; i >= 0; i-- {
91+ switch ev := former.Data[i].(type) {
92+ case irc.UserPartEvent, irc.UserQuitEvent:
93+ if partQuitUser(ev) == addedEvent.User {
94+ former.Data = append(former.Data[:i], former.Data[i+1:]...)
95+ changed = true
96+ continue Outer
97+ }
98+ }
99+ }
100+ former.Data = append(former.Data, addedEvent)
101+ case irc.UserQuitEvent, irc.UserPartEvent:
102+ for i := len(former.Data) - 1; i >= 0; i-- {
103+ switch ev := former.Data[i].(type) {
104+ case irc.UserJoinEvent:
105+ if ev.User == partQuitUser(addedEvent) {
106+ former.Data = append(former.Data[:i], former.Data[i+1:]...)
107+ changed = true
108+ continue Outer
109+ }
110+ }
111+ }
112+ former.Data = append(former.Data, addedEvent)
113+ //case irc.ModeChangeEvent: //TODO
114+ default:
115+ former.Data = append(former.Data, addedEvent)
116+ }
117+ }
118+ if changed {
119+ if len(former.Data) == 0 {
120+ former.Body = ui.PlainString("")
121+ return
122+ }
123+ var body ui.StyledStringBuilder
124+ body.Grow(len(former.Body.String()))
125+ body.WriteStyledString(app.formatEvent(former.Data[0]).Body)
126+ for _, ev := range former.Data[1:] {
127+ body.WriteString(" ")
128+ body.WriteStyledString(app.formatEvent(ev).Body)
129+ }
130+ former.Body = body.StyledString()
131+ } else {
132+ var newBody ui.StyledStringBuilder
133+ newBody.Grow(len(former.Body.String()) + 2 + len(addition.Body.String()))
134+ newBody.WriteStyledString(former.Body)
135+ newBody.WriteString(" ")
136+ newBody.WriteStyledString(addition.Body)
137+ former.Body = newBody.StyledString()
138+ }
139+}
140+
141 // updatePrompt changes the prompt text according to the application context.
142 func (app *App) updatePrompt() {
143 netID, buffer := app.win.CurrentBuffer()
+23,
-16
1@@ -33,6 +33,7 @@ type Line struct {
2 HeadColor tcell.Color
3 Highlight bool
4 Mergeable bool
5+ Data []interface{}
6
7 splitPoints []point
8 width int
9@@ -43,17 +44,6 @@ func (l *Line) IsZero() bool {
10 return l.Body.string == ""
11 }
12
13-func (l *Line) Merge(line Line) {
14- newBody := new(StyledStringBuilder)
15- newBody.Grow(len(l.Body.string) + 2 + len(line.Body.string))
16- newBody.WriteStyledString(l.Body)
17- newBody.WriteString(" ")
18- newBody.WriteStyledString(line.Body)
19- l.Body = newBody.StyledString()
20- l.computeSplitPoints()
21- l.width = 0
22-}
23-
24 func (l *Line) computeSplitPoints() {
25 if l.splitPoints == nil {
26 l.splitPoints = []point{}
27@@ -209,14 +199,17 @@ type BufferList struct {
28 tlHeight int
29
30 showBufferNumbers bool
31+
32+ doMergeLine func(former *Line, addition Line)
33 }
34
35 // NewBufferList returns a new BufferList.
36 // Call Resize() once before using it.
37-func NewBufferList() BufferList {
38+func NewBufferList(mergeLine func(*Line, Line)) BufferList {
39 return BufferList{
40- list: []buffer{},
41- clicked: -1,
42+ list: []buffer{},
43+ clicked: -1,
44+ doMergeLine: mergeLine,
45 }
46 }
47
48@@ -306,6 +299,16 @@ func (bs *BufferList) Remove(netID, title string) bool {
49 return true
50 }
51
52+func (bs *BufferList) mergeLine(former *Line, addition Line) (keepLine bool) {
53+ bs.doMergeLine(former, addition)
54+ if former.Body.string == "" {
55+ return false
56+ }
57+ former.width = 0
58+ former.computeSplitPoints()
59+ return true
60+}
61+
62 func (bs *BufferList) AddLine(netID, title string, notify NotifyType, line Line) {
63 idx := bs.idx(netID, title)
64 if idx < 0 {
65@@ -322,7 +325,9 @@ func (bs *BufferList) AddLine(netID, title string, notify NotifyType, line Line)
66
67 if line.Mergeable && n != 0 && b.lines[n-1].Mergeable {
68 l := &b.lines[n-1]
69- l.Merge(line)
70+ if !bs.mergeLine(l, line) {
71+ b.lines = b.lines[:n-1]
72+ }
73 // TODO change b.scrollAmt if it's not 0 and bs.current is idx.
74 } else {
75 line.computeSplitPoints()
76@@ -353,7 +358,9 @@ func (bs *BufferList) AddLines(netID, title string, before, after []Line) {
77 for _, line := range *buf {
78 if line.Mergeable && len(lines) > 0 && lines[len(lines)-1].Mergeable {
79 l := &lines[len(lines)-1]
80- l.Merge(line)
81+ if !bs.mergeLine(l, line) {
82+ lines = lines[:len(lines)-1]
83+ }
84 } else {
85 if buf != &b.lines {
86 line.Body = line.Body.ParseURLs()
M
ui/ui.go
+2,
-1
1@@ -15,6 +15,7 @@ type Config struct {
2 MemberColWidth int
3 AutoComplete func(cursorIdx int, text []rune) []Completion
4 Mouse bool
5+ MergeLine func(former *Line, addition Line)
6 }
7
8 type UI struct {
9@@ -70,7 +71,7 @@ func New(config Config) (ui *UI, err error) {
10 close(ui.Events)
11 }()
12
13- ui.bs = NewBufferList()
14+ ui.bs = NewBufferList(ui.config.MergeLine)
15 ui.e = NewEditor(ui.config.AutoComplete)
16 ui.Resize()
17