Skip to content

Commit 1b8508c

Browse files
committed
Fix spinner clearing the AI response on short replies
The spinner row was being cleared twice: once when streaming started (stop_global) and again when finish() was called. By the second clear, the AI response text had been printed on that same row, so it got wiped. Added SPINNER_ROW_CLEARED guard so clear_spinner_row() only fires once per spinner cycle.
1 parent 2ac0191 commit 1b8508c

1 file changed

Lines changed: 14 additions & 0 deletions

File tree

rust/crates/rusty-claude-cli/src/render.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ static SPINNER_ACTIVE: std::sync::atomic::AtomicBool =
5252
static SPINNER_ROW: std::sync::atomic::AtomicU16 =
5353
std::sync::atomic::AtomicU16::new(0);
5454

55+
/// Guard against clearing the spinner row twice — the second clear would wipe
56+
/// the AI response that was printed on the same row after streaming started.
57+
static SPINNER_ROW_CLEARED: std::sync::atomic::AtomicBool =
58+
std::sync::atomic::AtomicBool::new(true);
59+
5560
pub struct Spinner {
5661
handle: Option<std::thread::JoinHandle<()>>,
5762
}
@@ -134,7 +139,14 @@ impl Spinner {
134139
}
135140

136141
/// Clear the spinner from the row where it was rendered.
142+
/// Only clears once per spinner cycle — a second call is a no-op so we
143+
/// don't accidentally wipe the AI response that now occupies that row.
137144
fn clear_spinner_row() {
145+
// swap(true) returns the *previous* value. If it was already true,
146+
// the row was already cleared — skip.
147+
if SPINNER_ROW_CLEARED.swap(true, std::sync::atomic::Ordering::SeqCst) {
148+
return;
149+
}
138150
let mut stdout = io::stdout();
139151
let row = SPINNER_ROW.load(std::sync::atomic::Ordering::SeqCst);
140152
let _ = execute!(
@@ -173,6 +185,8 @@ impl Spinner {
173185
_out: &mut impl Write,
174186
) -> io::Result<()> {
175187
SPINNER_ACTIVE.store(true, std::sync::atomic::Ordering::SeqCst);
188+
// Reset the cleared guard so the new spinner's row can be cleared once.
189+
SPINNER_ROW_CLEARED.store(false, std::sync::atomic::Ordering::SeqCst);
176190
let active_color = theme.spinner_active;
177191

178192
// Capture current cursor row — spinner renders on the next line

0 commit comments

Comments
 (0)