use crate::SettingsUI;
use crate::search::SearchTag;
use crate::section::{INPUT_WIDTH, keyword_section};
use std::collections::HashSet;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MuxHookStatus {
pub agent: String,
pub installed: bool,
}
pub(crate) fn show_par_mux_section(
ui: &mut egui::Ui,
settings: &mut SettingsUI,
changes_this_frame: &mut bool,
collapsed: &mut HashSet<String>,
) {
keyword_section(
ui,
"par-mux",
"sessions_par_mux",
&["mux", "daemon", "attach", "hooks", "agent hooks"],
true,
collapsed,
|ui| {
ui.label(
egui::RichText::new(
"par-mux keeps tabs and panes running in a background daemon, so a \
window can detach and reattach without losing work.",
)
.small()
.weak(),
);
ui.add_space(4.0);
ui.horizontal(|ui| {
ui.label("Attach on launch:");
let mut session = settings
.config
.tmux
.mux_auto_attach
.clone()
.unwrap_or_default();
let response = ui
.add(
egui::TextEdit::singleline(&mut session)
.desired_width(INPUT_WIDTH)
.hint_text("session name (empty = off)"),
)
.search_tag(&["mux_auto_attach", "auto attach"])
.on_hover_text(
"The first window attaches to this par-mux session on launch, \
creating it when it does not exist. Empty: no auto-attach. \
The --attach command-line option takes precedence.",
);
if response.changed() {
let trimmed = session.trim();
settings.config.tmux.mux_auto_attach =
(!trimmed.is_empty()).then(|| trimmed.to_string());
settings.has_changes = true;
*changes_this_frame = true;
}
});
ui.add_space(8.0);
show_hook_status(ui, settings);
ui.add_space(8.0);
ui.label(
egui::RichText::new(
"Closing the last tab of an attached session always asks whether to \
detach (the session keeps running) or end it. Per-profile par-mux \
sessions are set in each profile's Session page.",
)
.small()
.weak(),
);
},
);
}
fn show_hook_status(ui: &mut egui::Ui, settings: &mut SettingsUI) {
ui.label(egui::RichText::new("Agent session hooks").strong());
ui.label(
egui::RichText::new(
"Hooks let par-mux show which coding agent runs in each pane. Install or \
remove them with `par-term install-mux-hooks` and `par-term \
uninstall-mux-hooks`.",
)
.small()
.weak(),
);
let Some(status_fn) = settings.mux_hook_status_fn else {
ui.label(egui::RichText::new("Hook status is not available.").small());
return;
};
if ui
.small_button("Refresh")
.on_hover_text("Read the agents' config files again")
.clicked()
{
settings.mux_hook_status = None;
}
let statuses = settings
.mux_hook_status
.get_or_insert_with(status_fn)
.clone();
for status in statuses {
ui.horizontal(|ui| {
ui.label(format!("{}:", status.agent));
if status.installed {
ui.colored_label(egui::Color32::from_rgb(76, 175, 80), "installed");
} else {
ui.colored_label(egui::Color32::GRAY, "not installed");
}
});
}
}