supercode-frontend-tui 0.4.8

Attachable terminal frontend primitives for Supercode SDK runtimes.
Documentation
// Derived from OpenAI Codex: codex-rs/tui/src/tui.rs
// Pinned source: 8604689ec5e3437eb79802d8d72249b7722fbf5b
// Copyright 2025 OpenAI
// Licensed under the Apache License, Version 2.0.
// Modified by the Supercode contributors; see docs/legal/codex-frontend-extraction.toml.

//! Panic-safe, idempotent terminal mode ownership.

use std::io;
use std::io::stdout;

use crossterm::cursor::Hide;
use crossterm::cursor::Show;
use crossterm::event::DisableBracketedPaste;
use crossterm::event::DisableFocusChange;
use crossterm::event::EnableBracketedPaste;
use crossterm::event::EnableFocusChange;
use crossterm::execute;
use crossterm::terminal::disable_raw_mode;
use crossterm::terminal::enable_raw_mode;
use crossterm::terminal::EnterAlternateScreen;
use crossterm::terminal::LeaveAlternateScreen;

/// Backend seam used to prove exact mode setup and restoration without a TTY.
pub trait TerminalOps {
    fn set_raw_mode(&mut self, enabled: bool) -> io::Result<()>;
    fn set_bracketed_paste(&mut self, enabled: bool) -> io::Result<()>;
    fn set_focus_events(&mut self, enabled: bool) -> io::Result<()>;
    fn set_alternate_screen(&mut self, enabled: bool) -> io::Result<()>;
    fn set_cursor_visible(&mut self, visible: bool) -> io::Result<()>;
}

/// Real Crossterm terminal operations.
#[derive(Debug, Default)]
pub struct CrosstermTerminalOps;

impl TerminalOps for CrosstermTerminalOps {
    fn set_raw_mode(&mut self, enabled: bool) -> io::Result<()> {
        if enabled {
            enable_raw_mode()
        } else {
            disable_raw_mode()
        }
    }

    fn set_bracketed_paste(&mut self, enabled: bool) -> io::Result<()> {
        if enabled {
            execute!(stdout(), EnableBracketedPaste)
        } else {
            execute!(stdout(), DisableBracketedPaste)
        }
    }

    fn set_focus_events(&mut self, enabled: bool) -> io::Result<()> {
        if enabled {
            execute!(stdout(), EnableFocusChange)
        } else {
            execute!(stdout(), DisableFocusChange)
        }
    }

    fn set_alternate_screen(&mut self, enabled: bool) -> io::Result<()> {
        if enabled {
            execute!(stdout(), EnterAlternateScreen)
        } else {
            execute!(stdout(), LeaveAlternateScreen)
        }
    }

    fn set_cursor_visible(&mut self, visible: bool) -> io::Result<()> {
        if visible {
            execute!(stdout(), Show)
        } else {
            execute!(stdout(), Hide)
        }
    }
}

#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
struct ActiveModes {
    raw: bool,
    bracketed_paste: bool,
    focus_events: bool,
    alternate_screen: bool,
    cursor_hidden: bool,
}

/// Owns every terminal mode enabled by the frontend and restores them on drop.
pub struct TerminalGuard<O: TerminalOps> {
    ops: O,
    active: ActiveModes,
}

impl<O: TerminalOps> TerminalGuard<O> {
    /// Enable all terminal modes, rolling back any successfully enabled prefix
    /// if a later operation fails.
    pub fn enter(ops: O) -> io::Result<Self> {
        let mut guard = Self {
            ops,
            active: ActiveModes::default(),
        };
        if let Err(error) = guard.activate() {
            let _ = guard.restore();
            return Err(error);
        }
        Ok(guard)
    }

    fn activate(&mut self) -> io::Result<()> {
        self.ops.set_raw_mode(true)?;
        self.active.raw = true;

        self.ops.set_bracketed_paste(true)?;
        self.active.bracketed_paste = true;

        self.ops.set_focus_events(true)?;
        self.active.focus_events = true;

        self.ops.set_alternate_screen(true)?;
        self.active.alternate_screen = true;

        self.ops.set_cursor_visible(false)?;
        self.active.cursor_hidden = true;
        Ok(())
    }

    /// Restore every active mode in reverse order. Restoration is best-effort:
    /// all operations are attempted and the first error is returned.
    pub fn restore(&mut self) -> io::Result<()> {
        let mut first_error = None;

        if self.active.cursor_hidden {
            record_result(
                &mut first_error,
                self.ops.set_cursor_visible(true),
                &mut self.active.cursor_hidden,
            );
        }
        if self.active.alternate_screen {
            record_result(
                &mut first_error,
                self.ops.set_alternate_screen(false),
                &mut self.active.alternate_screen,
            );
        }
        if self.active.focus_events {
            record_result(
                &mut first_error,
                self.ops.set_focus_events(false),
                &mut self.active.focus_events,
            );
        }
        if self.active.bracketed_paste {
            record_result(
                &mut first_error,
                self.ops.set_bracketed_paste(false),
                &mut self.active.bracketed_paste,
            );
        }
        if self.active.raw {
            record_result(
                &mut first_error,
                self.ops.set_raw_mode(false),
                &mut self.active.raw,
            );
        }

        first_error.map_or(Ok(()), Err)
    }

    /// Temporarily restore the terminal around an external interactive action,
    /// then reacquire all modes even when that action returns an error.
    pub fn with_restored<T>(&mut self, action: impl FnOnce() -> io::Result<T>) -> io::Result<T> {
        self.restore()?;
        let action_result = action();
        let activate_result = self.activate();
        match (action_result, activate_result) {
            (Err(error), _) => Err(error),
            (Ok(_), Err(error)) => Err(error),
            (Ok(value), Ok(())) => Ok(value),
        }
    }

    /// True when this guard currently owns at least one terminal mode.
    pub fn is_active(&self) -> bool {
        self.active != ActiveModes::default()
    }
}

impl<O: TerminalOps> Drop for TerminalGuard<O> {
    fn drop(&mut self) {
        let _ = self.restore();
    }
}

fn record_result(first_error: &mut Option<io::Error>, result: io::Result<()>, active: &mut bool) {
    match result {
        Ok(()) => *active = false,
        Err(error) => {
            // Keep ownership recorded so `Drop` can retry a transient
            // restoration failure instead of silently abandoning the mode.
            first_error.get_or_insert(error);
        }
    }
}

#[cfg(test)]
mod tests {
    use std::cell::RefCell;
    use std::panic::AssertUnwindSafe;
    use std::rc::Rc;

    use super::*;

    #[derive(Clone, Default)]
    struct MockOps {
        calls: Rc<RefCell<Vec<&'static str>>>,
        fail_on: Rc<RefCell<Option<&'static str>>>,
    }

    impl MockOps {
        fn call(&self, name: &'static str) -> io::Result<()> {
            self.calls.borrow_mut().push(name);
            if self.fail_on.borrow().as_ref() == Some(&name) {
                Err(io::Error::other(format!("failed {name}")))
            } else {
                Ok(())
            }
        }
    }

    impl TerminalOps for MockOps {
        fn set_raw_mode(&mut self, enabled: bool) -> io::Result<()> {
            self.call(if enabled { "raw+" } else { "raw-" })
        }

        fn set_bracketed_paste(&mut self, enabled: bool) -> io::Result<()> {
            self.call(if enabled { "paste+" } else { "paste-" })
        }

        fn set_focus_events(&mut self, enabled: bool) -> io::Result<()> {
            self.call(if enabled { "focus+" } else { "focus-" })
        }

        fn set_alternate_screen(&mut self, enabled: bool) -> io::Result<()> {
            self.call(if enabled { "screen+" } else { "screen-" })
        }

        fn set_cursor_visible(&mut self, visible: bool) -> io::Result<()> {
            self.call(if visible { "cursor+" } else { "cursor-" })
        }
    }

    const ENTER: &[&str] = &["raw+", "paste+", "focus+", "screen+", "cursor-"];
    const RESTORE: &[&str] = &["cursor+", "screen-", "focus-", "paste-", "raw-"];

    #[test]
    fn normal_drop_restores_every_mode_in_reverse_order_once() {
        let ops = MockOps::default();
        let calls = Rc::clone(&ops.calls);
        {
            let guard = TerminalGuard::enter(ops).expect("enter");
            assert!(guard.is_active());
        }
        assert_eq!(&*calls.borrow(), &[ENTER, RESTORE].concat());
    }

    #[test]
    fn partial_setup_failure_rolls_back_the_successful_prefix() {
        let ops = MockOps::default();
        *ops.fail_on.borrow_mut() = Some("focus+");
        let calls = Rc::clone(&ops.calls);
        assert!(TerminalGuard::enter(ops).is_err());
        assert_eq!(
            &*calls.borrow(),
            &["raw+", "paste+", "focus+", "paste-", "raw-"]
        );
    }

    #[test]
    fn panic_unwind_restores_every_mode() {
        let ops = MockOps::default();
        let calls = Rc::clone(&ops.calls);
        let result = std::panic::catch_unwind(AssertUnwindSafe(|| {
            let _guard = TerminalGuard::enter(ops).expect("enter");
            panic!("test panic");
        }));
        assert!(result.is_err());
        assert_eq!(&*calls.borrow(), &[ENTER, RESTORE].concat());
    }

    #[test]
    fn external_action_restores_then_reacquires_modes() {
        let ops = MockOps::default();
        let calls = Rc::clone(&ops.calls);
        let mut guard = TerminalGuard::enter(ops).expect("enter");
        guard.with_restored(|| Ok(())).expect("resume");
        drop(guard);
        assert_eq!(&*calls.borrow(), &[ENTER, RESTORE, ENTER, RESTORE].concat());
    }

    #[test]
    fn external_action_error_still_reacquires_and_later_restores() {
        let ops = MockOps::default();
        let calls = Rc::clone(&ops.calls);
        let mut guard = TerminalGuard::enter(ops).expect("enter");
        let result = guard.with_restored(|| Err::<(), _>(io::Error::other("action failed")));
        assert_eq!(
            result.expect_err("action error").to_string(),
            "action failed"
        );
        assert!(guard.is_active());
        drop(guard);
        assert_eq!(&*calls.borrow(), &[ENTER, RESTORE, ENTER, RESTORE].concat());
    }

    #[test]
    fn restore_attempts_all_modes_after_an_individual_failure() {
        let ops = MockOps::default();
        let calls = Rc::clone(&ops.calls);
        let fail_on = Rc::clone(&ops.fail_on);
        let mut guard = TerminalGuard::enter(ops).expect("enter");
        *fail_on.borrow_mut() = Some("screen-");
        assert_eq!(
            guard.restore().expect_err("restore error").to_string(),
            "failed screen-"
        );
        assert!(guard.is_active());
        *fail_on.borrow_mut() = None;
        drop(guard);
        assert_eq!(&*calls.borrow(), &[ENTER, RESTORE, &["screen-"]].concat());
    }
}