diff --git a/barely.go b/barely.go index 3e9d7c1..9578995 100644 --- a/barely.go +++ b/barely.go @@ -8,6 +8,7 @@ import ( "strings" "sync" "text/template" + "unicode" ) var ( @@ -22,6 +23,8 @@ type StatusBar struct { last string status interface{} + + width int } // NewStatusBar returns new StatusBar object, initialized with given template. @@ -33,6 +36,12 @@ func NewStatusBar(format *template.Template) *StatusBar { } } +func (bar *StatusBar) SetWidth(w int) { + bar.Lock() + defer bar.Unlock() + bar.width = w +} + // Lock locks StatusBar object if locker object was set with SetLock method // to prevent multi-threading race conditions. // @@ -86,6 +95,11 @@ func (bar *StatusBar) Render(writer io.Writer) error { ) } + if str := buffer.String(); bar.width > 0 && graphicLength(str) > bar.width { + buffer.Reset() + buffer.WriteString(trimTo(str, bar.width)) + } + fmt.Fprintf(buffer, "\r") bar.last = escapeSequenceRegexp.ReplaceAllLiteralString( @@ -104,6 +118,26 @@ func (bar *StatusBar) Render(writer io.Writer) error { return nil } +func graphicLength(str string) int { + c := 0 + for _, r := range str { + if unicode.IsGraphic(r) { + c++ + } + } + + return c +} + +func trimTo(str string, l int) string { + orig := []rune(str) + if len(orig) < 4 { + return str + } + + return string(orig[:l-3]) + "…" +} + // Clear writes clear sequence in the specified writer, which is represented by // whitespace sequence followed by "\r". func (bar *StatusBar) Clear(writer io.Writer) {