use libtmux::{Error, Session};
use crate::config::{PaneConfig, ShellCommand, WindowConfig, Workspace};
pub async fn freeze(session: &Session) -> Result<Workspace, Error> {
let default_shell = session.format("#{default-shell}").await?;
let default_shell = basename(&default_shell.to_string_lossy()).to_owned();
let mut windows = Vec::new();
for window in session.windows().await? {
let mut panes = Vec::new();
for pane in window.panes().await? {
let command = pane
.current_command()
.map(|command| command.to_string_lossy().into_owned())
.filter(|command| {
let name = basename(command);
name != default_shell && !SHELLS.contains(&name)
});
panes.push(PaneConfig {
shell_commands: command.map(ShellCommand::new).into_iter().collect(),
start_directory: pane
.current_path()
.map(|path| path.to_string_lossy().into_owned().into()),
focus: pane.is_active(),
..PaneConfig::default()
});
}
windows.push(WindowConfig {
window_name: Some(window.name().to_string_lossy().into_owned()),
window_index: None,
window_shell: None,
environment: Vec::new(),
layout: Some(window.layout().to_string_lossy().into_owned()),
start_directory: None,
focus: window.is_active(),
options: Vec::new(),
shell_command_before: Vec::new(),
suppress_history: None,
panes,
unsupported_keys: Vec::new(),
});
}
Ok(Workspace {
session_name: session.name().to_string_lossy().into_owned(),
start_directory: None,
environment: Vec::new(),
options: Vec::new(),
global_options: Vec::new(),
shell_command_before: Vec::new(),
suppress_history: true,
windows,
unsupported_keys: Vec::new(),
})
}
fn basename(text: &str) -> &str {
text.rsplit('/').next().unwrap_or(text)
}
const SHELLS: &[&str] = &[
"sh", "bash", "zsh", "dash", "ash", "ksh", "mksh", "fish", "csh", "tcsh",
];