magi-code 0.62.0

Repository-aware CLI coding agent for terminal work
Documentation
use super::{input, render, state};

pub(crate) fn key_viewports(
    terminal_area: ratatui::layout::Rect,
    state: &state::MissionControlState,
) -> input::KeyViewports {
    let layout = render::layout_for(terminal_area, state);
    let prompt_viewport = layout.pane_area(render::TuiPane::Prompt).map(|area| {
        let text_area = render::content_text_area_for_pane(render::TuiPane::Prompt, area);
        input::PromptViewport {
            visible_rows: text_area.height.max(1),
            wrap_width: render::scroll_view_content_width(text_area).max(1),
        }
    });
    let transcript_viewport = layout.pane_area(render::TuiPane::Transcript).map(|area| {
        let text_area = render::content_text_area_for_pane(render::TuiPane::Transcript, area);
        input::TranscriptViewport {
            visible_rows: text_area.height.max(1),
            wrap_width: render::scroll_view_content_width(text_area).max(1),
        }
    });
    let activity_tree_viewport = layout.pane_area(render::TuiPane::ActivityTree).map(|area| {
        let text_area = render::content_text_area_for_pane(render::TuiPane::ActivityTree, area);
        input::ActivityTreeViewport {
            visible_rows: text_area.height.max(1),
        }
    });
    let detail_viewport = layout.pane_area(render::TuiPane::Detail).map(|area| {
        let text_area = render::content_text_area_for_pane(render::TuiPane::Detail, area);
        let visible_rows = state.detail_body_viewport_rows(
            text_area.height,
            render::scroll_view_content_width(text_area).max(1),
        );
        input::DetailViewport {
            visible_rows,
            wrap_width: render::scroll_view_content_width(text_area).max(1),
        }
    });
    let system_prompt_viewport =
        render::system_prompt_text_area(terminal_area).map(|area| input::SystemPromptViewport {
            visible_rows: area.height.max(1),
            wrap_width: render::scroll_view_content_width(area).max(1),
        });
    let login_picker_viewport = state.modals.login_picker.as_ref().and_then(|picker| {
        picker_viewport(render::auth_picker_list_area(
            terminal_area,
            picker.notice.is_some(),
        ))
    });
    let model_picker_viewport = state.modals.model_picker.as_ref().and_then(|picker| {
        picker_viewport(render::model_picker_list_area(
            terminal_area,
            picker.notice.is_some(),
        ))
    });
    input::KeyViewports {
        prompt: prompt_viewport,
        transcript: transcript_viewport,
        activity_tree: activity_tree_viewport,
        detail: detail_viewport,
        system_prompt: system_prompt_viewport,
        rewind_modal: render::rewind_modal_text_area(terminal_area).map(|area| {
            input::SystemPromptViewport {
                visible_rows: area.height.max(1),
                wrap_width: render::scroll_view_content_width(area).max(1),
            }
        }),
        usage_modal: render::usage_modal_text_area(terminal_area).map(|area| {
            input::SystemPromptViewport {
                visible_rows: area.height.max(1),
                wrap_width: render::scroll_view_content_width(area).max(1),
            }
        }),
        login_picker: login_picker_viewport,
        model_picker: model_picker_viewport,
        sessions_modal: session_picker_viewport(terminal_area),
        models_modal: picker_viewport(render::models_modal_list_area(terminal_area)),
    }
}

pub(crate) fn paste_viewports(
    terminal_area: ratatui::layout::Rect,
    state: &state::MissionControlState,
) -> input::KeyViewports {
    input::KeyViewports {
        prompt: key_viewports(terminal_area, state).prompt,
        ..input::KeyViewports::default()
    }
}

fn picker_viewport(list_area: Option<ratatui::layout::Rect>) -> Option<input::PickerViewport> {
    list_area.map(|area| input::PickerViewport {
        visible_rows: area.height.max(1),
    })
}

fn session_picker_viewport(
    terminal_area: ratatui::layout::Rect,
) -> Option<input::SessionPickerViewport> {
    render::sessions_modal_areas(terminal_area).map(|areas| input::SessionPickerViewport {
        list_rows: areas.list.height.max(1),
        preview_rows: areas.preview.map(|area| area.height.max(1)).unwrap_or(1),
        preview_width: areas
            .preview
            .map(|area| render::scroll_view_content_width(area).max(1))
            .unwrap_or(1),
        preview_visible: areas.preview.is_some(),
    })
}