1use std::path::Path;
2use thiserror::Error;
3
4#[derive(Error, Debug)]
5pub enum SessionError {
6 #[error("Tmux error: {0}")]
7 Tmux(String),
8 #[error("IO error: {0}")]
9 Io(#[from] std::io::Error),
10}
11
12pub fn open_worktree(path: &Path) -> Result<(), SessionError> {
18 let session_name = path
19 .file_name()
20 .and_then(|n| n.to_str())
21 .unwrap_or("worktree");
22
23 let check = std::process::Command::new("tmux")
25 .args(["has-session", "-t", session_name])
26 .output()?;
27
28 if !check.status.success() {
29 let output = std::process::Command::new("tmux")
31 .args([
32 "new-session",
33 "-d",
34 "-s",
35 session_name,
36 "-c",
37 path.to_str().unwrap_or("."),
38 ])
39 .output()?;
40
41 if !output.status.success() {
42 return Err(SessionError::Tmux(
43 String::from_utf8_lossy(&output.stderr).to_string(),
44 ));
45 }
46 }
47
48 std::process::Command::new("tmux")
50 .args(["switch-client", "-t", session_name])
51 .output()?;
52
53 tracing::info!("Opened tmux session: {}", session_name);
54 Ok(())
55}
56
57pub fn switch_to(path: &Path) -> Result<(), SessionError> {
63 open_worktree(path)
64}
65
66pub fn list_sessions() -> Result<Vec<String>, SessionError> {
72 let output = std::process::Command::new("tmux")
73 .args(["list-sessions", "-F", "#{session_name}"])
74 .output()?;
75
76 if !output.status.success() {
77 return Ok(Vec::new()); }
79
80 Ok(String::from_utf8_lossy(&output.stdout)
81 .lines()
82 .map(std::string::ToString::to_string)
83 .collect())
84}