flake_edit/tui/
run.rs

1//! TUI run loop for executing interactive workflows.
2
3use std::io;
4
5use crossterm::event::{self, Event, KeyEventKind};
6use ratatui::widgets::Widget;
7
8use super::app::{App, AppResult, UpdateResult};
9use super::backend::InlineTerminal;
10
11/// Run the app to completion, returning the result based on workflow type.
12///
13/// Returns `None` if the user cancelled, or `Some(AppResult)` with the
14/// appropriate result type for the workflow.
15pub fn run(mut app: App) -> io::Result<Option<AppResult>> {
16    let height = app.terminal_height();
17    let mut term = InlineTerminal::new(height)?;
18
19    loop {
20        // Resize terminal if needed (e.g., when transitioning to Confirm screen)
21        let new_height = app.terminal_height();
22        if new_height != term.height() {
23            term.resize(new_height)?;
24        }
25
26        term.terminal().draw(|frame| {
27            let area = frame.area();
28            (&app).render(area, frame.buffer_mut());
29            if let Some((x, y)) = app.cursor_position(area) {
30                frame.set_cursor_position((x, y));
31            }
32        })?;
33
34        if let Event::Key(key) = event::read()? {
35            if key.kind != KeyEventKind::Press {
36                continue;
37            }
38            match app.update(key) {
39                UpdateResult::Continue => {}
40                UpdateResult::Done => return Ok(app.extract_result()),
41                UpdateResult::Cancelled => return Ok(None),
42            }
43        }
44    }
45}