Skip to content

Commit

Permalink
progress: message snipped indicator (#53)
Browse files Browse the repository at this point in the history
  • Loading branch information
jedib0t authored Aug 14, 2018
1 parent 1e4c379 commit 9ff3b65
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 21 deletions.
8 changes: 1 addition & 7 deletions progress/render.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package progress

import (
"fmt"
"math"
"strings"
"time"
Expand Down Expand Up @@ -130,12 +129,7 @@ func (p *Progress) renderTrackerDone(out *strings.Builder, t *Tracker) {

func (p *Progress) renderTrackerProgress(out *strings.Builder, t *Tracker, trackerStr string) {
if p.messageWidth > 0 {
lenMessage := util.RuneCountWithoutEscapeSeq(t.Message)
if lenMessage > p.messageWidth {
t.Message = util.TrimTextWithoutEscapeSeq(t.Message, p.messageWidth)
} else if lenMessage < p.messageWidth {
t.Message = fmt.Sprintf("%-"+fmt.Sprint(p.messageWidth)+"s", t.Message)
}
t.Message = util.FixedLengthString(t.Message, p.messageWidth, p.style.Options.SnipIndicator)
}

if p.trackerPosition == PositionRight {
Expand Down
20 changes: 7 additions & 13 deletions progress/render_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,7 @@ func generateWriter() Writer {
pw.SetTrackerPosition(PositionRight)
pw.SetUpdateFrequency(time.Millisecond * 50)
pw.Style().Colors = StyleColors{}
pw.Style().Options = StyleOptions{
DoneString: "done!",
Separator: " ... ",
PercentFormat: "%5.2f%%",
TimeDonePrecision: time.Millisecond,
TimeInProgressPrecision: time.Microsecond,
}
pw.Style().Options = StyleOptionsDefault
return pw
}

Expand Down Expand Up @@ -185,12 +179,12 @@ func TestProgress_RenderSomeTrackers_WithLineWidth1(t *testing.T) {
renderAndWait(pw, false)

expectedOutPatterns := []*regexp.Regexp{
regexp.MustCompile(`\x1b\[KCalcu \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`),
regexp.MustCompile(`\x1b\[KDownl \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`),
regexp.MustCompile(`\x1b\[KTrans \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms]`),
regexp.MustCompile(`\x1b\[KCalcu \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`),
regexp.MustCompile(`\x1b\[KDownl \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`),
regexp.MustCompile(`\x1b\[KTrans \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`),
regexp.MustCompile(`\x1b\[KCalc~ \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+ in [\d.]+ms]`),
regexp.MustCompile(`\x1b\[KDown~ \.\.\. \d+\.\d+% \[[#.]{23}] \[\d+B in [\d.]+ms]`),
regexp.MustCompile(`\x1b\[KTran~ \.\.\. \d+\.\d+% \[[#.]{23}] \[\$\d+ in [\d.]+ms]`),
regexp.MustCompile(`\x1b\[KCalc~ \.\.\. done! \[\d+\.\d+K in [\d.]+ms]`),
regexp.MustCompile(`\x1b\[KDown~ \.\.\. done! \[\d+\.\d+KB in [\d.]+ms]`),
regexp.MustCompile(`\x1b\[KTran~ \.\.\. done! \[\$\d+\.\d+K in [\d.]+ms]`),
}
out := renderOutput.String()
for _, expectedOutPattern := range expectedOutPatterns {
Expand Down
4 changes: 3 additions & 1 deletion progress/style.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ var (
type StyleOptions struct {
DoneString string // "done!" string
Separator string // text between message and tracker
SnipIndicator string // text denoting message snipping
PercentFormat string // formatting to use for percentage
TimeDonePrecision time.Duration // precision for time when done
TimeInProgressPrecision time.Duration // precision for time when in progress
Expand All @@ -147,8 +148,9 @@ var (
// example to customize the Tracker rendering.
StyleOptionsDefault = StyleOptions{
DoneString: "done!",
Separator: " ... ",
PercentFormat: "%5.2f%%",
Separator: " ... ",
SnipIndicator: "~",
TimeDonePrecision: time.Millisecond,
TimeInProgressPrecision: time.Microsecond,
}
Expand Down
20 changes: 20 additions & 0 deletions util/string.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package util

import (
"fmt"
"strings"
"unicode/utf8"
)
Expand All @@ -14,6 +15,25 @@ const (
EscapeStopRune = 'm'
)

// FixedLengthString returns the given string with a fixed length. For ex.:
// FixedLengthString("Ghost", 0, "~") == "Ghost"
// FixedLengthString("Ghost", 1, "~") == "~"
// FixedLengthString("Ghost", 3, "~") == "Gh~"
// FixedLengthString("Ghost", 5, "~") == "Ghost"
// FixedLengthString("Ghost", 7, "~") == "Ghost "
func FixedLengthString(s string, length int, snipIndicator string) string {
if length > 0 {
lenStr := RuneCountWithoutEscapeSeq(s)
if lenStr < length {
return fmt.Sprintf("%-"+fmt.Sprint(length)+"s", s)
} else if lenStr > length {
lenStrFinal := length - RuneCountWithoutEscapeSeq(snipIndicator)
return TrimTextWithoutEscapeSeq(s, lenStrFinal) + snipIndicator
}
}
return s
}

// GetLongestLineLength returns the length of the longest "line" within the
// argument string. For ex.:
// GetLongestLineLength("Ghost!\nCome back here!\nRight now!") == 15
Expand Down
8 changes: 8 additions & 0 deletions util/string_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ import (
"github.com/stretchr/testify/assert"
)

func TestFixedLengthString(t *testing.T) {
assert.Equal(t, "Ghost", FixedLengthString("Ghost", 0, "~"))
assert.Equal(t, "~", FixedLengthString("Ghost", 1, "~"))
assert.Equal(t, "Gh~", FixedLengthString("Ghost", 3, "~"))
assert.Equal(t, "Ghost", FixedLengthString("Ghost", 5, "~"))
assert.Equal(t, "Ghost ", FixedLengthString("Ghost", 7, "~"))
}

func TestGetLongestLineLength(t *testing.T) {
assert.Equal(t, 0, GetLongestLineLength(""))
assert.Equal(t, 0, GetLongestLineLength("\n\n"))
Expand Down

0 comments on commit 9ff3b65

Please sign in to comment.