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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//! 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
/// Resolve the tmux session name of the CURRENT client's pane (#2157 item 4).
///
/// Why: the nested-session guard in `guided.rs` needs to know which tmux
/// session bare `tm` is running inside, so it can check whether that session
/// already maps to a managed record BEFORE offering to launch a brand-new
/// (nested) one. `$TMUX`'s own value encodes a socket path and a numeric
/// window/pane index, not the session's NAME, so the name has to come from
/// tmux itself.
/// What: returns `None` immediately when [`inside_tmux`] is `false` (no
/// session to query). Otherwise runs `tmux display-message -p '#S'` and
/// returns the trimmed, non-empty stdout, or `None` on any I/O failure,
/// non-zero exit, or empty output.
/// Test: I/O path, not unit-tested (requires a live tmux server); the guard's
/// decision logic that CONSUMES this value is pure and tested separately
/// (`nested_managed_match_*` in `tests_behavior_c_tests.rs`).
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