From 5b49ad5bd5d78a8425f7162b6387c2cad6e2ef10 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Wed, 27 Nov 2019 04:09:30 +0800 Subject: Use a simple progress bar instead of indicatif --- crates/ra_cli/Cargo.toml | 1 - crates/ra_cli/src/analysis_stats.rs | 17 ++--- crates/ra_cli/src/main.rs | 1 + crates/ra_cli/src/progress_bar.rs | 130 ++++++++++++++++++++++++++++++++++++ 4 files changed, 138 insertions(+), 11 deletions(-) create mode 100644 crates/ra_cli/src/progress_bar.rs (limited to 'crates/ra_cli') diff --git a/crates/ra_cli/Cargo.toml b/crates/ra_cli/Cargo.toml index c9d3bdb77..3bb475997 100644 --- a/crates/ra_cli/Cargo.toml +++ b/crates/ra_cli/Cargo.toml @@ -8,7 +8,6 @@ publish = false [dependencies] pico-args = "0.3.0" flexi_logger = "0.14.0" -indicatif = "0.13.0" ra_syntax = { path = "../ra_syntax" } ra_ide_api = { path = "../ra_ide_api" } diff --git a/crates/ra_cli/src/analysis_stats.rs b/crates/ra_cli/src/analysis_stats.rs index c4eb28245..8bf3863bb 100644 --- a/crates/ra_cli/src/analysis_stats.rs +++ b/crates/ra_cli/src/analysis_stats.rs @@ -6,7 +6,7 @@ use ra_db::SourceDatabaseExt; use ra_hir::{AssocItem, Crate, HasSource, HirDisplay, ModuleDef, Ty, TypeWalk}; use ra_syntax::AstNode; -use crate::{Result, Verbosity}; +use crate::{progress_bar::ProgressBar, Result, Verbosity}; pub fn run( verbosity: Verbosity, @@ -75,17 +75,14 @@ pub fn run( println!("Item Collection: {:?}, {}", analysis_time.elapsed(), ra_prof::memory_usage()); let inference_time = Instant::now(); - let bar = match verbosity { - Verbosity::Verbose | Verbosity::Normal => indicatif::ProgressBar::with_draw_target( - funcs.len() as u64, - indicatif::ProgressDrawTarget::stderr_nohz(), - ), - Verbosity::Quiet => indicatif::ProgressBar::hidden(), + let mut bar = match verbosity { + Verbosity::Verbose | Verbosity::Normal => ProgressBar::new(funcs.len() as u64), + Verbosity::Quiet => ProgressBar::hidden(), }; - bar.set_style( - indicatif::ProgressStyle::default_bar().template("{wide_bar} {pos}/{len}\n{msg}"), - ); + // bar.set_style( + // indicatif::ProgressStyle::default_bar().template("{wide_bar} {pos}/{len}\n{msg}"), + // ); bar.tick(); let mut num_exprs = 0; let mut num_exprs_unknown = 0; diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs index a31fd5d6a..c23d92ec2 100644 --- a/crates/ra_cli/src/main.rs +++ b/crates/ra_cli/src/main.rs @@ -3,6 +3,7 @@ mod analysis_stats; mod analysis_bench; mod help; +mod progress_bar; use std::{error::Error, fmt::Write, io::Read}; diff --git a/crates/ra_cli/src/progress_bar.rs b/crates/ra_cli/src/progress_bar.rs new file mode 100644 index 000000000..95bfcf4d0 --- /dev/null +++ b/crates/ra_cli/src/progress_bar.rs @@ -0,0 +1,130 @@ +//! A simple progress bar +//! +//! A single thread non-optimized progress bar +use std::io::Write; + +/// A Simple ASCII Progress Bar +pub struct ProgressBar { + curr: f32, + text: String, + anim: usize, + hidden: bool, + + len: u64, + pos: u64, + msg: String, +} + +impl ProgressBar { + const ANIMATION: &'static str = r#"|/-\"#; + const BLOCK_COUNT: usize = 20; + + pub fn new(len: u64) -> ProgressBar { + ProgressBar { + curr: 0.0, + text: String::new(), + anim: 0, + hidden: false, + len, + pos: 0, + msg: String::new(), + } + } + + pub fn hidden() -> ProgressBar { + ProgressBar { + curr: 0.0, + text: String::new(), + anim: 0, + hidden: true, + len: 0, + pos: 0, + msg: String::new(), + } + } + + pub fn set_message(&mut self, msg: &str) { + self.msg = msg.to_string(); + self.tick(); + } + + pub fn println>(&mut self, msg: I) { + self.clear(); + println!("{}", msg.into()); + self.tick(); + } + + pub fn inc(&mut self, delta: u64) { + self.pos += delta; + if self.len == 0 { + self.set_value(0.0) + } else { + self.set_value((self.pos as f32) / (self.len as f32)) + } + self.tick(); + } + + pub fn finish_and_clear(&mut self) { + self.clear(); + } + + pub fn tick(&mut self) { + if self.hidden { + return; + } + + let progress_block: usize = (self.curr * Self::BLOCK_COUNT as f32) as usize; + let percent = (self.curr * 100.0) as u32; + let text = format!( + "[{}{}] {:3>}% {} {}", + "#".repeat(progress_block), + "-".repeat(Self::BLOCK_COUNT - progress_block), + percent, + Self::ANIMATION.chars().nth(self.anim).unwrap(), + self.msg, + ); + + self.anim = (self.anim + 1) % Self::ANIMATION.len(); + self.update_text(&text); + } + + fn update_text(&mut self, text: &str) { + // Get length of common portion + let mut common_prefix_length = 0; + let common_length = usize::min(self.text.len(), text.len()); + + while common_prefix_length < common_length + && text.chars().nth(common_prefix_length).unwrap() + == self.text.chars().nth(common_prefix_length).unwrap() + { + common_prefix_length += 1; + } + + // Backtrack to the first differing character + let mut output = String::new(); + output += &'\x08'.to_string().repeat(self.text.len() - common_prefix_length); + // Output new suffix + output += &text[common_prefix_length..text.len()]; + + // If the new text is shorter than the old one: delete overlapping characters + if let Some(overlap_count) = self.text.len().checked_sub(text.len()) { + if overlap_count > 0 { + output += &" ".repeat(overlap_count); + output += &"\x08".repeat(overlap_count); + } + } + + let _ = std::io::stdout().write(output.as_bytes()); + let _ = std::io::stdout().flush(); + self.text = text.to_string(); + } + + fn set_value(&mut self, value: f32) { + self.curr = f32::max(0.0, f32::min(1.0, value)); + } + + fn clear(&mut self) { + print!("{}", "\x08".repeat(self.text.len())); + self.text = String::new(); + } +} -- cgit v1.2.3