For Development HEAD DRAFTSearch (procedure/syntax/module):

12.76 text.progress - Showing progress on text terminals

Module: text.progress

This module provides a utility to report a progress of processing on a text terminal, using characters to display bar chart.

The generic format of a progress bar consists of a single line of text, which is splitted into several parts; a header, which displays the title; followed by a bar, a numeric part, and a time part, as shown in the following example (only the line beginning with “foo” is actually displayed).

<-header-> <-------bar---------> <-num-><-time->      <---info---->
foo       |#############        |123/211   01:21 ETA  compiling...
          ^
          separator

Various things like the character used in the bar chart or the format of the numeric progress can be configured.

Internally a progress bar maintains two numbers, the maximum (goal) value and the current value. The bar shows the proportion of the current value relative to the maximum value. The numeric progress shows the current value over the maximum value by default, but you can configure it to show only the current value or percentage, for example.

A progress bar also has two states, “in progress” and “finished”. When it is in progress, every time the text is displayed it is followed by #\return, so that the next display overwrites the bar, and the time part shows ETA (estimated time of arrival). Once it becomes finished, the last line of text is displayed with #\newline, and the time part shows the actual time it took to finish.

This module provides only one procedure, make-text-progress-bar, which packages the progress bar feature in a closure and returns it.

Function: make-text-progress-bar :key header header-width bar-char bar-width num-width num-format time-width info info-width separator-char max-value port

{text.progress} Returns a procedure that packages operations on the progress bar. The procedure can be called with a symbol indicating an operation, and an optional numeric argument.

proc 'show

Redisplays the progress bar. All other operations implies redisplay, so you don’t need to use this unless you have a specific reason to redisplay the current state.

proc 'set value

Sets the current value to value, then redisplays the progress bar. If value exceeds the max value, it is clipped by the max value.

proc 'inc value

Increments the current value by value, then redisplays the progress bar. If the current value exceeds the max value, it is clipped by the max value.

proc 'finish

Puts the progress bar to the “finished” state, then redisplays it. The time part shows the total elapsed time, and the line is terminated by #\newline so that it won’t be clobbered. Once a progress bar becomes “finished”, there’s no way to put it back “in progress”.

proc 'set-info text

Changes the text displayed in the “info” part. To use the info part, you have to give a positive value to info-width keyword argument of make-text-progress-bar.

proc 'set-header text

Changes the text displayed in the “header’ area.

The keyword arguments are used to customize the display:

header

The text to be displayed in the header part. This can be changed later, by sending set-header message to the created progress bar.

header-width

The width of the header part, in number of characters. The header text is displayed left-aligned in the part. If the header text is longer than the width, the excess characters are omitted. The default is 14.

bar-char

A character used to draw a bar chart. The default is #\#.

bar-width

The width of the bar chart part, in number of characters. The default is 40.

num-width

The width of the numeric part, in number of characters. The default is 9. Setting this to 0 hides the numeric part.

num-format

A procedure to format the numeric part. Two arguments are passed; the current value and the maximum value. It must return a string. The default is the following procedure.

(lambda (cur max)
  (format "~d/~d" cur max))
time-width

The width of the time part, in number of characters. The default is 7. Settings this to 0 hides the time part.

info

The text to be displayed in the info part. This text can be changed later by sending set-info message to the created progress bar. Note that you have to give a positive number to info-width keyword argument to enable the info part.

info-width

The width of the info part. The default value is zero, which means the info part is not displayed.

separator-char

A character put around the bar part. Default is #\|. You can pass #f not to display the separators.

max-value

The maximum value of the progress bar. Must be a positive real number. Default is 100.

port

An output port to which the progress bar is displayed. The default value is the current output port when make-text-progress-bar is called.

Here’s a simple example, using customized numeric part:

(use text.progress)

(define (main args)
  (define (num-format cur max)
    (format "~d/~d(~3d%)" cur max
            (round->exact (/. (* cur 100) max))))

  (let ((p (make-text-progress-bar :header "Example"
                                   :header-width 10
                                   :bar-char #\o
                                   :num-format num-format
                                   :num-width 13
                                   :max-value 256)))
    (do ((i 0 (+ i 1)))
        ((= i 256) (p 'finish))
      (p 'inc 1)
      (sys-select #f #f #f 50000))))


For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT