diff options
| author | sigoden <sigoden@gmail.com> | 2024-04-21 06:52:22 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-21 06:52:22 +0800 |
| commit | b3162a72b50f88d78ca3d57c1f8b3421cecfe2b4 (patch) | |
| tree | cee11116acce66ffcc7599dc13dcc9588d174620 /src/utils | |
| parent | 8b75080973e6caa3128e9673440a57deb38fc0c9 (diff) | |
| download | aichat-b3162a72b50f88d78ca3d57c1f8b3421cecfe2b4.tar.gz | |
refactor: shell execution with spinner and select prompt (#425)
Diffstat (limited to 'src/utils')
| -rw-r--r-- | src/utils/mod.rs | 2 | ||||
| -rw-r--r-- | src/utils/spinner.rs | 52 |
2 files changed, 54 insertions, 0 deletions
diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 15af4ca..3df1a09 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -2,12 +2,14 @@ mod abort_signal; mod clipboard; mod prompt_input; mod render_prompt; +mod spinner; mod tiktoken; pub use self::abort_signal::{create_abort_signal, AbortSignal}; pub use self::clipboard::set_text; pub use self::prompt_input::*; pub use self::render_prompt::render_prompt; +pub use self::spinner::Spinner; pub use self::tiktoken::cl100k_base_singleton; use fancy_regex::Regex; diff --git a/src/utils/spinner.rs b/src/utils/spinner.rs new file mode 100644 index 0000000..c684901 --- /dev/null +++ b/src/utils/spinner.rs @@ -0,0 +1,52 @@ +use anyhow::Result; +use crossterm::{cursor, queue, style, terminal}; +use std::io::{Stdout, Write}; + +pub struct Spinner { + index: usize, + message: String, + stopped: bool, +} + +impl Spinner { + const DATA: [&'static str; 10] = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]; + + pub fn new(message: &str) -> Self { + Spinner { + index: 0, + message: message.to_string(), + stopped: false, + } + } + + pub fn step(&mut self, writer: &mut Stdout) -> Result<()> { + if self.stopped { + return Ok(()); + } + let frame = Self::DATA[self.index % Self::DATA.len()]; + let dots = ".".repeat((self.index / 5) % 4); + let line = format!("{frame}{}{:<3}", self.message, dots); + queue!(writer, cursor::MoveToColumn(0), style::Print(line),)?; + if self.index == 0 { + queue!(writer, cursor::Hide)?; + } + writer.flush()?; + self.index += 1; + Ok(()) + } + + pub fn stop(&mut self, writer: &mut Stdout) -> Result<()> { + if self.stopped { + return Ok(()); + } + self.stopped = true; + queue!( + writer, + cursor::MoveToColumn(0), + terminal::Clear(terminal::ClearType::FromCursorDown), + cursor::Show + )?; + writer.flush()?; + Ok(()) + } +} |
