mars-terminal 0.3.2

A terminal editor, multiplexer, and built-in AI agent in one binary — non-modal and Emacs-compatible, with tmux-style persistent sessions.
use crate::buffer::BufferId;

pub type PaneId = usize;
pub type TermId = usize;

#[derive(Debug, Clone)]
pub enum PaneContent {
    Editor(BufferId),
    Terminal(TermId),
}

#[derive(Debug, Clone)]
pub struct Pane {
    /// Legacy field kept for compatibility — prefer `content`.
    pub buffer_id: BufferId,
    pub content: PaneContent,
    pub cursor_row: usize,
    pub cursor_col: usize,
    /// Desired column when navigating up/down — preserves position across short lines.
    pub col_affinity: usize,
    pub scroll_row: usize,
    /// Selection anchor (row, col) — `Some` while a region is active (Shift-move).
    pub selection_anchor: Option<(usize, usize)>,
    /// Viewport height from the last render — used by recenter (C-l).
    pub view_h: usize,
    /// User-set pane title; falls back to the buffer name / "terminal".
    pub title: Option<String>,
}

impl Pane {
    pub fn new(buffer_id: BufferId) -> Self {
        Pane {
            buffer_id,
            content: PaneContent::Editor(buffer_id),
            cursor_row: 0,
            cursor_col: 0,
            col_affinity: 0,
            scroll_row: 0,
            selection_anchor: None,
            view_h: 0,
            title: None,
        }
    }

    pub fn ensure_scroll(&mut self, viewport_height: usize, margin: usize) {
        if self.cursor_row < self.scroll_row + margin {
            self.scroll_row = self.cursor_row.saturating_sub(margin);
        } else {
            let bottom = self.scroll_row + viewport_height.saturating_sub(margin + 1);
            if self.cursor_row > bottom {
                self.scroll_row = self.cursor_row + margin + 1 - viewport_height.max(1);
            }
        }
    }
}