From ae93d95bbec22b4d38be93fe779db977ca1dc8a4 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 16 Nov 2022 16:35:15 +0530 Subject: [PATCH] Get progress bar rendering working --- tools/tui/download_with_progress.go | 17 +++++++++++++---- tools/tui/progress-bar.go | 4 +++- tools/tui/progress-bar_test.go | 25 +++++++++++++++++++++++++ tools/wcswidth/wcswidth_test.go | 2 +- 4 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 tools/tui/progress-bar_test.go diff --git a/tools/tui/download_with_progress.go b/tools/tui/download_with_progress.go index fc6868fc1..359bd739d 100644 --- a/tools/tui/download_with_progress.go +++ b/tools/tui/download_with_progress.go @@ -5,6 +5,7 @@ package tui import ( "fmt" "os" + "strings" "sync" "time" @@ -56,13 +57,15 @@ func render_progress(rd *render_data) string { } now := time.Now() duration := now.Sub(rd.started_at) - rate := float64(rd.done) / float64(duration*time.Second) + rate := float64(rd.done) / float64(duration) frac := float64(rd.done) / float64(rd.total) bytes_left := rd.total - rd.done - time_left := time.Duration(float64(bytes_left)/rate) * time.Second + time_left := time.Duration(float64(bytes_left) / rate) + speed := rate * float64(time.Second) before := rd.spinner.Tick() - after := fmt.Sprintf(" %d%% %s/s %s", int(frac*100), humanize.Bytes(uint64(rate)), format_time(time_left)) - available_width := rd.screen_width - len("T 100% 1000MB 11:11:11") + after := fmt.Sprintf(" %d%% %s/s %s", int(frac*100), strings.ReplaceAll(humanize.Bytes(uint64(speed)), " ", ""), format_time(time_left)) + available_width := rd.screen_width - len("T 100% 1000 MB/s 11:11:11") + // fmt.Println("\r\n", frac, available_width) progress_bar := "" if available_width > 10 { progress_bar = " " + RenderProgressBar(frac, available_width) @@ -112,6 +115,12 @@ func DownloadFileWithProgress(destpath, url string, kill_if_signaled bool) (err } redraw := func() { + lp.StartAtomicUpdate() + lp.AllowLineWrapping(false) + defer func() { + lp.AllowLineWrapping(true) + lp.EndAtomicUpdate() + }() lp.QueueWriteString("\r") lp.ClearToEndOfLine() dl_data.mutex.Lock() diff --git a/tools/tui/progress-bar.go b/tools/tui/progress-bar.go index 3d18f0628..7261deb53 100644 --- a/tools/tui/progress-bar.go +++ b/tools/tui/progress-bar.go @@ -47,10 +47,12 @@ func RenderProgressBar(frac float64, width int) string { } ans := fc.Blue(filled) unfilled := "" + ul := 0 if width > fl && needs_break { unfilled = "🬇" + ul = 1 } - filler := width - fl - len(unfilled) + filler := width - fl - ul if filler > 0 { unfilled += RepeatChar("🬋", filler) } diff --git a/tools/tui/progress-bar_test.go b/tools/tui/progress-bar_test.go new file mode 100644 index 000000000..5e0295a76 --- /dev/null +++ b/tools/tui/progress-bar_test.go @@ -0,0 +1,25 @@ +// License: GPLv3 Copyright: 2022, Kovid Goyal, + +package tui + +import ( + "fmt" + "kitty/tools/wcswidth" + "testing" +) + +var _ = fmt.Print + +func TestRenderProgressBar(t *testing.T) { + + test := func(frac float64, width int) { + b := RenderProgressBar(frac, width) + a := wcswidth.Stringwidth(b) + if a != width { + t.Fatalf("Actual length %d != Expected length %d with fraction: %v\n%s", a, width, frac, b) + } + } + test(0.9376609994848016, 47) + test(0.9459041731066461, 47) + test(0.9500257599175682, 47) +} diff --git a/tools/wcswidth/wcswidth_test.go b/tools/wcswidth/wcswidth_test.go index 4a71e80bc..c21f00a2c 100644 --- a/tools/wcswidth/wcswidth_test.go +++ b/tools/wcswidth/wcswidth_test.go @@ -36,7 +36,7 @@ func TestWCSWidth(t *testing.T) { wcswidth("\U0001F1E6\U0001F1E8a", 3) wcswidth("\U0001F1E6\U0001F1E8\U0001F1E6", 4) wcswidth("a\u00adb", 2) - wcswidth("a\x1b[22b", 23) + wcswidth("a\x1b[22bcd", 25) // Flags individually and together wcwidth("\U0001f1ee\U0001f1f3", 2, 2) wcswidth("\U0001f1ee\U0001f1f3", 2)