Some unicode fonts are now implementing special glyph to render pretty progress bars. Here are some examples: * FiraCode [1] [2] * Iosevka [3] [4] [5] * JuliaMono [3] This change introduces a new parameter, `PrettyProgressBar` that triggers the use of those characters to render progress bars. Here is an example of how it renders with this new option and the FiraCode font: [6] [1] https://github.com/tonsky/FiraCode/releases/tag/6 [2] https://github.com/tonsky/FiraCode/issues/1182 [3] https://github.com/tonsky/FiraCode/issues/1182#issuecomment-1525953517 [4] https://github.com/be5invis/Iosevka/releases/tag/v11.2.0 [5] https://github.com/be5invis/Iosevka/issues/1327 [6] https://i2.paste.pics/OK03I.png Signed-off-by: Lénaïc Huard <lenaic@lhuard.fr> --- doc/pacman.conf.5.asciidoc | 3 + etc/pacman.conf.in | 1 + scripts/completion/zsh_completion.in | 1 + src/pacman/callback.c | 108 ++++++++++++++++----------- src/pacman/conf.c | 3 + src/pacman/conf.h | 2 + src/pacman/pacman-conf.c | 3 + 7 files changed, 76 insertions(+), 45 deletions(-) diff --git a/doc/pacman.conf.5.asciidoc b/doc/pacman.conf.5.asciidoc index 77a3907f..daab30d4 100644 --- a/doc/pacman.conf.5.asciidoc +++ b/doc/pacman.conf.5.asciidoc @@ -186,6 +186,9 @@ Options *Color*:: Automatically enable colors only when pacman's output is on a tty. +*PrettyProgressBar*:: + Use specific U+EE00..U+EE05 unicode characters to render pretty progress bars. + *NoProgressBar*:: Disables progress bars. This is useful for terminals which do not support escape characters. diff --git a/etc/pacman.conf.in b/etc/pacman.conf.in index 1799efc7..9ce2b938 100644 --- a/etc/pacman.conf.in +++ b/etc/pacman.conf.in @@ -31,6 +31,7 @@ Architecture = auto # Misc options #UseSyslog #Color +#PrettyProgressBar #NoProgressBar CheckSpace #VerbosePkgLists diff --git a/scripts/completion/zsh_completion.in b/scripts/completion/zsh_completion.in index 5fd8aebc..e64a603e 100644 --- a/scripts/completion/zsh_completion.in +++ b/scripts/completion/zsh_completion.in @@ -514,6 +514,7 @@ _pacman_conf_general_directives=( 'CheckSpace' 'VerbosePkgLists' 'DisableDownloadTimeout' + 'PrettyProgressBar' 'NoProgressBar' 'ParallelDownloads' 'CleanMethod' diff --git a/src/pacman/callback.c b/src/pacman/callback.c index 75c74f8b..f72a91cf 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -153,54 +153,72 @@ static int64_t get_update_timediff(int first_call) static void fill_progress(const int bar_percent, const int disp_percent, const int proglen) { - /* 8 = 1 space + 1 [ + 1 ] + 5 for percent */ - const int hashlen = proglen > 8 ? proglen - 8 : 0; - const int hash = bar_percent * hashlen / 100; - static int lasthash = 0, mouth = 0; int i; - if(bar_percent == 0) { - lasthash = 0; - mouth = 0; + /* if pretty progress bar enabled */ + if(config->pretty) { + /* 8 = 1 space + 1 + 1 + 5 for percent */ + const int hashlen = proglen > 8 ? proglen - 6 : 0; + const int hash = bar_percent * hashlen / 100; + + if(hashlen > 2) { + fputs(hash > 0 ? " " : " ", stdout); + for(i = hashlen - 1; i > 1; --i) { + fputs(i > hashlen - hash ? "" : "", stdout); + } + fputs(hash == hashlen ? "" : "", stdout); + } + + } else { + /* 8 = 1 space + 1 [ + 1 ] + 5 for percent */ + const int hashlen = proglen > 8 ? proglen - 8 : 0; + const int hash = bar_percent * hashlen / 100; + static int lasthash = 0, mouth = 0; + + if(bar_percent == 0) { + lasthash = 0; + mouth = 0; + } + + if(hashlen > 0) { + fputs(" [", stdout); + for(i = hashlen; i > 0; --i) { + /* if special progress bar enabled */ + if(config->chomp) { + if(i > hashlen - hash) { + putchar('-'); + } else if(i == hashlen - hash) { + if(lasthash == hash) { + if(mouth) { + fputs("\033[1;33mC\033[m", stdout); + } else { + fputs("\033[1;33mc\033[m", stdout); + } + } else { + lasthash = hash; + mouth = mouth == 1 ? 0 : 1; + if(mouth) { + fputs("\033[1;33mC\033[m", stdout); + } else { + fputs("\033[1;33mc\033[m", stdout); + } + } + } else if(i % 3 == 0) { + fputs("\033[0;37mo\033[m", stdout); + } else { + fputs("\033[0;37m \033[m", stdout); + } + } /* else regular progress bar */ + else if(i > hashlen - hash) { + putchar('#'); + } else { + putchar('-'); + } + } + putchar(']'); + } } - if(hashlen > 0) { - fputs(" [", stdout); - for(i = hashlen; i > 0; --i) { - /* if special progress bar enabled */ - if(config->chomp) { - if(i > hashlen - hash) { - putchar('-'); - } else if(i == hashlen - hash) { - if(lasthash == hash) { - if(mouth) { - fputs("\033[1;33mC\033[m", stdout); - } else { - fputs("\033[1;33mc\033[m", stdout); - } - } else { - lasthash = hash; - mouth = mouth == 1 ? 0 : 1; - if(mouth) { - fputs("\033[1;33mC\033[m", stdout); - } else { - fputs("\033[1;33mc\033[m", stdout); - } - } - } else if(i % 3 == 0) { - fputs("\033[0;37mo\033[m", stdout); - } else { - fputs("\033[0;37m \033[m", stdout); - } - } /* else regular progress bar */ - else if(i > hashlen - hash) { - putchar('#'); - } else { - putchar('-'); - } - } - putchar(']'); - } /* print display percent after progress bar */ /* 5 = 1 space + 3 digits + 1 % */ if(proglen >= 5) { @@ -252,7 +270,7 @@ void cb_event(void *ctx, alpm_event_t *event) alpm_event_hook_run_t *e = &event->hook_run; int digits = number_length(e->total); printf("(%*zu/%*zu) %s\n", digits, e->position, - digits, e->total, + digits, e->total, e->desc ? e->desc : e->name); } break; diff --git a/src/pacman/conf.c b/src/pacman/conf.c index 12fee64c..fa38930c 100644 --- a/src/pacman/conf.c +++ b/src/pacman/conf.c @@ -604,6 +604,9 @@ static int _parse_options(const char *key, char *value, } else if(strcmp(key, "ILoveCandy") == 0) { config->chomp = 1; pm_printf(ALPM_LOG_DEBUG, "config: chomp\n"); + } else if(strcmp(key, "PrettyProgressBar") == 0 ) { + config->pretty = 1; + pm_printf(ALPM_LOG_DEBUG, "config: pretty\n"); } else if(strcmp(key, "VerbosePkgLists") == 0) { config->verbosepkglists = 1; pm_printf(ALPM_LOG_DEBUG, "config: verbosepkglists\n"); diff --git a/src/pacman/conf.h b/src/pacman/conf.h index 04350d39..1ac6806f 100644 --- a/src/pacman/conf.h +++ b/src/pacman/conf.h @@ -111,6 +111,8 @@ typedef struct __config_t { /* conf file options */ /* I Love Candy! */ unsigned short chomp; + /* Pretty progress bar */ + unsigned short pretty; /* format target pkg lists as table */ unsigned short verbosepkglists; /* number of parallel download streams */ diff --git a/src/pacman/pacman-conf.c b/src/pacman/pacman-conf.c index 600f1622..3ea4816a 100644 --- a/src/pacman/pacman-conf.c +++ b/src/pacman/pacman-conf.c @@ -267,6 +267,7 @@ static void dump_config(void) show_bool("VerbosePkgLists", config->verbosepkglists); show_bool("DisableDownloadTimeout", config->disable_dl_timeout); show_bool("ILoveCandy", config->chomp); + show_bool("PrettyProgressBar", config->pretty); show_bool("NoProgressBar", config->noprogressbar); show_int("ParallelDownloads", config->parallel_downloads); @@ -379,6 +380,8 @@ static int list_directives(void) show_bool("DisableDownloadTimeout", config->disable_dl_timeout); } else if(strcasecmp(i->data, "ILoveCandy") == 0) { show_bool("ILoveCandy", config->chomp); + } else if(strcasecmp(i->data, "PrettyProgressBar") == 0) { + show_bool("PrettyProgressBar", config->pretty); } else if(strcasecmp(i->data, "NoProgressBar") == 0) { show_bool("NoProgressBar", config->noprogressbar); -- 2.40.1