d.Decor must always be called
otherwise goroutine leak will happen
Vladimir Bauer
3 years ago
| 454 | 454 | } |
| 455 | 455 | |
| 456 | 456 | func (s *bState) drawImpl(stat decor.Statistics) io.Reader { |
| 457 | decorFiller := func(buf *bytes.Buffer, decorators []decor.Decorator) (int, bool) { | |
| 458 | tw := stat.AvailableWidth | |
| 459 | for _, d := range decorators { | |
| 460 | str := d.Decor(stat) | |
| 461 | if stat.AvailableWidth > 0 { | |
| 462 | stat.AvailableWidth -= runewidth.StringWidth(stripansi.Strip(str)) | |
| 463 | mustWriteString(buf, str) | |
| 464 | } | |
| 465 | } | |
| 466 | return tw, stat.AvailableWidth < 0 | |
| 467 | } | |
| 468 | ||
| 457 | 469 | bufP, bufB, bufA := s.buffers[0], s.buffers[1], s.buffers[2] |
| 458 | tw := stat.AvailableWidth | |
| 459 | for _, d := range s.pDecorators { | |
| 460 | str := d.Decor(stat) | |
| 461 | stat.AvailableWidth -= runewidth.StringWidth(stripansi.Strip(str)) | |
| 462 | mustWriteString(bufP, str) | |
| 463 | } | |
| 464 | if stat.AvailableWidth < 1 { | |
| 465 | trunc := strings.NewReader(runewidth.Truncate(stripansi.Strip(bufP.String()), tw, "…")) | |
| 466 | bufP.Reset() | |
| 467 | return trunc | |
| 468 | } | |
| 469 | ||
| 470 | if !s.trimSpace && stat.AvailableWidth > 1 { | |
| 470 | ||
| 471 | twP, truncateP := decorFiller(bufP, s.pDecorators) | |
| 472 | ||
| 473 | if !s.trimSpace && stat.AvailableWidth >= 2 { | |
| 471 | 474 | mustWriteString(bufB, " ") |
| 472 | 475 | defer mustWriteString(bufB, " ") |
| 473 | 476 | stat.AvailableWidth -= 2 |
| 474 | 477 | } |
| 475 | 478 | |
| 476 | tw = stat.AvailableWidth | |
| 477 | for _, d := range s.aDecorators { | |
| 478 | str := d.Decor(stat) | |
| 479 | stat.AvailableWidth -= runewidth.StringWidth(stripansi.Strip(str)) | |
| 480 | mustWriteString(bufA, str) | |
| 481 | } | |
| 482 | if stat.AvailableWidth < 1 { | |
| 483 | trunc := strings.NewReader(runewidth.Truncate(stripansi.Strip(bufA.String()), tw, "…")) | |
| 479 | twA, truncateA := decorFiller(bufA, s.aDecorators) | |
| 480 | ||
| 481 | if truncateP { | |
| 482 | trunc := strings.NewReader(runewidth.Truncate(stripansi.Strip(bufP.String()), twP, "…")) | |
| 483 | bufP.Reset() | |
| 484 | return trunc | |
| 485 | } | |
| 486 | ||
| 487 | if truncateA { | |
| 488 | trunc := strings.NewReader(runewidth.Truncate(stripansi.Strip(bufA.String()), twA, "…")) | |
| 484 | 489 | bufA.Reset() |
| 485 | 490 | return io.MultiReader(bufP, bufB, trunc) |
| 486 | 491 | } |