diff --git a/powerline.go b/powerline.go index 8a92f5c1..e8bbc0eb 100644 --- a/powerline.go +++ b/powerline.go @@ -5,6 +5,8 @@ import ( "fmt" "strings" + "github.com/mattn/go-runewidth" + "golang.org/x/crypto/ssh/terminal" "golang.org/x/text/width" "os" "strconv" @@ -75,17 +77,36 @@ func (p *powerline) appendSegment(origin string, segment segment) { p.Segments = append(p.Segments, segment) } +func termWidth() int { + width, _, err := terminal.GetSize(int(os.Stdout.Fd())) + if err != nil { + shellMaxLengthStr, found := os.LookupEnv("COLUMNS") + if !found { + return 80 // Otherwise 0 default. + } + + shellMaxLength64, err := strconv.ParseInt(shellMaxLengthStr, 0, 64) + if err != nil { + return 80 // Otherwise 0 default. + } + + width = int(shellMaxLength64) + } + + return width +} + func (p *powerline) draw() string { - shellMaxLengthStr, _ := os.LookupEnv("COLUMNS") - shellMaxLength64, _ := strconv.ParseInt(shellMaxLengthStr, 0, 64) - shellMaxLength := int(shellMaxLength64) + shellMaxLength := termWidth() shellMaxLength = shellMaxLength * *p.args.MaxWidthPercentage / 100 shellActualLength := 0 if shellMaxLength > 0 { + rlen := runewidth.StringWidth + for _, segment := range p.Segments { - shellActualLength += len(segment.content) + len(segment.separator) + shellActualLength += rlen(segment.content) + rlen(segment.separator) } for shellActualLength > shellMaxLength { minPriority := MaxInteger @@ -99,7 +120,7 @@ func (p *powerline) draw() string { if minPrioritySegmentId != -1 { segment := p.Segments[minPrioritySegmentId] p.Segments = append(p.Segments[:minPrioritySegmentId], p.Segments[minPrioritySegmentId+1:]...) - shellActualLength -= len(segment.content) + len(segment.separator) + shellActualLength -= rlen(segment.content) + rlen(segment.separator) } } }