about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--Functions/Zftp/zftp_progress52
2 files changed, 48 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 3ad62c8a9..fa3dc5472 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2001-01-18  Peter Stephenson  <pws@csr.com>
+
+	* 13302: Functions/Zftp/zftp_progress: division by zero
+
 2001-01-16  Sven Wischnowsky  <wischnow@zsh.org>
 
 	* 13365: Src/builtin.c, Src/exec.c, Src/glob.c, Src/hashtable.c,
diff --git a/Functions/Zftp/zftp_progress b/Functions/Zftp/zftp_progress
index e2b5084c4..cc6195661 100644
--- a/Functions/Zftp/zftp_progress
+++ b/Functions/Zftp/zftp_progress
@@ -1,18 +1,54 @@
 # function zftp_progress {
 # Basic progress metre, showing the percent of the file transferred.
-# You want growing bars?  You gotta write growing bars.
+# You want growing bars?  You gottem.
+# styles used (context :zftp:zfparent_function:):
+#   progress
+#       empty or `none'                  no progress meter
+#       `bar'                            use a growing bar of inverse video
+#       `percent' or other non-blank     show the percentage transferred
+#     If size of remote file is not available, `bar' or `percent' just show
+#     bytes.
+#   update
+#       Minimum time in seconds between updates of the progress display.
+
+local style update=1
+
+# What style: either bar for growing bars, or anything else for simple
+# percentage.  For bar we need to have the terminal width in COLUMNS,
+# which is often set automatically, but you never know.
+zstyle -s ":zftp$curcontext" progress style
+# How many seconds to wait before printing an updated progress report.
+zstyle -s ":zftp$curcontext" update update
 
 # Don't show progress unless stderr is a terminal
-[[ ! -t 2 ]] && return 0
+[[ ! -t 2 || $style = (|none) ]] && return 0
 
-if [[ $ZFTP_TRANSFER = *F ]]; then
-  print 1>&2
-elif [[ -n $ZFTP_TRANSFER ]]; then
-  if [[ -n $ZFTP_SIZE ]]; then
-    local frac="$(( ZFTP_COUNT * 100 / ZFTP_SIZE ))%"
-    print -n "\r$ZFTP_FILE ($ZFTP_SIZE bytes): $ZFTP_TRANSFER $frac" 1>&2
+if [[ -n $ZFTP_TRANSFER ]]; then
+  # avoid a `parameter unset' message
+  [[ $ZFTP_TRANSFER != *F ]] &&
+    (( ${+zftpseconds} )) && (( SECONDS - zftpseconds < update )) && return
+  # size is usually ZFTP_SIZE, but zftransfer may set ZFTP_TSIZE
+  local size=${ZFTP_TSIZE:-$ZFTP_SIZE}
+  if [[ ${size:-0} -ne 0 ]]; then
+    local frac="$(( ZFTP_COUNT * 100 / size ))%"
+    if [[ $style = bar && ${+COLUMNS} = 1 && $COLUMNS -gt 0 ]]; then
+      if (( ! ${+zftpseconds} )); then
+	print "$ZFTP_FILE ($size bytes): $ZFTP_TRANSFER" 1>&2
+      fi
+      integer maxwidth=$(( COLUMNS - 7 ))
+      local width="$(( ZFTP_COUNT * maxwidth / size ))"
+      print -nP "\r%S${(l:width:):-}%s${(l:maxwidth-width:):-}: ${frac}%%" 1>&2
+    else
+      print -n "\r$ZFTP_FILE ($size bytes): $ZFTP_TRANSFER $frac" 1>&2
+    fi
   else
     print -n "\r$ZFTP_FILE: $ZFTP_TRANSFER $ZFTP_COUNT" 1>&2
   fi
+  if [[ $ZFTP_TRANSFER = *F && ${+zftpseconds} = 1 ]]; then
+    unset zftpseconds
+    print 1>&2
+  else
+    zftpseconds=$SECONDS
+  fi
 fi
 # }