Richard Suchenwirth 2005-08-05 - When a longer-running process runs in a terminal window, it may be helpful for the user to indicate that it is still active. Here's a simple way of producing some animation on stdout: You store the "phases" you want to display in a variable, and in certain intervals call ascii_animate which will display the first of the phases on stdout, followed by CR but no LF, so the next operation will occur in the same place. Also, the phases list is cycled, with the first element being moved to the end of the list. The example shows a short bar that seems to rotate :)
set phases {- / | \\} proc ascii_animate _var { upvar 1 $_var var puts -nonewline [lindex $var 0]\r flush stdout set var [concat [lrange $var 1 end] [lindex $var 0]] } #-- Test: while 1 { ascii_animate phases after 500 }
RS 2013-12-09: The above test uses a blocking while loop. For practical application, you'd better use an every timer:
every 500 ascii_animate phases
Lectus: And here is a Progress Bar command ready to be used.
It displays like this: (Your message) |###| 30%
#|---------------------------| #| ASCII_ProgressBar command | #|---------------------------| namespace eval ASCII_ProgressBar { variable count 0 variable p "#" variable msg "" proc new {message} { set ASCII_ProgressBar::count 0 set ASCII_ProgressBar::p "#" puts -nonewline "${message} \|| 0%\r" flush stdout set ASCII_ProgressBar::msg $message } proc increase {n {timer 0}} { for {set i 0} {$i < $n} {incr i} {incr ASCII_ProgressBar::count} for {set i 0} {$i < $n} {incr i 10} {append ASCII_ProgressBar::p "\010#\|"} if {[string length $ASCII_ProgressBar::p] == 10} { append ASCII_ProgressBar::p "\010\|"} puts -nonewline "${ASCII_ProgressBar::msg} \|${ASCII_ProgressBar::p} ${ASCII_ProgressBar::count}%\r"; flush stdout; after $timer } namespace export new increase namespace ensemble create } #|----------| #| Examples | #|----------| # First ASCII_ProgressBar new "Computing operation 1..." ASCII_ProgressBar increase 10 500 ASCII_ProgressBar increase 10 500 # simple operation set x 8 ASCII_ProgressBar increase 20 1000 set y 4 #another one ASCII_ProgressBar increase 20 1000 set z [expr $x * $y] ASCII_ProgressBar increase 30 1000 set z [expr $z + 10] ASCII_ProgressBar increase 10 1000 puts "\n\nWe're done and the operation resulted: $z" puts "\n" # Second ASCII_ProgressBar new "Computing operation 2..." ASCII_ProgressBar increase 10 500 ASCII_ProgressBar increase 10 500 # simple operation set x $z ASCII_ProgressBar increase 20 1000 set y 2 #another one ASCII_ProgressBar increase 20 1000 set z [expr $z * $y] ASCII_ProgressBar increase 30 1000 set z [expr $z + 10] ASCII_ProgressBar increase 10 1000 puts "\n\nWe're done and the operation resulted: $z"