magi-code 0.96.1

Repository-aware CLI coding agent for terminal work
Documentation
//! Present all cell, cursor, and image writes as one terminal update.

use std::io::{self, Write};

use anyhow::Result;
use crossterm::{
    QueueableCommand, execute,
    terminal::{BeginSynchronizedUpdate, EndSynchronizedUpdate},
};

struct SynchronizedOutput<'a, W: Write> {
    writer: Option<&'a mut W>,
}

impl<W: Write> SynchronizedOutput<'_, W> {
    fn finish(&mut self) -> io::Result<()> {
        if let Some(writer) = self.writer.take() {
            execute!(writer, EndSynchronizedUpdate)?;
        }
        Ok(())
    }
}

impl<W: Write> Drop for SynchronizedOutput<'_, W> {
    fn drop(&mut self) {
        let _ = self.finish();
    }
}

/// Keep intermediate cursor positions off screen, including image writes.
/// The caller holds stdout's lock; TestBackend draws need no terminal commands.
pub(in crate::tui) fn draw_synchronized<W: Write, T>(
    writer: &mut W,
    draw: impl FnOnce(&mut W) -> Result<T>,
) -> Result<T> {
    let mut output = SynchronizedOutput {
        writer: Some(writer),
    };
    let writer = output.writer.as_deref_mut().expect("active frame writer");
    writer.queue(BeginSynchronizedUpdate)?;
    let draw_result = draw(writer);
    // Always end and flush, even when drawing failed. Preserve the draw error.
    let finish_result = output.finish();
    let value = draw_result?;
    finish_result?;
    Ok(value)
}