Giter Club home page Giter Club logo

indicatif's People

Contributors

afontenot avatar aj-bagwell avatar arxanas avatar benkay86 avatar chris-laplante avatar danieleades avatar dependabot[bot] avatar djc avatar djugei avatar durka avatar happenslol avatar ishitatsuyuki avatar kpcyrd avatar lecyberducky avatar lucab avatar marienz avatar messense avatar mibac138 avatar mitsuhiko avatar nlinker avatar oli-obk avatar rdruon avatar redzic avatar rlee287 avatar sigmasd avatar smoelius avatar tgolsson avatar wankkoree avatar willcrichton avatar x0f5c3 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

indicatif's Issues

Indicatif's progress bar panics if `set_message()` is too long

If set_message() is too long and "squeezes" the progress bar too much, it panics with attempt to subtract with overflow'.

Minimal example:

extern crate indicatif;
use indicatif::ProgressBar;

fn main() {
    let pb = ProgressBar::new(100);
    pb.set_style(
        indicatif::ProgressStyle::default_bar()
            .template("{wide_bar:.cyan/blue} {pos:>6}/{len:6} {msg}"),
    );
    for i in 0..100 {
        pb.inc(1);
        pb.set_message(&format!(
            "*********************************************************************************************************************************"
        ));
        std::thread::sleep_ms(10);
    }
    pb.finish();
}

Backtrace:

 -> echo $COLUMNS && cargo run
143
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/tind`
██░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░      1/100
thread 'main' panicked at 'attempt to subtract with overflow', /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:309:37
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::_print
             at libstd/sys_common/backtrace.rs:71
   2: std::panicking::default_hook::{{closure}}
             at libstd/sys_common/backtrace.rs:59
             at libstd/panicking.rs:380
   3: std::panicking::default_hook
             at libstd/panicking.rs:396
   4: std::panicking::begin_panic
             at libstd/panicking.rs:576
   5: std::panicking::begin_panic
             at libstd/panicking.rs:537
   6: std::panicking::try::do_call
             at libstd/panicking.rs:521
   7: std::panicking::try::do_call
             at libstd/panicking.rs:497
   8: <core::ops::range::Range<Idx> as core::fmt::Debug>::fmt
             at libcore/panicking.rs:71
   9: <core::ops::range::Range<Idx> as core::fmt::Debug>::fmt
             at libcore/panicking.rs:51
  10: indicatif::progress::ProgressStyle::format_state
             at /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:309
  11: indicatif::progress::draw_state
             at /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:666
  12: indicatif::progress::ProgressBar::draw
             at /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:652
  13: indicatif::progress::ProgressBar::update_and_draw
             at /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:648
  14: indicatif::progress::ProgressBar::inc::{{closure}}
             at /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:573
  15: tind::main
             at src/main.rs:12
  16: std::rt::lang_start::{{closure}}
             at /Users/travis/build/rust-lang/rust/src/libstd/rt.rs:74
  17: std::panicking::try::do_call
             at libstd/rt.rs:59
             at libstd/panicking.rs:479
  18: panic_unwind::dwarf::eh::read_encoded_pointer
             at libpanic_unwind/lib.rs:102
  19: rust_panic
             at libstd/panicking.rs:458
             at libstd/panic.rs:358
             at libstd/rt.rs:58
  20: std::rt::lang_start
             at /Users/travis/build/rust-lang/rust/src/libstd/rt.rs:74

Related to #45.

Is it possible to use MultiProgress with Rayon?

It's my first time using Rayon and Indicatif so apologies if this is a naive question. I'm trying to use Rayon to iterate over a set of files. Code is like this:

    let mp = MultiProgress::new();

    // Long calculation is running. Bars are created but do not paint.
    let total_bytes: u64 = config.input_files.par_iter()
        .map(|f| process_log_file(&mp, f))
        .sum();
    
    // This appears first.
    println!("Rayon iteration complete");

    // Then the bars appear (and update themselves 0..100%) when we get to here.
    // But by this point we are done!
    mp.join().unwrap();

Inside process_log_file I am creating a new ProgressBar, adding it to mp, incrementing it and eventually calling finish.

As the comments say, the problem is that nothing appears until Rayon's par_iter has actually finished doing work. You have lots of examples of using thread::spawn and a tokio example, but I couldn't see anything like this.

Is there a fix I can make or is it impossible at the moment?

For reference, the current code in complete form is at https://github.com/PhilipDaniels/log-file-processor/blob/f-rewrite/src/main.rs

Thanks for any advice you can offer.

MultiProgress with lots of progress bars

If you specify more progress bars than rows in your terminal window then it prints all the progress bars as new lines - it doesn't erase them properly.

I guess ideally it would maintain an internal buffer of what the output should be and only try to print the visible lines. When the terminal is resized it could reveal more lines.

[Feature Request] Add a `percent` key to templates

Request for a convenient feature of having a percent key added to the ProgressStyle template.

The value of this percent key would be the result of bytes / total_bytes

Motivation

This is really helpful when showing progress as a percentage .e.g. 50%

Regression: ETA calculation shows "00:00:00" for the first ten ticks.

indicatif 0.9 used to show a good ETA estimate after the the first .inc(1) update, but 0.10 seems to require around ten .inc(1) calls until it shows the first ETA that is non-zero.

In my use case, a single "tick" can easily last multiple seconds, so this is easy to notice. Minimal example to reproduce:

extern crate indicatif;

use std::thread;
use std::time::Duration;

use indicatif::{ProgressBar, ProgressStyle};

fn main() {
    let count = 15;
    let pb = ProgressBar::new(count);

    pb.set_style(
        ProgressStyle::default_bar()
            .template("{wide_bar} Elapsed: {elapsed_precise}, ETA: {eta_precise}")
    );

    for _ in 0..count {
        thread::sleep(Duration::from_millis(1000));
        pb.inc(1);
    }
    pb.finish_with_message("done");
}

After 9 seconds, it still shows:

███████████████████░░░░░░░░░░░░░ Elapsed: 00:00:09, ETA: 00:00:00

Add a default clear mode

ProgressBar::finish should clear with a style default setting. This would also help Drop automatically clear progress bars if wanted.

eg:

let style = ProgressStyle::new().clear_on_finish(true);

Then the progress bar will automatically disappear if someone calls finish() on it.

time_per_step() should return f64, not Duration.

Currently, the Estimate::time_per_step returns Duration. This limits the precision and range that time per step can represent – Duration always stores multiples of nanosecods. Moreover, if your step takes less than nanosecond, time per step would be 0, and the ETA would be always 00:00:00. This is how I discovered the bug.

TLDR: Here is list of speeds that indicatif currently supports: :)
…, ¼GB/s, ⅓GB/s, ½GB/s, 1GB/s, ∞YB/s.

Add File Wrappers

It would be great if one can directly wrap files so it works with io::copy and others.

Add a way to reset draw_next

I'm reusing a progress bar in a similar fashion to the one described in #49. When I advance to the next step I reset the position to 0, update length to the appropriate value and reset_eta(). My problem is that the progress bar does not update until it's position is greater than or equal to the length of the bar from the previous step. I believe this is happening because of this line if new_pos >= state.draw_next.

Avoid clearing lines?

For me, using MultiProgress results in tons of flickering as the update step clears all the bars and redraws. Maybe this is because I'm using the program through ssh, but it's annoying.

I tried changing the call to term.clear_last_lines to term.move_cursor_up and it's way way better. Is there a reason not to do this?

I'm imagining there could be problems if the number of bars doesn't stay constant, so maybe it would have to be an option.

Indicatif's progress bar panics if template is too large

If I set a template that is too large for the terminal window, the inc() call panics.

Minimal example:

extern crate indicatif;
use indicatif::ProgressBar;

fn main() {
    let pb = ProgressBar::new(100);
    pb.set_style(indicatif::ProgressStyle::default_bar()
            .template("{wide_bar:.cyan/blue} {pos:>6}/{len:6} ************************************************************************************************************************************************************************************"));
    for i in 0..100 {
        pb.inc(1);
        std::thread::sleep_ms(10);
    }
    pb.finish();
}

Backtrace:

 -> echo $COLUMNS && cargo run
143
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/tind`
thread 'main' panicked at 'attempt to subtract with overflow', /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:309:37
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::_print
             at libstd/sys_common/backtrace.rs:71
   2: std::panicking::default_hook::{{closure}}
             at libstd/sys_common/backtrace.rs:59
             at libstd/panicking.rs:380
   3: std::panicking::default_hook
             at libstd/panicking.rs:396
   4: std::panicking::begin_panic
             at libstd/panicking.rs:576
   5: std::panicking::begin_panic
             at libstd/panicking.rs:537
   6: std::panicking::try::do_call
             at libstd/panicking.rs:521
   7: std::panicking::try::do_call
             at libstd/panicking.rs:497
   8: <core::ops::range::Range<Idx> as core::fmt::Debug>::fmt
             at libcore/panicking.rs:71
   9: <core::ops::range::Range<Idx> as core::fmt::Debug>::fmt
             at libcore/panicking.rs:51
  10: indicatif::progress::ProgressStyle::format_state
             at /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:309
  11: indicatif::progress::draw_state
             at /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:666
  12: indicatif::progress::ProgressBar::draw
             at /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:652
  13: indicatif::progress::ProgressBar::update_and_draw
             at /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:648
  14: indicatif::progress::ProgressState::eta
             at /Users/nbigaouette/.cargo/registry/src/github.com-1ecc6299db9ec823/indicatif-0.9.0/src/progress.rs:534
  15: tind::main
             at src/main.rs:9
  16: std::rt::lang_start::{{closure}}
             at /Users/travis/build/rust-lang/rust/src/libstd/rt.rs:74
  17: std::panicking::try::do_call
             at libstd/rt.rs:59
             at libstd/panicking.rs:479
  18: panic_unwind::dwarf::eh::read_encoded_pointer
             at libpanic_unwind/lib.rs:102
  19: rust_panic
             at libstd/panicking.rs:458
             at libstd/panic.rs:358
             at libstd/rt.rs:58
  20: std::rt::lang_start
             at /Users/travis/build/rust-lang/rust/src/libstd/rt.rs:74
  21: tind::main

Note that the above panic happens for a terminal window of width 143 columns.

Cannot join MultiProgress with hidden ProgressBars

I seem to be unable to join a MultiProgress containing hidden ProgressBars. I would have expected this to work, or alternatively to be able to figure out a workaround from the documentation.

#[test]
fn hangs() {
    let m = MultiProgress::new();

    let p = m.add(ProgressBar::new(1));
    p.set_draw_target(ProgressDrawTarget::hidden());
    p.finish_and_clear();
 
    m.join_and_clear();
}

Add Iterator Wrapper

It should be possible to easily render progress bars when working with iterators.

Eg:

let pb = ProgressBar::new(length);
for item in pb.wrap_iter(something.iter()) {
    ...
}

Would be roughly similar to this:

let pb = ProgressBar::new(length);
for item in something.iter() {
    ...
    pb.inc(1);
}

This would work well with #6.

ETA not reset when restarting progress bar

I'm using a single progress bar to show the progress of a series of steps, by resetting progress and length whenever advancing to the next step. It seems like that confuses the ETA, though. It ends up way overestimating (~minutes rather than ~seconds).

enable_steady_tick doesn't work if one doesn't call tick or set_message continuously

After reading the docs I was expecting that one could create a spinner ProgressBar, set enable_steady_tick(200)on it and it would be automatically ticked and rendered every 200 ms.

But when I tried that the spinner is not updating or re-drawn automatically, unless I also call either ticker set_message` on the progress bar manually, which sort of defeats the point of it.

This can be reproduced in the cargowrap.rs example by simply commenting out the pb.set_messageand pb.tick calls. Doing that will cause the spinner to be stuck.

Or am I misunderstanding how enable_steady_tickis intended to work?

Single-threaded MultiProgress

MultiProgress seems to conflate support for displaying and update multiple progress bars concurrently and support for updating progress bars from multiple threads. It would be nice to isolate these so that a single thread performing multiple tasks can effectively use MultiProgress. Inter-thread communication could perhaps even be left up to the user.

Easy way to create cool progress bars

I briefly tried out the library and was disappointed by the default progress bar. It'd be nice if the GIFs were linked to an example of the progress bar that it's showing.

Broken template rendering with opt-level=z and lto=true

Hello,

using rustc 1.32.0, ProgressBar rendering is broken when using opt-level=z.

I get the raw template (only total_bytes is actually templated):

{spinner:.green} [{elapsed_precise}] [{bar:30.cyan/blue}] {bytes}/207.49MB (4s)

instead of:

⠒ [00:00:01] [####>-------------------------] 27.67MB/207.49MB (6s)

Here is my code:

let pb = ProgressBar::new(size as u64);
            pb.set_style(ProgressStyle::default_bar()
                .template("{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {bytes}/{total_bytes} ({eta})")
                .progress_chars("#>-"));
            pb.enable_steady_tick(200);
            let mut progress = gpm::file::FileProgressWriter::new(
                file,
                size,
                |p : usize, _t : usize| {
                    pb.set_position(p as u64);
                }
            );

            lfs::resolve_lfs_link(
                remote.parse().unwrap(),
                Some(refspec.clone()),
                &package_path,
                &mut progress,
                key,
                passphrase,
            ).map_err(CommandError::IO)?;

            pb.finish();

It works as expected when setting opt-level = "s" or lto = false.

You can easily reproduce the issue by adding:

[profile.release]
opt-level = "z"
lto = true

to Cargo.toml and run cargo run --release --example download.

Progress bar and spinner won't update without .inc(1)

This commit: 7a13000 has made it so that unless there's a change to the current value, no update will happen. This means that, unless I also want to increase the value:

  • .set_message() has no effect
  • .tick() has no effect
  • .set_style() has no effect
  • .set_length() has no effect

An immediate fix would be to make ProgressState.draw_delta and ProgressState.draw_next default to 0 instead of 1, so that all updates are applied immediately by default, and let the draw delta behavior be opt-in for those who need performance.

A better fix would be to apply this draw delta logic only to .inc() calls, but I can't see an easy way to do that. Alternatively, keep another counter that gets updated every time .update_and_draw() is called, and track that against draw_delta.

If you have an idea for how to approach this I can work on a pull request if you'd like.

ProgressBar panics if set_position or inc exceeds length.

extern crate indicatif;
use indicatif::ProgressBar;

fn main() {
    let pb = ProgressBar::new(1);
    pb.inc(2);
    pb.finish();
}
thread 'main' panicked at 'attempt to subtract with overflow', src/progress.rs:220
stack backtrace:
   0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
             at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::_print
             at /checkout/src/libstd/sys_common/backtrace.rs:71
   2: std::panicking::default_hook::{{closure}}
             at /checkout/src/libstd/sys_common/backtrace.rs:60
             at /checkout/src/libstd/panicking.rs:355
   3: std::panicking::default_hook
             at /checkout/src/libstd/panicking.rs:371
   4: std::panicking::rust_panic_with_hook
             at /checkout/src/libstd/panicking.rs:549
   5: std::panicking::begin_panic
             at /checkout/src/libstd/panicking.rs:511
   6: std::panicking::begin_panic_fmt
             at /checkout/src/libstd/panicking.rs:495
   7: rust_begin_unwind
             at /checkout/src/libstd/panicking.rs:471
   8: core::panicking::panic_fmt
             at /checkout/src/libcore/panicking.rs:69
   9: core::panicking::panic
             at /checkout/src/libcore/panicking.rs:49
  10: indicatif::progress::ProgressStyle::format_bar
             at ./src/progress.rs:220
  11: indicatif::progress::ProgressStyle::format_state
             at ./src/progress.rs:269
  12: indicatif::progress::ProgressBar::draw
             at ./src/progress.rs:539
  13: indicatif::progress::ProgressBar::update_and_draw
             at ./src/progress.rs:526
  14: indicatif::progress::ProgressBar::set_position
             at ./src/progress.rs:445
  15: single::main
             at ./examples/single.rs:6
  16: std::panicking::try::do_call
             at /checkout/src/libstd/panicking.rs:454
  17: __rust_maybe_catch_panic
             at /checkout/src/libpanic_unwind/lib.rs:98
  18: std::rt::lang_start
             at /checkout/src/libstd/panicking.rs:433
             at /checkout/src/libstd/panic.rs:361
             at /checkout/src/libstd/rt.rs:57
  19: main
  20: __libc_start_main
  21: _start

MSYS terminals don't update current line

Spawned off from rustwasm/wasm-pack#284 (comment), but on the current master in an MSYS terminal you get:

$ cargo run --example log
...
    Finished dev [unoptimized + debuginfo] target(s) in 30.03s
     Running `target\debug\examples\log.exe`
[+] finished #0
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/100
[+] finished #1
█░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 1/100
[+] finished #2
██░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 2/100
[+] finished #3
███░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 3/100
[+] finished #4
███░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 4/100
[+] finished #5
████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 5/100
[+] finished #6
█████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 6/100
[+] finished #7
██████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 7/100
[+] finished #8
██████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 8/100
[+] finished #9
███████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 9/100
[+] finished #10
████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 10/100
[+] finished #11
████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 11/100
[+] finished #12
█████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 12/100

Confusion about stdout

Maybe I am misunderstanding something but

  • here it says that progress bars default to stdout
  • here it says that progress bars default to stderr

Windows 10 MSYS2 terminal cant print result of finish_with_message

Running the following sample code in ms windows 10 and msys2, power shell don't produce the outputs of finish_with_message function:

use std::thread;
use std::time::Duration;
use indicatif::ProgressBar;
 
fn main() {
     let pb = indicatif::ProgressBar::new(100);
 
     for _i in 0..100 {
         pb.inc(1);
         thread::sleep(Duration::from_millis(500));
     }
 
     pb.finish_with_message("done");
 }

Weird behaviour when calling set_position and set_message together

Minimal example:

let bar = ProgressBar::new(100);
bar.set_style(
    indicatif::ProgressStyle::default_bar()
        .template("[{bar:60}] [{percent}%] {msg}")
        .progress_chars("=> "),
);

for i in 0..10 {
    std::thread::sleep_ms(1000);
    bar.set_message(&i.to_string());
    bar.set_position(i * 10);
}

The progress bar looks like

[======>                                                     ] [10%] 2

Note the percent and message are out of sync. If I add enable_steady_tick to the progress bar they sync up, but if I do

for i in 0..10 {
    std::thread::sleep_ms(1000);
    bar.set_message(&i.to_string());
    bar.set_position(i * 10);
    bar.tick();
}

I get the same issue. If I add some delay between the calls like

for i in 0..10 {
    std::thread::sleep_ms(900);
    bar.set_message(&i.to_string());
    std::thread::sleep_ms(100);
    bar.set_position(i * 10);
}

it works fine apart from the 100ms delay when the percent and message are out of sync

Edit: After looking at the code it looks like this is due to the refresh rate cap set by ProgressDrawTarget, and is intended behaviour. I have created a PR to hopefully make this more obvious to new users of the library.

Better ETA when resuming progress

I didn't find anything in the API to handle resuming some kind of progress and get an accurate ETA.

My use case is equivalent to resuming a 12h long download after 10% has been already downloaded.

Right now I just recreate a progress bar and set_position to the amount of data that has already been downloaded. The ETA displayed is then strongly biased because from indicatif point of view, 10% were downloaded in a few seconds.

Feature request: Show iteration rate

Hi,

I'm coming from tqdm in Python and one of my favourite features there is that it shows the current iteration rate, e.g. [229.00it/s]:

76%|████████████████████████████         | 7568/10000 [00:33<00:10, 229.00it/s]

This is particularly useful if you're watching a process where a slow-down or uptake in iterations can indicate an issue.

I would be great to have something similar in indicatif, so I just wanted to open this issue to start discussing.

From a quick skim over both projects we'd obviously need a formatter in https://github.com/mitsuhiko/indicatif/blob/master/src/style.rs#L116.
It'd also need slightly advanced tracking of iteration times, see avg_time here: https://github.com/tqdm/tqdm/blob/master/tqdm/_tqdm.py#L1011

The smoothing of recent iteration times is really useful, and often more interesting than just total time divided by iterations.

I could imagine the same being useful for e.g. the download example, in addition to seeing 71/220MB are done you'd also know you're getting 15MB/sec.

Edit: Looks like we already have https://github.com/mitsuhiko/indicatif/blob/master/src/utils.rs#L18, so this might be easier than expected.

No output on MSYS terminals

When using an MSYS terminal on Windows I unfortunately get no output when using indicatif which can be seen notably by executing the examples. Opening up a prompt and executing cargo run --example log unfortunately produces no output :(

Last print not visible when using progress bar

I have found that the last print is not done when I am using the progress bar. Here is a minimum working case of this behavior. When we remove the progress bar incrementation it works again (the last print is visible).

extern crate indicatif;
use indicatif::ProgressBar;

fn main() {
    let n_data = 1_000;
    let pb = ProgressBar::new(n_data as u64);
    for _ in 0..n_data {  
        pb.inc(1);
    }
    println!("Visible");
    println!("Not visible");
}

Is there some option to correct it ?

MultiProgress bar flickers

Hello,
My program updates bar quite heavy and I found that it cause MultiProgressBar looks quite bad - it flickers all the time.
I run examples from the crate and see the same problem for multibar and finebars.

Did check examples in windows console, but I see the same problem with my program on linux+putty.

I suppose it could be connected to #18

Regards,

Colorized output is dependent on stdout being a tty

It seems that the default implementation draws to stderr, but whether the output is colorized is dependent on whether stdout is a tty, so if you do something like foo > log, you get progress bars, but they're uncolored.

I'm not sure if there's a reasonable fix here without a lot of rearchitecting: it seems to me that console needs to be in charge of printing a styled string, to be able to know whether it should be colorized or not.

Panic involving string slicing in indicatif::utils::pad_str

We got a report of a panic in the wasm-pack issue tracker that seems to be some bad string slicing in indicatif::utils::pad_str:

Relevant portion of the stack trace:

   6:     0x561b9a7eab33 - std::panicking::rust_panic_with_hook::h0e12cb2fc86d00fa
                        at libstd/panicking.rs:481
   7:     0x561b9a7ea699 - std::panicking::continue_panic_fmt::h141671b29fe0e27d
                        at libstd/panicking.rs:391
   8:     0x561b9a7ea595 - rust_begin_unwind
                        at libstd/panicking.rs:326
   9:     0x561b9a83f6cb - core::panicking::panic_fmt::h429a06507aba9228
                        at libcore/panicking.rs:77
  10:     0x561b9a8417df - core::str::slice_error_fail::he7f58755ae0832f9
                        at libcore/str/mod.rs:0
  11:     0x561b9a630967 - core::str::traits::<impl core::slice::SliceIndex<str> for core::ops::range::RangeTo<usize>>::index::{{closure}}::h0e5e8ea169b43852
  12:     0x561b9a630f6f - indicatif::utils::pad_str::h2463675fdede442d
  13:     0x561b9a626cab - indicatif::progress::draw_state::h53128cfecbded1e8
  14:     0x561b9a626434 - indicatif::progress::ProgressBar::set_message::hcd6d894753c95d95

Order of calling ProgressBar::set_{prefix, message, style}

Calling set_message or set_prefix before set_style causes the style passed to set_style to not take effect for the first draw. Perhaps set_style should also call update_and_draw ? Otherwise it would be nice to document somewhere that the user should either call set_style before any other function or use tick to force a redraw after changing the style.

Compilation fails on Windows

Issue is pretty simple, I'm getting the following compilation error on Windows. I have the latest rustc and am getting the error on both nightly and stable.

error: no method named `as_raw_handle` found for type `{integer}` in the current scope
  --> [cargo installation directory]\indicatif-0.3.1\src\term\windows.rs:19:28
   |
19 |         GetConsoleMode(out.as_raw_handle(), &mut out) != 0
   |                            ^^^^^^^^^^^^^

error: aborting due to previous error

error: Could not compile `indicatif`.

Link to source code

Refresh rate does not propagate in the `MultiProgress`

ProgressBar and MultiProgress both share the common refresh rate mechanism (via set_draw_target). But since the rate limiting occurs at the final draw stage, MultiProgress gets much more slower than ProgressBar alone when there are more than thousands of state updates.

In my naive benchmark, which makes one ProgressBar, optionally adds it to MultiProgress, and runs 1,000,000 inc(1) calls:

  • Without MultiProgress it took 9.6 seconds (104,000 calls/s);
  • With MultiProgress it took 69.2 seconds (14,400 calls/s).

I expect that along with the MPSC Sender the refresh rate should be shared across ProgressBars.

Spinners in a multibar don't spin while a child process runs

I observed that spinners do not spin while a child process runs that was spawned with std::process::Command. Especially when they are in a multibar. I created a small example that shows the issue: https://github.com/migerh/indicatif-multibar

The use_multibar_with_timeout_for_finish() example shows that while the child process is running, the spinners in the multibar do not update. They start spinning as soon as the child process finishes, though.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.