Activate a rolling buffer for the current executor run. Suspends the group spinner and installs a shared rolling buffer that `run_command_with_log_pipe` will automatically pick up. Starts a background tick thread to keep the spinner animating.
(title: &str)
| 285 | /// `run_command_with_log_pipe` will automatically pick up. Starts a background |
| 286 | /// tick thread to keep the spinner animating. |
| 287 | pub fn activate_rolling_buffer(title: &str) { |
| 288 | if !*IS_TTY { |
| 289 | return; |
| 290 | } |
| 291 | let rb = RollingBuffer::new(title); |
| 292 | if !rb.is_active() { |
| 293 | return; |
| 294 | } |
| 295 | // Suspend the group spinner so it doesn't interfere with rolling output |
| 296 | if let Ok(mut spinner) = SPINNER.lock() { |
| 297 | if let Some(pb) = spinner.take() { |
| 298 | pb.suspend(|| eprintln!()); |
| 299 | pb.finish_and_clear(); |
| 300 | } |
| 301 | } |
| 302 | *ROLLING_BUFFER.lock().unwrap() = Some(rb); |
| 303 | |
| 304 | // Start a background thread that redraws periodically to animate the spinner |
| 305 | TICK_STOP.store(false, Ordering::Relaxed); |
| 306 | std::thread::spawn(|| { |
| 307 | while !TICK_STOP.load(Ordering::Relaxed) { |
| 308 | std::thread::sleep(Duration::from_millis(TICK_INTERVAL_MS)); |
| 309 | if TICK_STOP.load(Ordering::Relaxed) { |
| 310 | break; |
| 311 | } |
| 312 | if let Ok(mut guard) = ROLLING_BUFFER.try_lock() { |
| 313 | if let Some(rb) = guard.as_mut() { |
| 314 | if rb.finished { |
| 315 | break; |
| 316 | } |
| 317 | rb.redraw_title(); |
| 318 | } |
| 319 | } |
| 320 | } |
| 321 | }); |
| 322 | } |
| 323 | |
| 324 | /// Finish and deactivate the current rolling buffer. |
| 325 | pub fn deactivate_rolling_buffer() { |
no test coverage detected