use rmux_core::formats::{
DEFAULT_LIST_PANES_ALL_FORMAT, DEFAULT_LIST_PANES_SESSION_FORMAT,
DEFAULT_LIST_PANES_WINDOW_FORMAT,
};
use rmux_core::{Pane, Session};
use rmux_proto::OptionName;
use crate::pane_terminals::HandlerState;
use crate::pane_visible_geometry::visible_pane_content_geometry;
#[derive(Clone, Copy)]
pub(super) enum DefaultListPanesFormat {
Window,
Session,
All,
}
impl DefaultListPanesFormat {
pub(super) fn from_format(format: &str) -> Option<Self> {
match format {
DEFAULT_LIST_PANES_WINDOW_FORMAT => Some(Self::Window),
DEFAULT_LIST_PANES_SESSION_FORMAT => Some(Self::Session),
DEFAULT_LIST_PANES_ALL_FORMAT => Some(Self::All),
_ => None,
}
}
}
pub(super) fn push_default_list_panes_line(
stdout: &mut Vec<u8>,
context: DefaultListPanesLineContext<'_>,
) -> bool {
use std::fmt::Write as _;
let DefaultListPanesLineContext {
format,
state,
session,
attached_count,
window_index,
pane,
pane_active,
} = context;
let Some(history_stats) = state.pane_history_size_stats(session.name(), pane.id()) else {
return false;
};
let Some(history_bytes) = state.pane_history_bytes(session.name(), pane.id()) else {
return false;
};
let geometry = list_panes_default_geometry(state, session, attached_count, window_index, pane);
let mut line = String::new();
match format {
DefaultListPanesFormat::Window => {
let _ = write!(&mut line, "{}: ", pane.index());
}
DefaultListPanesFormat::Session => {
let _ = write!(&mut line, "{}.{}: ", window_index, pane.index());
}
DefaultListPanesFormat::All => {
let _ = write!(
&mut line,
"{}:{}.{}: ",
session.name(),
window_index,
pane.index()
);
}
}
let _ = write!(
&mut line,
"[{}x{}] [history {}/{}, {} bytes] {}",
geometry.cols(),
geometry.rows(),
history_stats.size,
history_stats.limit,
history_bytes,
pane.id()
);
if pane_active {
line.push_str(" (active)");
}
if state.pane_is_dead(session.name(), pane.id()) {
line.push_str(" (dead)");
}
stdout.extend_from_slice(line.as_bytes());
true
}
pub(super) struct DefaultListPanesLineContext<'a> {
pub(super) format: DefaultListPanesFormat,
pub(super) state: &'a HandlerState,
pub(super) session: &'a Session,
pub(super) attached_count: usize,
pub(super) window_index: u32,
pub(super) pane: &'a Pane,
pub(super) pane_active: bool,
}
fn list_panes_default_geometry(
state: &HandlerState,
session: &Session,
attached_count: usize,
window_index: u32,
pane: &Pane,
) -> rmux_core::PaneGeometry {
let geometry = pane.geometry();
if attached_count == 0 {
return geometry;
}
let size = session.window().size();
if size.cols == 0 || size.rows == 0 {
return geometry;
}
let content_rows = if matches!(
state
.options
.resolve(Some(session.name()), OptionName::Status),
Some("off")
) {
size.rows
} else {
size.rows.saturating_sub(1)
};
visible_pane_content_geometry(
&state.options,
session.name(),
window_index,
geometry,
content_rows,
)
}