use std::process::Command;
use crate::error::{Error, Result};
fn run(args: &[&str]) -> Result<String> {
let output = Command::new("tmux").args(args).output().map_err(|e| {
if e.kind() == std::io::ErrorKind::NotFound {
Error::TmuxMissing
} else {
Error::Tmux(e.to_string())
}
})?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr).trim().to_string();
return Err(Error::Tmux(format!("`tmux {}` → {}", args.join(" "), stderr)));
}
Ok(String::from_utf8_lossy(&output.stdout).into_owned())
}
pub fn new_session(name: &str, width: u16, height: u16, cwd: &str, command: &str) -> Result<()> {
if has_session(name)? {
return Err(Error::SessionExists(name.to_string()));
}
run(&[
"new-session",
"-d",
"-s",
name,
"-x",
&width.to_string(),
"-y",
&height.to_string(),
"-c",
cwd,
command,
])
.map(|_| ())
}
pub fn send_literal(name: &str, text: &str) -> Result<()> {
require_session(name)?;
run(&["send-keys", "-t", name, "-l", text]).map(|_| ())
}
pub fn send_key(name: &str, key: &str) -> Result<()> {
require_session(name)?;
run(&["send-keys", "-t", name, key]).map(|_| ())
}
pub fn capture_pane(name: &str) -> Result<String> {
require_session(name)?;
run(&["capture-pane", "-p", "-t", name])
}
pub fn has_session(name: &str) -> Result<bool> {
let output = Command::new("tmux")
.args(["has-session", "-t", name])
.output()
.map_err(|e| {
if e.kind() == std::io::ErrorKind::NotFound {
Error::TmuxMissing
} else {
Error::Tmux(e.to_string())
}
})?;
Ok(output.status.success())
}
pub fn kill_session(name: &str) -> Result<()> {
require_session(name)?;
run(&["kill-session", "-t", name]).map(|_| ())
}
fn require_session(name: &str) -> Result<()> {
if !has_session(name)? {
return Err(Error::NoSuchSession(name.to_string()));
}
Ok(())
}