Skip to content

Commit e88b800

Browse files
authored
progress: support pinned messages with multiple lines (#233)
1 parent 7d299c2 commit e88b800

File tree

7 files changed

+117
-130
lines changed

7 files changed

+117
-130
lines changed

cmd/demo-progress/demo.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,8 @@ func trackSomething(pw progress.Writer, idx int64, updateMessage bool) {
9090
tracker.MarkAsErrored()
9191
}
9292
pw.SetPinnedMessages(
93-
fmt.Sprintf("Current Time: %s | Total Time: %s",
94-
time.Now().Format(time.RFC3339),
95-
time.Now().Sub(timeStart).Round(time.Second),
96-
),
93+
fmt.Sprintf(">> Current Time: %-32s", time.Now().Format(time.RFC3339)),
94+
fmt.Sprintf(">> Total Time: %-32s", time.Now().Sub(timeStart).Round(time.Millisecond)),
9795
)
9896
case <-updateTicker:
9997
if updateMessage {

progress/progress.go

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ type Progress struct {
3535
overallTracker *Tracker
3636
overallTrackerMutex sync.RWMutex
3737
pinnedMessages []string
38-
pinnedMessagesMutex sync.RWMutex
38+
pinnedMessageMutex sync.RWMutex
39+
pinnedMessageNumLines int
3940
renderInProgress bool
4041
renderInProgressMutex sync.RWMutex
4142
sortBy SortBy
@@ -157,14 +158,6 @@ func (p *Progress) Log(msg string, a ...interface{}) {
157158
p.logsToRenderMutex.Unlock()
158159
}
159160

160-
// PinnedMessages returns the current pinned messages.
161-
func (p *Progress) PinnedMessages() []string {
162-
p.pinnedMessagesMutex.RLock()
163-
defer p.pinnedMessagesMutex.RUnlock()
164-
165-
return p.pinnedMessages
166-
}
167-
168161
// SetAutoStop toggles the auto-stop functionality. Auto-stop set to true would
169162
// mean that the Render() function will automatically stop once all currently
170163
// active Trackers reach their final states. When set to false, the client code
@@ -197,8 +190,8 @@ func (p *Progress) SetOutputWriter(writer io.Writer) {
197190
// progress bar. This method can be used to overwrite all the pinned messages.
198191
// Call this function without arguments to "clear" the pinned messages.
199192
func (p *Progress) SetPinnedMessages(messages ...string) {
200-
p.pinnedMessagesMutex.Lock()
201-
defer p.pinnedMessagesMutex.Unlock()
193+
p.pinnedMessageMutex.Lock()
194+
defer p.pinnedMessageMutex.Unlock()
202195

203196
p.pinnedMessages = messages
204197
}

progress/progress_test.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,6 @@ func TestProgress_Log(t *testing.T) {
9595
assert.Len(t, p.logsToRender, 1)
9696
}
9797

98-
func TestProgress_PinnedMessages(t *testing.T) {
99-
p := Progress{}
100-
assert.Nil(t, p.pinnedMessages)
101-
102-
p.pinnedMessages = []string{"pin1", "pin2"}
103-
assert.Equal(t, []string{"pin1", "pin2"}, p.PinnedMessages())
104-
}
105-
10698
func TestProgress_SetAutoStop(t *testing.T) {
10799
p := Progress{}
108100
assert.False(t, p.autoStop)

progress/render.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -159,22 +159,28 @@ func (p *Progress) moveCursorToTheTop(out *strings.Builder) {
159159
numLinesToMoveUp++
160160
}
161161
if p.style.Visibility.Pinned {
162-
numLinesToMoveUp += len(p.pinnedMessages)
162+
numLinesToMoveUp += p.pinnedMessageNumLines
163163
}
164-
if numLinesToMoveUp > 0 {
165-
out.WriteString(text.CursorUp.Sprintn(numLinesToMoveUp))
164+
for numLinesToMoveUp > 0 {
165+
out.WriteString(text.CursorUp.Sprint())
166+
out.WriteString(text.EraseLine.Sprint())
167+
numLinesToMoveUp--
166168
}
167169
}
168170

169171
func (p *Progress) renderPinnedMessages(out *strings.Builder) {
170-
p.pinnedMessagesMutex.RLock()
171-
defer p.pinnedMessagesMutex.RUnlock()
172+
p.pinnedMessageMutex.RLock()
173+
defer p.pinnedMessageMutex.RUnlock()
172174

175+
numLines := len(p.pinnedMessages)
173176
for _, msg := range p.pinnedMessages {
174-
out.WriteString(text.EraseLine.Sprint())
175-
out.WriteString(p.Style().Colors.Pinned.Sprint(msg))
177+
msg = strings.TrimSpace(msg)
178+
out.WriteString(p.style.Colors.Pinned.Sprint(msg))
176179
out.WriteRune('\n')
180+
181+
numLines += strings.Count(msg, "\n")
177182
}
183+
p.pinnedMessageNumLines = numLines
178184
}
179185

180186
func (p *Progress) renderTracker(out *strings.Builder, t *Tracker, hint renderHint) {
@@ -194,7 +200,6 @@ func (p *Progress) renderTracker(out *strings.Builder, t *Tracker, hint renderHi
194200
}
195201
}
196202

197-
out.WriteString(text.EraseLine.Sprint())
198203
if hint.isOverallTracker {
199204
if !t.IsDone() {
200205
hint := renderHint{hideValue: true, isOverallTracker: true}

0 commit comments

Comments
 (0)