1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
//! Nested-tmux-safe attach helper shared by `tm launch`, `tm connect`, and the
//! guided picker's resume/restart paths.
//!
//! Why: tmux refuses `attach-session` when invoked from inside an existing
//! tmux client (i.e. `$TMUX` is set), to avoid nesting one tmux client inside
//! another. Every call site that hands the terminal over to a tmux session hit
//! this failure identically ("sessions should be nested with care, unset
//! $TMUX to force" / `Error: tmux attach-session exited with failure").
//! What: [`attach_argv`] is the pure decision function (testable without
//! spawning tmux) that picks `switch-client` vs `attach-session` argv based on
//! whether the caller is already inside tmux; [`inside_tmux`] reads `$TMUX`;
//! [`tmux_attach`] ties them together — it shells out to the resulting tmux
//! subcommand and translates a `switch-client` failure into an actionable
//! hint.
//! Test: `attach_argv_inside_tmux_uses_switch_client`,
//! `attach_argv_outside_tmux_uses_attach_session` cover the pure decision
//! logic directly; `tmux_attach` itself is exercised indirectly by the
//! picker/launch/connect flows (it spawns a real `tmux` process).
use Context as _;
/// Build the tmux argv for attaching to `session`, adapting to nesting.
///
/// Why: `tmux attach-session` errors out when `$TMUX` is already set (a
/// nested client), but `switch-client -t <session>` is the documented
/// nested-safe idiom — it moves the *current* client to the target session
/// instead of trying to spawn a new client inside the existing one.
/// What: returns `["switch-client", "-t", session]` when `inside_tmux` is
/// `true`, else `["attach-session", "-t", session]`.
/// Test: `attach_argv_inside_tmux_uses_switch_client`,
/// `attach_argv_outside_tmux_uses_attach_session`.
pub
/// Detect whether the current process is already running inside a tmux client.
///
/// Why: centralizes the `$TMUX` check so every call site uses identical
/// semantics — an empty value (which tmux never sets, but a shell script
/// could export) is treated the same as unset.
/// What: returns `true` when the `TMUX` environment variable is set to a
/// non-empty string.
/// Test: environment-dependent, so it is exercised indirectly; `attach_argv`
/// takes the resulting bool directly so its tests stay hermetic.
pub
/// Attach (or switch) the current terminal into the tmux session `name`.
///
/// Why: single choke point for the nested-tmux-safe attach behavior so
/// `guided.rs` and `launch.rs` don't each re-implement the `$TMUX` branch —
/// and so a `switch-client` failure gets a more actionable error than a bare
/// "exited with failure".
/// What: shells out to `tmux <attach_argv(name, inside_tmux())>` and waits;
/// returns `Err` if tmux exits with a non-zero status. When the nested-client
/// `switch-client` path fails, the error mentions that the target session may
/// live on a different tmux server.
/// Test: exercised indirectly by the picker/launch/connect flows; the argv
/// selection itself is unit-tested via `attach_argv`.
pub