diff options
Diffstat (limited to 'crates/ra_cli/src')
-rw-r--r-- | crates/ra_cli/src/analysis_stats.rs | 17 | ||||
-rw-r--r-- | crates/ra_cli/src/main.rs | 1 | ||||
-rw-r--r-- | crates/ra_cli/src/progress_bar.rs | 130 |
3 files changed, 138 insertions, 10 deletions
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; | |||
6 | use ra_hir::{AssocItem, Crate, HasSource, HirDisplay, ModuleDef, Ty, TypeWalk}; | 6 | use ra_hir::{AssocItem, Crate, HasSource, HirDisplay, ModuleDef, Ty, TypeWalk}; |
7 | use ra_syntax::AstNode; | 7 | use ra_syntax::AstNode; |
8 | 8 | ||
9 | use crate::{Result, Verbosity}; | 9 | use crate::{progress_bar::ProgressBar, Result, Verbosity}; |
10 | 10 | ||
11 | pub fn run( | 11 | pub fn run( |
12 | verbosity: Verbosity, | 12 | verbosity: Verbosity, |
@@ -75,17 +75,14 @@ pub fn run( | |||
75 | println!("Item Collection: {:?}, {}", analysis_time.elapsed(), ra_prof::memory_usage()); | 75 | println!("Item Collection: {:?}, {}", analysis_time.elapsed(), ra_prof::memory_usage()); |
76 | 76 | ||
77 | let inference_time = Instant::now(); | 77 | let inference_time = Instant::now(); |
78 | let bar = match verbosity { | 78 | let mut bar = match verbosity { |
79 | Verbosity::Verbose | Verbosity::Normal => indicatif::ProgressBar::with_draw_target( | 79 | Verbosity::Verbose | Verbosity::Normal => ProgressBar::new(funcs.len() as u64), |
80 | funcs.len() as u64, | 80 | Verbosity::Quiet => ProgressBar::hidden(), |
81 | indicatif::ProgressDrawTarget::stderr_nohz(), | ||
82 | ), | ||
83 | Verbosity::Quiet => indicatif::ProgressBar::hidden(), | ||
84 | }; | 81 | }; |
85 | 82 | ||
86 | bar.set_style( | 83 | // bar.set_style( |
87 | indicatif::ProgressStyle::default_bar().template("{wide_bar} {pos}/{len}\n{msg}"), | 84 | // indicatif::ProgressStyle::default_bar().template("{wide_bar} {pos}/{len}\n{msg}"), |
88 | ); | 85 | // ); |
89 | bar.tick(); | 86 | bar.tick(); |
90 | let mut num_exprs = 0; | 87 | let mut num_exprs = 0; |
91 | let mut num_exprs_unknown = 0; | 88 | 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 @@ | |||
3 | mod analysis_stats; | 3 | mod analysis_stats; |
4 | mod analysis_bench; | 4 | mod analysis_bench; |
5 | mod help; | 5 | mod help; |
6 | mod progress_bar; | ||
6 | 7 | ||
7 | use std::{error::Error, fmt::Write, io::Read}; | 8 | use std::{error::Error, fmt::Write, io::Read}; |
8 | 9 | ||
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 @@ | |||
1 | //! A simple progress bar | ||
2 | //! | ||
3 | //! A single thread non-optimized progress bar | ||
4 | use std::io::Write; | ||
5 | |||
6 | /// A Simple ASCII Progress Bar | ||
7 | pub struct ProgressBar { | ||
8 | curr: f32, | ||
9 | text: String, | ||
10 | anim: usize, | ||
11 | hidden: bool, | ||
12 | |||
13 | len: u64, | ||
14 | pos: u64, | ||
15 | msg: String, | ||
16 | } | ||
17 | |||
18 | impl ProgressBar { | ||
19 | const ANIMATION: &'static str = r#"|/-\"#; | ||
20 | const BLOCK_COUNT: usize = 20; | ||
21 | |||
22 | pub fn new(len: u64) -> ProgressBar { | ||
23 | ProgressBar { | ||
24 | curr: 0.0, | ||
25 | text: String::new(), | ||
26 | anim: 0, | ||
27 | hidden: false, | ||
28 | len, | ||
29 | pos: 0, | ||
30 | msg: String::new(), | ||
31 | } | ||
32 | } | ||
33 | |||
34 | pub fn hidden() -> ProgressBar { | ||
35 | ProgressBar { | ||
36 | curr: 0.0, | ||
37 | text: String::new(), | ||
38 | anim: 0, | ||
39 | hidden: true, | ||
40 | len: 0, | ||
41 | pos: 0, | ||
42 | msg: String::new(), | ||
43 | } | ||
44 | } | ||
45 | |||
46 | pub fn set_message(&mut self, msg: &str) { | ||
47 | self.msg = msg.to_string(); | ||
48 | self.tick(); | ||
49 | } | ||
50 | |||
51 | pub fn println<I: Into<String>>(&mut self, msg: I) { | ||
52 | self.clear(); | ||
53 | println!("{}", msg.into()); | ||
54 | self.tick(); | ||
55 | } | ||
56 | |||
57 | pub fn inc(&mut self, delta: u64) { | ||
58 | self.pos += delta; | ||
59 | if self.len == 0 { | ||
60 | self.set_value(0.0) | ||
61 | } else { | ||
62 | self.set_value((self.pos as f32) / (self.len as f32)) | ||
63 | } | ||
64 | self.tick(); | ||
65 | } | ||
66 | |||
67 | pub fn finish_and_clear(&mut self) { | ||
68 | self.clear(); | ||
69 | } | ||
70 | |||
71 | pub fn tick(&mut self) { | ||
72 | if self.hidden { | ||
73 | return; | ||
74 | } | ||
75 | |||
76 | let progress_block: usize = (self.curr * Self::BLOCK_COUNT as f32) as usize; | ||
77 | let percent = (self.curr * 100.0) as u32; | ||
78 | let text = format!( | ||
79 | "[{}{}] {:3>}% {} {}", | ||
80 | "#".repeat(progress_block), | ||
81 | "-".repeat(Self::BLOCK_COUNT - progress_block), | ||
82 | percent, | ||
83 | Self::ANIMATION.chars().nth(self.anim).unwrap(), | ||
84 | self.msg, | ||
85 | ); | ||
86 | |||
87 | self.anim = (self.anim + 1) % Self::ANIMATION.len(); | ||
88 | self.update_text(&text); | ||
89 | } | ||
90 | |||
91 | fn update_text(&mut self, text: &str) { | ||
92 | // Get length of common portion | ||
93 | let mut common_prefix_length = 0; | ||
94 | let common_length = usize::min(self.text.len(), text.len()); | ||
95 | |||
96 | while common_prefix_length < common_length | ||
97 | && text.chars().nth(common_prefix_length).unwrap() | ||
98 | == self.text.chars().nth(common_prefix_length).unwrap() | ||
99 | { | ||
100 | common_prefix_length += 1; | ||
101 | } | ||
102 | |||
103 | // Backtrack to the first differing character | ||
104 | let mut output = String::new(); | ||
105 | output += &'\x08'.to_string().repeat(self.text.len() - common_prefix_length); | ||
106 | // Output new suffix | ||
107 | output += &text[common_prefix_length..text.len()]; | ||
108 | |||
109 | // If the new text is shorter than the old one: delete overlapping characters | ||
110 | if let Some(overlap_count) = self.text.len().checked_sub(text.len()) { | ||
111 | if overlap_count > 0 { | ||
112 | output += &" ".repeat(overlap_count); | ||
113 | output += &"\x08".repeat(overlap_count); | ||
114 | } | ||
115 | } | ||
116 | |||
117 | let _ = std::io::stdout().write(output.as_bytes()); | ||
118 | let _ = std::io::stdout().flush(); | ||
119 | self.text = text.to_string(); | ||
120 | } | ||
121 | |||
122 | fn set_value(&mut self, value: f32) { | ||
123 | self.curr = f32::max(0.0, f32::min(1.0, value)); | ||
124 | } | ||
125 | |||
126 | fn clear(&mut self) { | ||
127 | print!("{}", "\x08".repeat(self.text.len())); | ||
128 | self.text = String::new(); | ||
129 | } | ||
130 | } | ||