Skip to main content

flow_tmux/
session.rs

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
12/// Open a tmux session for a worktree path.
13///
14/// # Errors
15///
16/// Returns an error if the session cannot be created or switched to.
17pub 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    // Check if session exists
24    let check = std::process::Command::new("tmux")
25        .args(["has-session", "-t", session_name])
26        .output()?;
27
28    if !check.status.success() {
29        // Create new session
30        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    // Switch to session
49    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
57/// Switch to a project path in tmux.
58///
59/// # Errors
60///
61/// Returns an error if the session cannot be switched to.
62pub fn switch_to(path: &Path) -> Result<(), SessionError> {
63    open_worktree(path)
64}
65
66/// List all tmux sessions.
67///
68/// # Errors
69///
70/// Returns an error if the sessions cannot be listed.
71pub 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()); // No sessions or tmux not running
78    }
79
80    Ok(String::from_utf8_lossy(&output.stdout)
81        .lines()
82        .map(std::string::ToString::to_string)
83        .collect())
84}