(address . guix-patches@gnu.org)
Hi Guix!
The attached patch is a small improvement on our progress bars. Instead
of our cute ASCII art:
1.2MiB/s 00:04 [### ] 18.5%
We get something a little more smooth:
1.1MiB/s 00:04 ???? ? 17.1%
1.2MiB/s 00:05 ????? ? 20.7%
Using unicode characters that can represent 1/8 of a character width.
I used port-encoding to detect when the output supports unicode, but
maybe there's something more dedicated to figuring that out? When the
port encoding is not UTF-8, we fall back to the ASCII version.
Thoughts?
From c428c80fd628797ae80029a0a22678ef55c68d6c Mon Sep 17 00:00:00 2001
From: Julien Lepiller <julien@lepiller.eu>
Date: Sun, 11 Dec 2022 18:51:13 +0100
Subject: [PATCH] guix: Show better progress bars.
* guix/progress.scm (progress-bar): When supported, use unicode variant.
---
guix/progress.scm | 43 ++++++++++++++++++++++++++++++++++++-------
1 file changed, 36 insertions(+), 7 deletions(-)
Toggle diff (59 lines)
diff --git a/guix/progress.scm b/guix/progress.scm
index 4f8e98edc0..527bf72839 100644
--- a/guix/progress.scm
+++ b/guix/progress.scm
@@ -166,16 +166,45 @@ (define current-terminal-columns
;; Number of columns of the terminal.
(make-parameter 80))
+(define-record-type* <progress-bar-style>
+ progress-bar-style make-progress-bar-style progress-bar-style?
+ (start progress-bar-style-start
+ (default #\x2595))
+ (stop progress-bar-style-stop
+ (default #\x258f))
+ (filled progress-bar-style-filled
+ (default #\x2588))
+ (steps progress-bar-style-steps
+ (default '(#\x258F #\x258E #\x258D #\x258C #\x258B #\x258A #\x2589))))
+
+(define unicode-bar-style (progress-bar-style))
+(define ascii-bar-style
+ (progress-bar-style
+ (start #\[)
+ (stop #\])
+ (filled #\#)
+ (steps '())))
+
(define* (progress-bar % #:optional (bar-width 20))
"Return % as a string representing an ASCII-art progress bar. The total
width of the bar is BAR-WIDTH."
- (let* ((bar-width (max 3 (- bar-width 2)))
- (fraction (/ % 100))
- (filled (inexact->exact (floor (* fraction bar-width))))
- (empty (- bar-width filled)))
- (format #f "[~a~a]"
- (make-string filled #\#)
- (make-string empty #\space))))
+ (let* ((bar-style (if (equal? (port-encoding (current-output-port)) "UTF-8")
+ unicode-bar-style
+ ascii-bar-style))
+ (bar-width (max 3 (- bar-width 2)))
+ (intermediates (+ (length (progress-bar-style-steps bar-style)) 1))
+ (step (inexact->exact (floor (/ (* % bar-width intermediates) 100))))
+ (filled (quotient step intermediates))
+ (intermediate
+ (list-ref (cons #f (progress-bar-style-steps bar-style))
+ (modulo step intermediates)))
+ (empty (- bar-width filled (if intermediate 1 0))))
+ (format #f "~a~a~a~a~a"
+ (string (progress-bar-style-start bar-style))
+ (make-string filled (progress-bar-style-filled bar-style))
+ (if intermediate (string intermediate) "")
+ (make-string empty #\space)
+ (string (progress-bar-style-stop bar-style)))))
(define (erase-current-line port)
"Write an ANSI erase-current-line sequence to PORT to erase the whole line and
--
2.38.1