From: "SZEDER Gábor" <szeder.dev@gmail.com>
To: Junio C Hamano <gitster@pobox.com>
Cc: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
"Jeff King" <peff@peff.net>, "Duy Nguyen" <pclouds@gmail.com>,
"Luke Mewburn" <luke@mewburn.net>,
git@vger.kernel.org, "SZEDER Gábor" <szeder.dev@gmail.com>
Subject: [PATCH v2 0/4] Progress display fixes
Date: Mon, 1 Apr 2019 13:52:13 +0200 [thread overview]
Message-ID: <20190401115217.3423-1-szeder.dev@gmail.com> (raw)
In-Reply-To: <20190325103844.26749-1-szeder.dev@gmail.com>
This patch series fixes two progress display issues:
- When showing throughput, and the both the total and the throughput
change units in the same update, than the previously shown
progress bar is not cleaned up properly:
Receiving objects: 25% (2901/11603), 772.01 KiB | 733.00 KiB/s
Receiving objects: 27% (3133/11603), 1.43 MiB | 1.16 MiB/s s
- When the progress bar is longer than the width of the terminal,
then we end up with a bunch of truncated progress bar lines
scrolling past:
$ LANG=es_ES.UTF-8 git commit-graph write
Encontrando commits para commit graph entre los objetos empaquetados: 2% (1599
Encontrando commits para commit graph entre los objetos empaquetados: 3% (1975
Encontrando commits para commit graph entre los objetos empaquetados: 4% (2633
Encontrando commits para commit graph entre los objetos empaquetados: 5% (3292
[...]
Patches 3 and 4 fix these two issues, while the first three are
minor preparatory cleanups and refactorings.
Changes since v1:
- Use utf8_strwidth().
- Dropped patch 2/5 (progress: return early when in the background).
Consequently, the new patch 2/4 (progress: assemble percentage and
counters in a strbuf before printing; was patch 3/5 in v1) moves
the is_foreground_fd() check around a bit, resulting in enough
changes that range-diff can't match the new patch 3/4 to the old
4/5. With increased '--creation-factor' it's able to line up
those two patches, and shows the updates to the commit message,
but the resulting diff-of-a-diff looks utterly unreadable to me.
I've included an interdiff as well, as I find it much more
telling.
- Commit message updates.
SZEDER Gábor (4):
progress: make display_progress() return void
progress: assemble percentage and counters in a strbuf before printing
progress: clear previous progress update dynamically
progress: break too long progress bar lines
progress.c | 73 +++++++++++++++++++++++++++++++++++++++---------------
progress.h | 2 +-
2 files changed, 54 insertions(+), 21 deletions(-)
Interdiff:
diff --git a/progress.c b/progress.c
index 97bc4b04e8..e28ccdafd2 100644
--- a/progress.c
+++ b/progress.c
@@ -86,19 +86,13 @@ static void display(struct progress *progress, uint64_t n, const char *done)
{
const char *tp;
struct strbuf *counters_sb = &progress->counters_sb;
- int update = 0;
+ int show_update = 0;
int last_count_len = counters_sb->len;
if (progress->delay && (!progress_update || --progress->delay))
return;
progress->last_value = n;
-
- if (!is_foreground_fd(fileno(stderr)) && !done) {
- progress_update = 0;
- return;
- }
-
tp = (progress->throughput) ? progress->throughput->display.buf : "";
if (progress->total) {
unsigned percent = n * 100 / progress->total;
@@ -110,35 +104,39 @@ static void display(struct progress *progress, uint64_t n, const char *done)
"%3u%% (%"PRIuMAX"/%"PRIuMAX")%s", percent,
(uintmax_t)n, (uintmax_t)progress->total,
tp);
- update = 1;
+ show_update = 1;
}
} else if (progress_update) {
strbuf_reset(counters_sb);
strbuf_addf(counters_sb, "%"PRIuMAX"%s", (uintmax_t)n, tp);
- update = 1;
+ show_update = 1;
}
- if (update) {
- const char *eol = done ? done : "\r";
- int clear_len = counters_sb->len < last_count_len ?
- last_count_len - counters_sb->len : 0;
- int cols = term_columns();
-
- if (progress->split) {
- fprintf(stderr, " %s%-*s", counters_sb->buf, clear_len,
- eol);
- } else if (!done &&
- cols < progress->title_len + counters_sb->len + 2) {
- clear_len = progress->title_len + 1 < cols ?
- cols - progress->title_len - 1 : 0;
- fprintf(stderr, "%s:%*s\n %s%s", progress->title,
- clear_len, "", counters_sb->buf, eol);
- progress->split = 1;
- } else {
- fprintf(stderr, "%s: %s%-*s", progress->title,
- counters_sb->buf, clear_len, eol);
+ if (show_update) {
+ if (is_foreground_fd(fileno(stderr)) || done) {
+ const char *eol = done ? done : "\r";
+ int clear_len = counters_sb->len < last_count_len ?
+ last_count_len - counters_sb->len : 0;
+ int progress_line_len = progress->title_len +
+ counters_sb->len + 2;
+ int cols = term_columns();
+
+ if (progress->split) {
+ fprintf(stderr, " %s%-*s", counters_sb->buf,
+ clear_len, eol);
+ } else if (!done && cols < progress_line_len) {
+ clear_len = progress->title_len + 1 < cols ?
+ cols - progress->title_len - 1 : 0;
+ fprintf(stderr, "%s:%*s\n %s%s",
+ progress->title, clear_len, "",
+ counters_sb->buf, eol);
+ progress->split = 1;
+ } else {
+ fprintf(stderr, "%s: %s%-*s", progress->title,
+ counters_sb->buf, clear_len, eol);
+ }
+ fflush(stderr);
}
- fflush(stderr);
progress_update = 0;
}
@@ -242,7 +240,7 @@ static struct progress *start_progress_delay(const char *title, uint64_t total,
progress->throughput = NULL;
progress->start_ns = getnanotime();
strbuf_init(&progress->counters_sb, 0);
- progress->title_len = strlen(title);
+ progress->title_len = utf8_strwidth(title);
progress->split = 0;
set_progress_signal();
return progress;
Range-diff:
1: dea36bd2a7 = 1: dea36bd2a7 progress: make display_progress() return void
2: 159a0b9561 < -: ---------- progress: return early when in the background
3: ecd6b0fd68 ! 2: 97de2a98a0 progress: assemble percentage and counters in a strbuf before printing
@@ -4,10 +4,11 @@
The following patches in this series want to handle the progress bar's
title and changing parts (i.e. the counter and the optional percentage
- and throughput combined) differently.
+ and throughput combined) differently, and need to know the length
+ of the changing parts of the previously displayed progress bar.
To prepare for those changes assemble the changing parts in a separate
- strbuf before printing.
+ strbuf kept in 'struct progress' before printing.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
@@ -29,24 +30,25 @@
- const char *eol, *tp;
+ const char *tp;
+ struct strbuf *counters_sb = &progress->counters_sb;
-+ int update = 0;
++ int show_update = 0;
if (progress->delay && (!progress_update || --progress->delay))
return;
-@@
- }
+ progress->last_value = n;
tp = (progress->throughput) ? progress->throughput->display.buf : "";
- eol = done ? done : " \r";
if (progress->total) {
unsigned percent = n * 100 / progress->total;
if (percent != progress->last_percent || progress_update) {
progress->last_percent = percent;
-- fprintf(stderr, "%s: %3u%% (%"PRIuMAX"/%"PRIuMAX")%s%s",
-- progress->title, percent,
-- (uintmax_t)n, (uintmax_t)progress->total,
-- tp, eol);
-- fflush(stderr);
+- if (is_foreground_fd(fileno(stderr)) || done) {
+- fprintf(stderr, "%s: %3u%% (%"PRIuMAX"/%"PRIuMAX")%s%s",
+- progress->title, percent,
+- (uintmax_t)n, (uintmax_t)progress->total,
+- tp, eol);
+- fflush(stderr);
+- }
- progress_update = 0;
- return;
+
@@ -55,22 +57,24 @@
+ "%3u%% (%"PRIuMAX"/%"PRIuMAX")%s", percent,
+ (uintmax_t)n, (uintmax_t)progress->total,
+ tp);
-+ update = 1;
++ show_update = 1;
}
} else if (progress_update) {
-- fprintf(stderr, "%s: %"PRIuMAX"%s%s",
-- progress->title, (uintmax_t)n, tp, eol);
+ strbuf_reset(counters_sb);
+ strbuf_addf(counters_sb, "%"PRIuMAX"%s", (uintmax_t)n, tp);
-+ update = 1;
++ show_update = 1;
+ }
+
-+ if (update) {
-+ const char *eol = done ? done : " \r";
++ if (show_update) {
+ if (is_foreground_fd(fileno(stderr)) || done) {
+- fprintf(stderr, "%s: %"PRIuMAX"%s%s",
+- progress->title, (uintmax_t)n, tp, eol);
++ const char *eol = done ? done : " \r";
+
-+ fprintf(stderr, "%s: %s%s", progress->title, counters_sb->buf,
-+ eol);
- fflush(stderr);
++ fprintf(stderr, "%s: %s%s", progress->title,
++ counters_sb->buf, eol);
+ fflush(stderr);
+ }
progress_update = 0;
- return;
}
4: e360365f18 ! 3: edfe0157a7 progress: clear previous progress update dynamically
@@ -10,7 +10,7 @@
Alas, covering only three characters is not quite enough: when both
the total and the throughput happen to change units from KiB to MiB in
the same update, then the progress bar's length is shortened by four
- characters:
+ characters (or maybe even more!):
Receiving objects: 25% (2901/11603), 772.01 KiB | 733.00 KiB/s
Receiving objects: 27% (3133/11603), 1.43 MiB | 1.16 MiB/s s
@@ -21,11 +21,10 @@
the length of the current progress bar with the previous one, and
cover up as many characters as needed.
- Sure, it would be much simpler to just print four spaces instead of
- three at the end of the progress bar, but this approach is more
- future-proof, and it won't print extra spaces when none are needed,
- notably when the progress bar doesn't show throughput and thus never
- shrinks.
+ Sure, it would be much simpler to just print more spaces at the end of
+ the progress bar, but this approach is more future-proof, and it won't
+ print extra spaces when none are needed, notably when the progress bar
+ doesn't show throughput and thus never shrinks.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
@@ -35,24 +34,24 @@
@@
const char *tp;
struct strbuf *counters_sb = &progress->counters_sb;
- int update = 0;
+ int show_update = 0;
+ int last_count_len = counters_sb->len;
if (progress->delay && (!progress_update || --progress->delay))
return;
@@
- }
- if (update) {
-- const char *eol = done ? done : " \r";
+ if (show_update) {
+ if (is_foreground_fd(fileno(stderr)) || done) {
+- const char *eol = done ? done : " \r";
-
-- fprintf(stderr, "%s: %s%s", progress->title, counters_sb->buf,
-- eol);
-+ const char *eol = done ? done : "\r";
-+ int clear_len = counters_sb->len < last_count_len ?
-+ last_count_len - counters_sb->len : 0;
-+ fprintf(stderr, "%s: %s%-*s", progress->title,
-+ counters_sb->buf, clear_len, eol);
- fflush(stderr);
+- fprintf(stderr, "%s: %s%s", progress->title,
+- counters_sb->buf, eol);
++ const char *eol = done ? done : "\r";
++ int clear_len = counters_sb->len < last_count_len ?
++ last_count_len - counters_sb->len : 0;
++ fprintf(stderr, "%s: %s%-*s", progress->title,
++ counters_sb->buf, clear_len, eol);
+ fflush(stderr);
+ }
progress_update = 0;
- }
5: cbd3be1c6d ! 4: d53de231ee progress: break too long progress bar lines
@@ -69,35 +69,37 @@
static volatile sig_atomic_t progress_update;
@@
- const char *eol = done ? done : "\r";
- int clear_len = counters_sb->len < last_count_len ?
- last_count_len - counters_sb->len : 0;
-- fprintf(stderr, "%s: %s%-*s", progress->title,
-- counters_sb->buf, clear_len, eol);
-+ int cols = term_columns();
+ const char *eol = done ? done : "\r";
+ int clear_len = counters_sb->len < last_count_len ?
+ last_count_len - counters_sb->len : 0;
+- fprintf(stderr, "%s: %s%-*s", progress->title,
+- counters_sb->buf, clear_len, eol);
++ int progress_line_len = progress->title_len +
++ counters_sb->len + 2;
++ int cols = term_columns();
+
-+ if (progress->split) {
-+ fprintf(stderr, " %s%-*s", counters_sb->buf, clear_len,
-+ eol);
-+ } else if (!done &&
-+ cols < progress->title_len + counters_sb->len + 2) {
-+ clear_len = progress->title_len + 1 < cols ?
-+ cols - progress->title_len - 1 : 0;
-+ fprintf(stderr, "%s:%*s\n %s%s", progress->title,
-+ clear_len, "", counters_sb->buf, eol);
-+ progress->split = 1;
-+ } else {
-+ fprintf(stderr, "%s: %s%-*s", progress->title,
-+ counters_sb->buf, clear_len, eol);
-+ }
- fflush(stderr);
++ if (progress->split) {
++ fprintf(stderr, " %s%-*s", counters_sb->buf,
++ clear_len, eol);
++ } else if (!done && cols < progress_line_len) {
++ clear_len = progress->title_len + 1 < cols ?
++ cols - progress->title_len - 1 : 0;
++ fprintf(stderr, "%s:%*s\n %s%s",
++ progress->title, clear_len, "",
++ counters_sb->buf, eol);
++ progress->split = 1;
++ } else {
++ fprintf(stderr, "%s: %s%-*s", progress->title,
++ counters_sb->buf, clear_len, eol);
++ }
+ fflush(stderr);
+ }
progress_update = 0;
- }
@@
progress->throughput = NULL;
progress->start_ns = getnanotime();
strbuf_init(&progress->counters_sb, 0);
-+ progress->title_len = strlen(title);
++ progress->title_len = utf8_strwidth(title);
+ progress->split = 0;
set_progress_signal();
return progress;
--
2.21.0.539.g07239c3a71.dirty
next prev parent reply other threads:[~2019-04-01 11:52 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-25 10:38 [PATCH 0/5] Progress display fixes SZEDER Gábor
2019-03-25 10:38 ` [PATCH 1/5] progress: make display_progress() return void SZEDER Gábor
2019-03-25 10:38 ` [PATCH 2/5] progress: return early when in the background SZEDER Gábor
2019-03-25 11:08 ` Ævar Arnfjörð Bjarmason
2019-03-25 11:39 ` SZEDER Gábor
2019-03-26 6:28 ` Luke Mewburn
2019-03-26 5:38 ` Jeff King
2019-03-25 10:38 ` [PATCH 3/5] progress: assemble percentage and counters in a strbuf before printing SZEDER Gábor
2019-03-26 5:45 ` Jeff King
2019-03-27 10:24 ` SZEDER Gábor
2019-03-28 2:12 ` Jeff King
2019-03-25 10:38 ` [PATCH 4/5] progress: clear previous progress update dynamically SZEDER Gábor
2019-03-25 10:38 ` [PATCH 5/5] progress: break too long progress bar lines SZEDER Gábor
2019-03-25 11:02 ` Duy Nguyen
2019-03-25 11:12 ` SZEDER Gábor
2019-03-26 5:52 ` [PATCH 0/5] Progress display fixes Jeff King
2019-04-01 11:52 ` SZEDER Gábor [this message]
2019-04-01 11:52 ` [PATCH v2 1/4] progress: make display_progress() return void SZEDER Gábor
2019-04-02 5:42 ` Eric Sunshine
2019-04-01 11:52 ` [PATCH v2 2/4] progress: assemble percentage and counters in a strbuf before printing SZEDER Gábor
2019-04-02 5:45 ` Eric Sunshine
2019-04-02 5:50 ` Eric Sunshine
2019-04-01 11:52 ` [PATCH v2 3/4] progress: clear previous progress update dynamically SZEDER Gábor
2019-04-01 13:30 ` Jeff King
2019-04-01 14:15 ` SZEDER Gábor
2019-04-02 14:27 ` Jeff King
2019-04-01 11:52 ` [PATCH v2 4/4] progress: break too long progress bar lines SZEDER Gábor
2019-04-05 0:45 ` [PATCH v3 0/4] Progress display fixes SZEDER Gábor
2019-04-05 0:45 ` [PATCH v3 1/4] progress: make display_progress() return void SZEDER Gábor
2019-04-05 0:45 ` [PATCH v3 2/4] progress: assemble percentage and counters in a strbuf before printing SZEDER Gábor
2019-04-05 0:45 ` [PATCH v3 3/4] progress: clear previous progress update dynamically SZEDER Gábor
2019-04-05 0:45 ` [PATCH v3 4/4] progress: break too long progress bar lines SZEDER Gábor
2019-04-05 22:21 ` [PATCH v3 0/4] Progress display fixes Jeff King
2019-04-12 19:45 ` [PATCH v4 " SZEDER Gábor
2019-04-12 19:45 ` [PATCH v4 1/4] progress: make display_progress() return void SZEDER Gábor
2019-04-12 19:45 ` [PATCH v4 2/4] progress: assemble percentage and counters in a strbuf before printing SZEDER Gábor
2019-04-12 19:45 ` [PATCH v4 3/4] progress: clear previous progress update dynamically SZEDER Gábor
2019-04-12 19:45 ` [PATCH v4 4/4] progress: break too long progress bar lines SZEDER Gábor
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190401115217.3423-1-szeder.dev@gmail.com \
--to=szeder.dev@gmail.com \
--cc=avarab@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=luke@mewburn.net \
--cc=pclouds@gmail.com \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.