magi-code 0.77.1

Repository-aware CLI coding agent for terminal work
Documentation
use super::super::render_scroll_view_persistent_state_with_theme;
use super::{SYSTEM_PROMPT_MODAL, draw_modal_panel, modal_text_area};
use crate::tui::state::MissionControlState;
use ratatui::{
    Frame,
    layout::Rect,
    widgets::{Paragraph, Wrap},
};

pub(crate) fn rewind_modal_text_area(area: Rect) -> Option<Rect> {
    modal_text_area(area, "Rewind", SYSTEM_PROMPT_MODAL)
}

pub(in crate::tui::render) fn draw_rewind_modal(
    frame: &mut Frame<'_>,
    area: Rect,
    state: &MissionControlState,
) {
    let Some(modal) = &state.modals.rewind_modal else {
        return;
    };
    let theme = state.theme;
    let Some(text_area) = draw_modal_panel(frame, area, "Rewind", SYSTEM_PROMPT_MODAL, theme)
    else {
        return;
    };
    let content = modal.display_text();
    let wrap_width = super::super::scroll_view_content_width(text_area).max(1);
    render_scroll_view_persistent_state_with_theme(
        frame,
        text_area,
        super::super::usize_to_u16_saturating(crate::tui::transcript::ratatui_wrapped_visual_rows(
            &content, wrap_width,
        )),
        Paragraph::new(content)
            .style(theme.pane())
            .wrap(Wrap { trim: false }),
        &state.scroll_views.rewind_modal,
        theme,
    );
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn rewind_preview_renders_three_modes_and_scrolls_to_final_line() {
        let mut state = MissionControlState::default();
        let plan = crate::checkpoints::RestorePlan {
            session_id: "session".into(),
            target_turn: 1,
            latest_turn: None,
            operations: Vec::new(),
            diagnostics: Vec::new(),
        };
        state.open_rewind_modal(
            format!("{}\nfinal preview line", "preview row\n".repeat(40)),
            Some(plan),
            false,
        );
        let mut terminal =
            ratatui::Terminal::new(ratatui::backend::TestBackend::new(120, 30)).unwrap();
        terminal
            .draw(|frame| draw_rewind_modal(frame, frame.area(), &state))
            .unwrap();
        let rendered = terminal
            .backend()
            .buffer()
            .content()
            .iter()
            .map(|cell| cell.symbol())
            .collect::<String>();
        assert!(rendered.contains("conversation only | files only | both"));
        assert!(rendered.contains("Selected: conversation only"));
        let area = rewind_modal_text_area(Rect::new(0, 0, 120, 30)).unwrap();
        let width = crate::tui::render::scroll_view_content_width(area);
        state.scroll_rewind_down_by(u16::MAX, area.height, width);
        terminal
            .draw(|frame| draw_rewind_modal(frame, frame.area(), &state))
            .unwrap();
        let rendered = terminal
            .backend()
            .buffer()
            .content()
            .iter()
            .map(|cell| cell.symbol())
            .collect::<String>();
        assert!(rendered.contains("final preview line"));
    }
}