ok/jj
1
0
Fork 0
forked from mirrors/jj

cli: hide cursor during progress display

This commit is contained in:
Benjamin Saunders 2022-10-29 19:34:17 -07:00
parent 472b6926e5
commit 210b54afd7
2 changed files with 33 additions and 0 deletions

View file

@ -4,12 +4,14 @@ use std::time::{Duration, Instant};
use crossterm::terminal::{Clear, ClearType};
use jujutsu_lib::git;
use crate::cleanup_guard::CleanupGuard;
use crate::ui::Ui;
pub struct Progress {
next_print: Instant,
rate: RateEstimate,
buffer: String,
guard: Option<CleanupGuard>,
}
impl Progress {
@ -18,6 +20,7 @@ impl Progress {
next_print: now + INITIAL_DELAY,
rate: RateEstimate::new(),
buffer: String::new(),
guard: None,
}
}
@ -40,6 +43,14 @@ impl Progress {
if now < self.next_print {
return Ok(());
}
if self.guard.is_none() {
let guard = self.ui.output_guard(crossterm::cursor::Show.to_string());
let guard = CleanupGuard::new(move || {
drop(guard);
});
_ = write!(self.ui, "{}", crossterm::cursor::Hide);
self.guard = Some(guard);
}
self.next_print = now.min(self.next_print + Duration::from_secs(1) / UPDATE_HZ);
self.buffer.clear();

View file

@ -234,8 +234,30 @@ impl Ui {
pub fn size(&self) -> Option<(u16, u16)> {
crossterm::terminal::size().ok()
}
/// Construct a guard object which writes `data` when dropped. Useful for
/// restoring terminal state.
pub fn output_guard(&self, text: String) -> OutputGuard {
OutputGuard {
text,
output: match self.output_pair {
UiOutputPair::Terminal { .. } => io::stdout(),
},
}
}
}
enum UiOutputPair {
Terminal { stdout: Stdout, stderr: Stderr },
}
pub struct OutputGuard {
text: String,
output: Stdout,
}
impl Drop for OutputGuard {
fn drop(&mut self) {
_ = self.output.write_all(self.text.as_bytes());
}
}