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