use ratatui::layout::Rect;
use super::App;
use crate::repo;
impl App {
pub fn open_terminal_panel(&mut self) {
if self.terminal_panel.session.is_none() {
let Some(path) = self.terminal_target_path() else {
self.status_message = Some("No repository selected".to_string());
return;
};
let label = path.file_name().and_then(|n| n.to_str()).unwrap_or("shell").to_string();
let (rows, cols) = self.terminal_grid_estimate();
match crate::terminal_session::TerminalSession::spawn(&path, label, rows, cols) {
Ok(session) => self.terminal_panel.session = Some(session),
Err(e) => {
self.set_error(e);
return;
}
}
}
self.terminal_panel.visible = true;
self.terminal_focused = true;
}
pub fn hide_terminal_panel(&mut self) {
self.terminal_panel.visible = false;
self.terminal_focused = false;
}
pub fn toggle_terminal_panel(&mut self) {
if self.terminal_panel.visible {
self.hide_terminal_panel();
} else {
self.open_terminal_panel();
}
}
pub fn close_terminal_session(&mut self) {
self.terminal_panel.session = None;
self.hide_terminal_panel();
}
fn terminal_target_path(&self) -> Option<std::path::PathBuf> {
if let Some(repo::ItemDetail::Repo { resolved, .. }) = &self.current_detail {
return Some(resolved.clone());
}
self.get_selected_item().map(|item| repo::expand_tilde(item))
}
}
impl App {
pub fn terminal_panel_outer_height(&self, inner_area_height: u16) -> u16 {
if !self.terminal_panel.visible {
return 0;
}
let budget = inner_area_height.saturating_sub(self.status_height()).saturating_sub(5);
self.terminal_panel.height.clamp(5, budget.max(5))
}
pub fn terminal_grid_size(&self, inner_area: Rect) -> Option<(u16, u16)> {
let outer = self.terminal_panel_outer_height(inner_area.height);
if outer == 0 {
return None;
}
Some((outer.saturating_sub(2), inner_area.width.saturating_sub(2)))
}
fn terminal_grid_estimate(&self) -> (u16, u16) {
let (width, height) = crossterm::terminal::size().unwrap_or((80, 24));
let inner = Rect::new(0, 0, width.saturating_sub(2), height.saturating_sub(2));
let budget = inner.height.saturating_sub(self.status_height()).saturating_sub(5);
let outer = self.terminal_panel.height.clamp(5, budget.max(5));
(outer.saturating_sub(2), inner.width.saturating_sub(2))
}
}