progress-bar.go 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. // License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
  2. package tui
  3. import (
  4. "fmt"
  5. "kitty/tools/cli/markup"
  6. "strings"
  7. )
  8. var _ = fmt.Print
  9. func RepeatChar(char string, count int) string {
  10. if count <= 5 {
  11. return strings.Repeat(char, count)
  12. }
  13. return fmt.Sprintf("%s\x1b[%db", char, count-1)
  14. }
  15. func RenderProgressBar(frac float64, width int) string {
  16. fc := markup.New(true)
  17. if frac >= 1 {
  18. return fc.Green(RepeatChar("🬋", width))
  19. }
  20. if frac <= 0 {
  21. return fc.Dim(RepeatChar("🬋", width))
  22. }
  23. w := frac * float64(width)
  24. fl := int(w)
  25. overhang := w - float64(fl)
  26. filled := RepeatChar("🬋", fl)
  27. needs_break := false
  28. if overhang < 0.2 {
  29. needs_break = true
  30. } else if overhang < 0.8 {
  31. filled += "🬃"
  32. fl += 1
  33. } else {
  34. if fl < width-1 {
  35. filled += "🬋"
  36. fl += 1
  37. needs_break = true
  38. } else {
  39. filled += "🬃"
  40. fl += 1
  41. }
  42. }
  43. ans := fc.Blue(filled)
  44. unfilled := ""
  45. ul := 0
  46. if width > fl && needs_break {
  47. unfilled = "🬇"
  48. ul = 1
  49. }
  50. filler := width - fl - ul
  51. if filler > 0 {
  52. unfilled += RepeatChar("🬋", filler)
  53. }
  54. if unfilled != "" {
  55. ans += fc.Dim(unfilled)
  56. }
  57. return ans
  58. }