The following examples show how to use the CLI_Progress bar.

Simple Progress Bar


Using the default properties, start, update, and finish a progress bar.

cli_progress.initialize
for i = 0, 100 do begin & $
  wait, 0.02 & $ ; your code here
  cli_progress.update, i & $
endfor

One should see a progress bar appear on the IDL console/terminal and it should fill up to 100%:

100% [########################################]

Setting and Using Properties


Properties should be set in one of two ways: Either through the use of keywords to CLI_Progress.Initialize or through the use of the dot(.) operator. For example:

pro cli_example
  LengthOfLoop = 1000
  ; Using Initialize to set Properties
  CLI_Progress.Initialize, width = 10, maximum = LengthOfLoop
   
  for i = 0, LengthOfLoop do begin
    ; Using the dot operator to set a property
    if i eq LengthOfLoop then begin
      CLI_Progress.complete_char = "X"
    endif
    CLI_Progress.Update, i
    wait, 0.002 ; your code here
  endfor
end

One should see a progress bar of width 10 appear in the IDL console/terminal and it should fill up to 100%:

Upon reaching 100% all the characters should change to X's

100.0% [XXXXXXXXXX]

Using a Ping Pong Bar


The ping pong bar is a type of marquee loader that bounces the COMPLETE_CHAR string back and forth along the length of the loading bar. For example:

CLI_Progress.Initialize, ping_pong = !true, complete_char = "<IDL>"
for i = 0,114 do begin & $
  CLI_Progress.Update & $
  wait, 0.02 & $
endfor

The word <IDL> bounces back and forth:

[-----------------------------------<IDL>-----]

 

For the next example we make the ping pong text reverse direction when it goes back from right to left:

CLI_Progress.Initialize, ping_pong = !true, complete_char = "--+"
cli_Progress.reverse = !true
cli_Progress.incomplete_char = "."
for i = 0,114 do begin & $
  CLI_Progress.Update & $
  wait, 0.02 & $
endfor

IDL prints:

[...................................--+.....]

 

Normally, a ping pong bar does not display a percentage since it does not have a maximum. However, if we add a maximum then we can display a percent:

CLI_Progress.Initialize, ping_pong = !true, complete_char = "<IDL>", maximum = 114, /percent
for i = 0,114 do begin & $
  CLI_Progress.Update & $
  wait, 0.02 & $
endfor

IDL prints:

100.0% [----------------------------------<IDL>------]

Exit Early and Print Messages


Normally, CLI_Progress captures the cursor in order to print the progress bar. If you want to display a message partway through, or you want to abandon the progress bar before its completed, you can use the CLI_Progress::Erase or CLI_Progress::Newline methods.

 

If we just want to return the Console to its default configuration we will use.CLI_Progress::Newline

pro cli_example_newline
  LengthOfLoop = 1000
  CLI_Progress.Initialize, width = 10, maximum = LengthOfLoop
   
  for i = 0, LengthOfLoop do begin
    ;Here we are going to abandon our progress bar due to an "error"
    if i eq 500 then begin
      CLI_Progress.Newline
      print, "ERROR!"
      break
    endif
    CLI_Progress.Update, i
    wait, 0.002
  endfor
end

One should see a progress bar of width 10 appear and it should fill up to 49%. Then IDL will print "ERROR!" on a new line:

 49.9% [####------]
ERROR!

 

If you don’t want to abandon your progress bar but rather want to print above it. One would accomplish this with CLI_Progress::Erase. By doing this you clear the line you are currently on up for normal printing. After you can print normally. Once you are done printing whatever you wish normally CLI_Progress::Update will re-secure your cursor and continue the progress bar.

pro cli_example_erase
  LengthOfLoop = 1000
  CLI_Progress.Initialize, width = 10, maximum = LengthOfLoop
   
  for i = 0, LengthOfLoop do begin
    ;Here we are going to print a warning
    if i eq 500 then begin
      CLI_Progress.Erase
      print,"WARNING!"
    endif
    CLI_Progress.Update, i
    wait,.002
  endfor
end

You should see your progress bar fill to 49% at which point it will spew a "warning" and then continue the bar. As below.

WARNING
100.0% [##########]

Finish and AUTO_FINISH


By default CLI_Progress will automatically finish when the current update step equals the MAXIMUM property value. Instead, you can turn this feature off and manually finish. For example:

pro cli_example_finish
  CLI_Progress.Initialize, preset = "retro", auto_finish = !false
  ; Here, we will hit 100% multiple times, which would normally cause finish to be called.
  array = [[1:100],1,100,1,100]
  foreach element, array do begin
    CLI_Progress.Update, element
    wait,.1
  endforeach
  ; Instead, we need to manually call Finish
  CLI_Progress.Finish
end

You should see the progress bar fill to 100% then flash between

[|] 100% [========================================]

and

[|]   1% [----------------------------------------]

before finishing.

Tip: CLI_Progress::Finish can also be called at any time, even if auto_finish is still turned on. It will just finish your bar wherever it may happen to be.

Using Multiple Characters for the Complete/Incomplete Strings


WIDTH, COMPLETE_CHAR, and INCOMPLETE_CHAR are all unaware of each other: If you change one of these to have multiple characters, you may need to adjust the other properties to match. For example

pro cli_example_multi
  CLI_Progress.Initialize
   
  ;These can be done in Initialize but for fun let's change them using dot operators.
   
  ; I want each step of my progress bar to fill using "+-"
  CLI_Progress.complete_char = "+-"
   
  ; Because of this each instance of INCOMPLETE_CHAR will be replaced with "+-"
  ; So I will need to compensate by using two dots
  CLI_Progress.incomplete_char = ".."
   
  ; I will also have to compensate WIDTH as it just places instances of COMPLETE/INCOMPLETE_CHAR
  ; 20 = 40 / 2 (length of our "Char's")
  CLI_Progress.width = 20
   
  for i = 0,100 do begin
    CLI_Progress.Update
    wait,.02
  endfor
   
  ; Same example but set all the properties on the Initialize call.
  CLI_Progress.Initialize, complete_char = "+-", incomplete_char = "..", width = 20
  for i = 0,100 do begin
    CLI_Progress.Update
    wait,.02
  endfor
end

The output should look similar to.

100% [+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-]
14% [+-+-....................................]

Using REMAINING


REMAINING allows you to add an estimate of the time until completion.

pro cli_example_remaining
  CLI_PROGRESS.INITIALIZE, /REMAINING
  store = []
  for i = 0,100 do begin
    CLI_PROGRESS.UPDATE
    wait,.5
  endfor
end

The output should look similar to.

 15% [######----------------------------------] 42s Remaining

Using OUTPUT


OUTPUT allows you to capture your output instead of printing it. You will need to pass in a named variable.

pro cli_example_output
  CLI_Progress.Initialize
  store = []
  for i = 0,100 do begin
    CLI_Progress.Update, output = progressOut
    wait,.02
    store = [store, progressOut]
  endfor
  print,store, /implied
end

Complicated Example


Below is a fake loading sequence that shows off several abilities of the CLI_Progress bar tool at once.

pro fakeLoadMapStack
  CLI_Progress.Initialize, maximum = 100, width = 30, complete_char = "=-",incomplete_char = "__", $
    title = "Loading Modules Please wait...", auto_finish = !false
   
  for i=0,100 do begin
    if i gt 30 then cli_progress.title = "Prepping textures..."
    cli_Progress.update, i
    wait,.03
  endfor
   
  CLI_Progress.auto_finish = !True
  CLI_Progress.spinner = 4
  CLI_Progress.title = "Loading to Map"
  for i=0,100 do begin
    CLI_Progress.Update, i
     
    if i eq 70 then begin
      CLI_Progress.Newline
      print, "ERROR: MapStack not initialized"
      print, "Aborting and trying secondary image"
      print, "Abort successful"
      wait,.5
      break
    endif
     
    wait,.03
  endfor
   
  CLI_Progress.initialize, title = "Finalizing", ping_pong = !true, complete_char = "<O>"
  for i=0,300 do begin
    CLI_Progress.Update, i
    wait,.01
  endfor
  CLI_Progress.finish, text = "[SUCCESS]"
   
  CLI_Progress.initialize, title = "Resolving and installing", auto_finish = !false
  for i=0,100 do begin
    wait,.03
    if i eq 30 then begin
      CLI_Progress.Erase
      print, "Warning: Non-Standard MapStack"
      print, "This might have unintended consequences."
    endif
     
    CLI_Progress.Update, i
  endfor
  CLI_Progress.finish, text = "[SUCCESS]"
end

Version History


9.1

Introduced

See Also


CLI_Progress