add a function to show appointments, callable from .profile
[shellsnippets/shellsnippets.git] / mksh / progress-bar
index 886ddc6..de1ebb5 100644 (file)
@@ -1,6 +1,8 @@
 # -*- mode: sh -*-
 #-
-# Copyright © 2015
+# Copyright © 2017
+#      mirabilos <t.glaser@tarent.de>
+# Copyright © 2015, 2017
 #      mirabilos <thorsten.glaser@teckids.org>
 #
 # Provided that these terms and disclaimer and all copyright notices
@@ -26,7 +28,8 @@
 # – after:   done_progress_bar
 #
 # init_progress_bar trashes the EXIT and SIGWINCH traps, which later
-# are cleared, again, by done_progress_bar.
+# are cleared, again, by done_progress_bar. Note that signals do not
+# work well with “wait” except in a “while [[ -n $(jobs) ]]” loop.
 
 # global variables used by this library
 _cnt_progress_bar=0
@@ -34,42 +37,67 @@ _cur_progress_bar=0
 isin_progress_bar=0
 nlin_progress_bar=0
 
+if [[ $KSH_VERSION = @(\@\(#\)MIRBSD KSH R)@(5[5-9]|[6-9][0-9]|[1-9][0-9][0-9])\ * ]]; then
+       alias global='typeset -g'
+else
+       alias global=global
+fi
+
 # args: $1 = number of draw_progress_bar calls to make up 100%
 function init_progress_bar {
        global -i _cnt_progress_bar=$1 _cur_progress_bar=0
        global -i nlin_progress_bar=$LINES isin_progress_bar=1
 
-       trap 'done_progress_bar' EXIT
+       trap 'done_progress_bar 1' EXIT
        trap 'sigwinch_progress_bar' WINCH
-       # newline; up one line (to ensure we are not in the last line);
-       # save position; set scrolling region; restore position
-       print -n "\\n\\e[A\\e7\\e[1;$((# nlin_progress_bar - 1))r\\e8"
+       # set up scrolling region, draw initial empty bar
+       sigwinch_progress_bar
 }
 
+unalias global
+
 function sigwinch_progress_bar {
        (( isin_progress_bar )) || return 0
 
        # get new terminal size
        nlin_progress_bar=$LINES
-       # newline; up one line (to ensure we are not in the last line);
-       # save position; set scrolling region; restore position
-       print -n "\\n\\e[A\\e7\\e[1;$((# nlin_progress_bar - 1))r\\e8"
+
+       # save position; clear scrolling region; restore position; newline;
+       # up one line (to ensure we are not in the last line); save position;
+       # clear rest of screen; set new scrolling region; restore position
+       print -nu2 "\\e7\\e[0;0r\\e8\\n\\e[A\\e7\\e[J\\e[1;$((# nlin_progress_bar - 1))r\\e8"
+
+       # redraw progress bar
+       draw_progress_bar_internal
 }
 
 function done_progress_bar {
        (( isin_progress_bar )) || return 0
-       # save position; clear scrolling region;
-       # go to last line; delete line; restore position
-       print "\\e7\\e[0;0r\\e[$nlin_progress_bar;0H\\e[M\\e8"
        isin_progress_bar=0
+       # 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 )) || \
+           print -ru2 W: expected $_cnt_progress_bar draw_progress_bar calls, \
+           got only $_cur_progress_bar
 }
 
 function draw_progress_bar {
+       # increment current progress
+       if (( ++_cur_progress_bar > _cnt_progress_bar )); then
+               print -ru2 "W: too many draw_progress_bar calls"
+               _cur_progress_bar=$_cnt_progress_bar
+       fi
+       # remaining drawing code
+       draw_progress_bar_internal
+}
+
+function draw_progress_bar_internal {
        local bar num w=$COLUMNS
 
-       ((# num = (++_cur_progress_bar * w * 8) / _cnt_progress_bar ))
+       ((# num = (_cur_progress_bar * w * 8) / _cnt_progress_bar ))
        while ((# num >= 8 )); do
                bar+=█
                ((# num -= 8 ))
@@ -90,5 +118,5 @@ function draw_progress_bar {
        # 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 -n -- "\\e7\\e[$nlin_progress_bar;0H\\e[0;1;33;44m$spc\\r$bar\\e8"
+       print -nu2 -- "\\e7\\e[$nlin_progress_bar;1H\\e[0;1;33;44m$spc\\r$bar\\e8"
 }