diff mbox series

[bug#59975] guix: Show better progress bars.

Message ID 20221211190059.51c44520@sybil.lepiller.eu
State New
Headers show
Series [bug#59975] guix: Show better progress bars. | expand

Commit Message

Julien Lepiller Dec. 11, 2022, 6 p.m. UTC
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?

Comments

Julien Lepiller Dec. 21, 2022, 4:20 p.m. UTC | #1
Hi Guix!

The patch is pretty simple, but I'm surprised nobody bikeshedded yet :)

Thoughts?

Le 11 décembre 2022 19:00:59 GMT+01:00, Julien Lepiller <julien@lepiller.eu> a écrit :
>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?
Simon Tournier Jan. 6, 2023, 5:45 p.m. UTC | #2
Hi Julien,

> Le 11 décembre 2022 19:00:59 GMT+01:00, Julien Lepiller <julien@lepiller.eu> a écrit :

>>1.1MiB/s 00:04 ▕███               ▏  17.1%
>>1.2MiB/s 00:05 ▕███▋              ▏  20.7%

On Wed, 21 Dec 2022 at 17:20, Julien Lepiller <julien@lepiller.eu> wrote:

> The patch is pretty simple, but I'm surprised nobody bikeshedded yet :)

Personally, I am not fan of fancy Unicode. :-)  But the patch LGTM.

Well, if there is no strong objection and since it is more than 25 days,
maybe you could apply it after waiting a couple more of days. :-)

Cheers,
simon
Ludovic Courtès Jan. 13, 2023, 5:07 p.m. UTC | #3
Hello!

Julien Lepiller <julien@lepiller.eu> skribis:

> 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.

Woow, fancy!  Love it!!  Too bad I was too late to have it under the
Newtonmas tree. 🎄

> 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.

One question: how likely is it that people won’t have a font with those
glyphs to display it correctly?

It would be good to check in xterm, Linux console with some default
font, and GNOME/Xfce terminals with defaults.

(Works for me in xterm and in Emacs, FWIW.)

>>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.

Please describe all the changes.

> +(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))

How about just dropping the ‘default’ bits and being explicit here?

> +  (let* ((bar-style (if (equal? (port-encoding (current-output-port)) "UTF-8")
> +                        unicode-bar-style
> +                        ascii-bar-style))

In theory you want to check for Unicode-capable, not UTF-8-encoded.

There are ways to do that (see ‘right-arrow’ in (guix ui)), but it’s
more expensive and trickier, so what you’re doing here is good enough
IMO (I actually did that in (guix scripts weather) too).

> +         (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"

s/format/simple-format/ for slightly better performance.

Otherwise LGTM, thanks!

Ludo’.
Christopher Baines Feb. 12, 2023, 10:02 a.m. UTC | #4
Julien Lepiller <julien@lepiller.eu> writes:

> Here's the new version, it's now a small series. The first patch sets
> unifont as default, so we can see the fancy bars in a TTY :) The second
> hasn't changed.
>
> Julien Lepiller (2):
>   gnu: Use unifont by default in TTYs.
>   guix: Show better progress bars.
>
>  gnu/services/base.scm |  7 +++----
>  guix/progress.scm     | 45 ++++++++++++++++++++++++++++++++++++-------
>  2 files changed, 41 insertions(+), 11 deletions(-)
>
>
> base-commit: 92755c6352fd967bc74d8e5354aad057d779b717

I haven't tried this out, but the changes look good to me :)

Thanks,

Chris
Julien Lepiller Feb. 19, 2023, 9:11 a.m. UTC | #5
Finally pushed to master as 01334a61c7541d8ae29c5252e2e5b3ed7a59c552
and 189525412e3d803f3f77e15ec4a62aaa57f65a2d.

Le Sun, 12 Feb 2023 10:02:50 +0000,
Christopher Baines <mail@cbaines.net> a écrit :

> Julien Lepiller <julien@lepiller.eu> writes:
> 
> > Here's the new version, it's now a small series. The first patch
> > sets unifont as default, so we can see the fancy bars in a TTY :)
> > The second hasn't changed.
> >
> > Julien Lepiller (2):
> >   gnu: Use unifont by default in TTYs.
> >   guix: Show better progress bars.
> >
> >  gnu/services/base.scm |  7 +++----
> >  guix/progress.scm     | 45
> > ++++++++++++++++++++++++++++++++++++------- 2 files changed, 41
> > insertions(+), 11 deletions(-)
> >
> >
> > base-commit: 92755c6352fd967bc74d8e5354aad057d779b717  
> 
> I haven't tried this out, but the changes look good to me :)
> 
> Thanks,
> 
> Chris
diff mbox series

Patch

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(-)

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