merge improvements from MirBSD CVS:
[shellsnippets/shellsnippets.git] / mksh / progress-bar
index 3864ae2..12b4353 100644 (file)
@@ -1,5 +1,5 @@
 # -*- mode: sh -*-
-# $MirOS: contrib/hosted/tg/progress-bar,v 1.2 2018/12/02 07:01:17 tg Exp $
+# $MirOS: contrib/hosted/tg/progress-bar,v 1.4 2018/12/02 08:12:31 tg Exp $
 #-
 # Copyright © 2018
 #      mirabilos <m@mirbsd.org>
@@ -40,6 +40,7 @@ _cnt_progress_bar=0
 _cur_progress_bar=0
 isin_progress_bar=0
 nlin_progress_bar=0
+_cch_progress_bar=
 
 if [[ $KSH_VERSION = @(\@\(#\)MIRBSD KSH R)@(5[5-9]|[6-9][0-9]|[1-9][0-9][0-9])\ * ]]; then
        alias global='typeset -g'
@@ -51,8 +52,9 @@ fi
 function init_progress_bar {
        global -i _cnt_progress_bar=$1 _cur_progress_bar=0
        global -i nlin_progress_bar=$LINES isin_progress_bar=1
+       _cch_progress_bar=
 
-       trap 'done_progress_bar 1' EXIT
+       trap 'done_progress_bar $?' EXIT
        trap 'sigwinch_progress_bar' WINCH
        # set up scrolling region, draw initial empty bar
        sigwinch_progress_bar
@@ -78,12 +80,14 @@ function sigwinch_progress_bar {
 function done_progress_bar {
        (( isin_progress_bar )) || return 0
        isin_progress_bar=0
+       _cch_progress_bar=
        # save position; clear scrolling region; restore position;
        # save position; clear rest of screen; restore position
        print -nu2 "\\e7\\e[0;0r\\e8\\e7\\e[J\\e8"
        trap - WINCH
        trap - EXIT
-       [[ -n $1 ]] || (( _cur_progress_bar == _cnt_progress_bar )) || \
+       [[ -z $1 ]] || return $1
+       (( _cur_progress_bar == _cnt_progress_bar )) || \
            print -ru2 W: expected $_cnt_progress_bar draw_progress_bar calls, \
            got only $_cur_progress_bar
 }
@@ -111,13 +115,16 @@ function redo_progress_bar {
                    after $_cur_progress_bar calls
                _cur_progress_bar=$_cnt_progress_bar
        fi
+       _cch_progress_bar=
        draw_progress_bar_internal
 }
 
 function draw_progress_bar_internal {
-       local bar num w=$COLUMNS
+       local bar num w=$COLUMNS pct
 
        ((# num = (_cur_progress_bar * w * 8) / _cnt_progress_bar ))
+       ((# pct = _cur_progress_bar * 100 / _cnt_progress_bar ))
+       [[ $_cch_progress_bar != $num.$pct ]] || return 0
        while ((# num >= 8 )); do
                bar+=█
                ((# num -= 8 ))
@@ -132,11 +139,12 @@ function draw_progress_bar_internal {
        (1) bar+=▏ ;;
        }
        # fill complete line, right-align completion percentage display
-       local -R$w spc="$((# _cur_progress_bar * 100 / _cnt_progress_bar))%"
+       local -R$w spc="$pct%"
        # elide percentage when it stops fitting
        ((# (_cur_progress_bar * w / _cnt_progress_bar) > (w - 4) )) && spc=
        # save position; go to last line; set colours;
        # output a line full of spaces (and completion percentage);
        # jump to first column; output bar (line præfix); restore position
        print -nu2 -- "\\e7\\e[$nlin_progress_bar;1H\\e[0;1;33;44m$spc\\r$bar\\e8"
+       _cch_progress_bar=$num.$pct
 }