1use rmux_proto::{
2 BreakPaneRequest, CancelSdkWaitRequest, ClockModeRequest, CopyModeRequest, DisplayPanesRequest,
3 JoinPaneRequest, KillPaneRequest, LastPaneRequest, MovePaneRequest, PaneBroadcastInputRequest,
4 PaneInputRequest, PaneOutputCursorRequest, PaneOutputSubscriptionId,
5 PaneOutputSubscriptionStart, PaneSnapshotRefRequest, PaneTarget, PaneTargetRef,
6 PipePaneRequest, Request, ResizePaneAdjustment, ResizePaneRequest,
7 ResizePaneTargetActionRequest, RespawnPaneRequest, Response, SdkWaitForOutputRefRequest,
8 SdkWaitId, SdkWaitOwnerId, SelectPaneAdjacentRequest, SelectPaneDirection,
9 SelectPaneMarkRequest, SelectPaneRequest, SendKeysExt2Request, SendKeysExtRequest,
10 SendKeysRequest, SendPrefixRequest, SessionName, SubscribePaneOutputRefRequest,
11 SwapPaneDirection, SwapPaneRequest, UnsubscribePaneOutputRequest, WindowTarget,
12 CAPABILITY_SDK_PANE_BROADCAST, CAPABILITY_SDK_PANE_BY_ID, CAPABILITY_SDK_WAITS,
13 CAPABILITY_TARGET_CLIENT_COMMANDS,
14};
15
16use crate::{connection::Connection, ClientError};
17
18impl Connection {
19 pub fn swap_pane(
21 &mut self,
22 source: PaneTarget,
23 target: PaneTarget,
24 detached: bool,
25 preserve_zoom: bool,
26 ) -> Result<Response, ClientError> {
27 self.roundtrip(&Request::SwapPane(SwapPaneRequest {
28 source,
29 target,
30 direction: None,
31 detached,
32 preserve_zoom,
33 }))
34 }
35
36 pub fn swap_pane_with_next(
38 &mut self,
39 target: PaneTarget,
40 detached: bool,
41 preserve_zoom: bool,
42 ) -> Result<Response, ClientError> {
43 self.roundtrip(&Request::SwapPane(SwapPaneRequest {
44 source: target.clone(),
45 target,
46 direction: Some(SwapPaneDirection::Down),
47 detached,
48 preserve_zoom,
49 }))
50 }
51
52 pub fn swap_pane_with_previous(
54 &mut self,
55 target: PaneTarget,
56 detached: bool,
57 preserve_zoom: bool,
58 ) -> Result<Response, ClientError> {
59 self.roundtrip(&Request::SwapPane(SwapPaneRequest {
60 source: target.clone(),
61 target,
62 direction: Some(SwapPaneDirection::Up),
63 detached,
64 preserve_zoom,
65 }))
66 }
67
68 pub fn last_pane(&mut self, target: WindowTarget) -> Result<Response, ClientError> {
70 self.last_pane_with_zoom(target, false)
71 }
72
73 pub fn last_pane_with_zoom(
75 &mut self,
76 target: WindowTarget,
77 preserve_zoom: bool,
78 ) -> Result<Response, ClientError> {
79 self.last_pane_with_options(target, preserve_zoom, None)
80 }
81
82 pub fn last_pane_with_options(
84 &mut self,
85 target: WindowTarget,
86 preserve_zoom: bool,
87 input_disabled: Option<bool>,
88 ) -> Result<Response, ClientError> {
89 self.roundtrip(&Request::LastPane(LastPaneRequest {
90 target,
91 preserve_zoom,
92 input_disabled,
93 }))
94 }
95
96 pub fn join_pane(&mut self, request: JoinPaneRequest) -> Result<Response, ClientError> {
98 self.roundtrip(&Request::JoinPane(request))
99 }
100
101 pub fn move_pane(&mut self, request: MovePaneRequest) -> Result<Response, ClientError> {
103 self.roundtrip(&Request::MovePane(request))
104 }
105
106 pub fn break_pane(&mut self, request: BreakPaneRequest) -> Result<Response, ClientError> {
108 self.roundtrip(&Request::BreakPane(Box::new(request)))
109 }
110
111 pub fn resize_pane(
113 &mut self,
114 target: PaneTarget,
115 adjustment: ResizePaneAdjustment,
116 ) -> Result<Response, ClientError> {
117 self.roundtrip(&Request::ResizePane(ResizePaneRequest {
118 target,
119 adjustment,
120 }))
121 }
122
123 pub fn resize_pane_target_action(
125 &mut self,
126 request: ResizePaneTargetActionRequest,
127 ) -> Result<Response, ClientError> {
128 self.roundtrip(&Request::ResizePaneTargetAction(request))
129 }
130
131 pub fn display_panes(
133 &mut self,
134 target: SessionName,
135 duration_ms: Option<u64>,
136 non_blocking: bool,
137 no_command: bool,
138 template: Option<String>,
139 ) -> Result<Response, ClientError> {
140 let request = Request::DisplayPanes(DisplayPanesRequest {
141 target,
142 duration_ms,
143 non_blocking,
144 no_command,
145 template,
146 });
147 if non_blocking {
148 self.roundtrip(&request)
149 } else {
150 self.roundtrip_without_read_timeout(&request)
151 }
152 }
153
154 pub fn pipe_pane(
156 &mut self,
157 target: PaneTarget,
158 stdin: bool,
159 stdout: bool,
160 once: bool,
161 command: Option<String>,
162 ) -> Result<Response, ClientError> {
163 self.roundtrip(&Request::PipePane(PipePaneRequest {
164 target,
165 stdin,
166 stdout,
167 once,
168 command,
169 }))
170 }
171
172 pub fn respawn_pane(&mut self, request: RespawnPaneRequest) -> Result<Response, ClientError> {
174 self.roundtrip(&Request::RespawnPane(Box::new(request)))
175 }
176
177 pub fn select_pane(&mut self, target: PaneTarget) -> Result<Response, ClientError> {
179 self.select_pane_with_title(target, None)
180 }
181
182 pub fn select_pane_with_title(
184 &mut self,
185 target: PaneTarget,
186 title: Option<String>,
187 ) -> Result<Response, ClientError> {
188 self.select_pane_with_title_and_zoom(target, title, false)
189 }
190
191 pub fn select_pane_with_title_and_zoom(
193 &mut self,
194 target: PaneTarget,
195 title: Option<String>,
196 preserve_zoom: bool,
197 ) -> Result<Response, ClientError> {
198 self.select_pane_with_options(target, title, None, None, preserve_zoom)
199 }
200
201 pub fn select_pane_with_options(
203 &mut self,
204 target: PaneTarget,
205 title: Option<String>,
206 style: Option<String>,
207 input_disabled: Option<bool>,
208 preserve_zoom: bool,
209 ) -> Result<Response, ClientError> {
210 self.roundtrip(&Request::SelectPane(Box::new(SelectPaneRequest {
211 target,
212 title,
213 input_disabled,
214 preserve_zoom,
215 style,
216 })))
217 }
218
219 pub fn select_pane_input(
221 &mut self,
222 target: PaneTarget,
223 disabled: bool,
224 ) -> Result<Response, ClientError> {
225 self.roundtrip(&Request::SelectPane(Box::new(SelectPaneRequest {
226 target,
227 title: None,
228 style: None,
229 input_disabled: Some(disabled),
230 preserve_zoom: false,
231 })))
232 }
233
234 pub fn select_pane_adjacent(
236 &mut self,
237 target: PaneTarget,
238 direction: SelectPaneDirection,
239 ) -> Result<Response, ClientError> {
240 self.select_pane_adjacent_with_zoom(target, direction, false)
241 }
242
243 pub fn select_pane_adjacent_with_zoom(
245 &mut self,
246 target: PaneTarget,
247 direction: SelectPaneDirection,
248 preserve_zoom: bool,
249 ) -> Result<Response, ClientError> {
250 self.roundtrip(&Request::SelectPaneAdjacent(SelectPaneAdjacentRequest {
251 target,
252 direction,
253 preserve_zoom,
254 }))
255 }
256
257 pub fn select_pane_mark(
259 &mut self,
260 target: PaneTarget,
261 clear: bool,
262 ) -> Result<Response, ClientError> {
263 self.select_pane_mark_with_title(target, clear, None)
264 }
265
266 pub fn select_pane_mark_with_title(
268 &mut self,
269 target: PaneTarget,
270 clear: bool,
271 title: Option<String>,
272 ) -> Result<Response, ClientError> {
273 self.roundtrip(&Request::SelectPaneMark(SelectPaneMarkRequest {
274 target,
275 clear,
276 title,
277 }))
278 }
279
280 pub fn kill_pane(&mut self, target: PaneTarget) -> Result<Response, ClientError> {
282 self.kill_pane_with_options(target, false)
283 }
284
285 pub fn kill_pane_with_options(
287 &mut self,
288 target: PaneTarget,
289 kill_all_except: bool,
290 ) -> Result<Response, ClientError> {
291 self.roundtrip(&Request::KillPane(KillPaneRequest {
292 target,
293 kill_all_except,
294 }))
295 }
296
297 pub fn send_keys(
299 &mut self,
300 target: PaneTarget,
301 keys: Vec<String>,
302 ) -> Result<Response, ClientError> {
303 self.roundtrip(&Request::SendKeys(SendKeysRequest { target, keys }))
304 }
305
306 pub fn send_keys_extended(
308 &mut self,
309 request: SendKeysExtRequest,
310 ) -> Result<Response, ClientError> {
311 self.roundtrip(&Request::SendKeysExt(request))
312 }
313
314 pub fn send_keys_extended_target_client(
316 &mut self,
317 request: SendKeysExt2Request,
318 ) -> Result<Response, ClientError> {
319 if !self.supports_capability(CAPABILITY_TARGET_CLIENT_COMMANDS)? {
320 return Err(ClientError::Protocol(
321 rmux_proto::RmuxError::UnsupportedCapability {
322 feature: CAPABILITY_TARGET_CLIENT_COMMANDS.to_owned(),
323 supported: Vec::new(),
324 },
325 ));
326 }
327 self.roundtrip(&Request::SendKeysExt2(Box::new(request)))
328 }
329
330 pub fn pane_input(&mut self, request: PaneInputRequest) -> Result<Response, ClientError> {
332 if !self.supports_capability(CAPABILITY_SDK_PANE_BY_ID)? {
333 return Err(ClientError::Protocol(
334 rmux_proto::RmuxError::UnsupportedCapability {
335 feature: CAPABILITY_SDK_PANE_BY_ID.to_owned(),
336 supported: Vec::new(),
337 },
338 ));
339 }
340 self.roundtrip(&Request::PaneInput(request))
341 }
342
343 pub fn pane_broadcast_input(
345 &mut self,
346 request: PaneBroadcastInputRequest,
347 ) -> Result<Response, ClientError> {
348 if !self.supports_capability(CAPABILITY_SDK_PANE_BROADCAST)? {
349 return Err(ClientError::Protocol(
350 rmux_proto::RmuxError::UnsupportedCapability {
351 feature: CAPABILITY_SDK_PANE_BROADCAST.to_owned(),
352 supported: Vec::new(),
353 },
354 ));
355 }
356 self.roundtrip(&Request::PaneBroadcastInput(request))
357 }
358
359 pub fn pane_snapshot_ref(&mut self, target: PaneTargetRef) -> Result<Response, ClientError> {
361 if !self.supports_capability(CAPABILITY_SDK_PANE_BY_ID)? {
362 return Err(ClientError::Protocol(
363 rmux_proto::RmuxError::UnsupportedCapability {
364 feature: CAPABILITY_SDK_PANE_BY_ID.to_owned(),
365 supported: Vec::new(),
366 },
367 ));
368 }
369 self.roundtrip(&Request::PaneSnapshotRef(PaneSnapshotRefRequest { target }))
370 }
371
372 pub fn subscribe_pane_output_ref(
374 &mut self,
375 target: PaneTargetRef,
376 start: PaneOutputSubscriptionStart,
377 ) -> Result<Response, ClientError> {
378 if !self.supports_capability(CAPABILITY_SDK_PANE_BY_ID)? {
379 return Err(ClientError::Protocol(
380 rmux_proto::RmuxError::UnsupportedCapability {
381 feature: CAPABILITY_SDK_PANE_BY_ID.to_owned(),
382 supported: Vec::new(),
383 },
384 ));
385 }
386 self.roundtrip(&Request::SubscribePaneOutputRef(
387 SubscribePaneOutputRefRequest { target, start },
388 ))
389 }
390
391 pub fn pane_output_cursor(
393 &mut self,
394 subscription_id: PaneOutputSubscriptionId,
395 max_events: Option<u16>,
396 ) -> Result<Response, ClientError> {
397 self.roundtrip(&Request::PaneOutputCursor(PaneOutputCursorRequest {
398 subscription_id,
399 max_events,
400 }))
401 }
402
403 pub fn unsubscribe_pane_output(
405 &mut self,
406 subscription_id: PaneOutputSubscriptionId,
407 ) -> Result<Response, ClientError> {
408 self.roundtrip(&Request::UnsubscribePaneOutput(
409 UnsubscribePaneOutputRequest { subscription_id },
410 ))
411 }
412
413 pub fn sdk_wait_for_output_ref(
415 &mut self,
416 owner_id: SdkWaitOwnerId,
417 wait_id: SdkWaitId,
418 target: PaneTargetRef,
419 bytes: Vec<u8>,
420 start: PaneOutputSubscriptionStart,
421 ) -> Result<Response, ClientError> {
422 if !self.supports_capability(CAPABILITY_SDK_WAITS)? {
423 return Err(ClientError::Protocol(
424 rmux_proto::RmuxError::UnsupportedCapability {
425 feature: CAPABILITY_SDK_WAITS.to_owned(),
426 supported: Vec::new(),
427 },
428 ));
429 }
430 self.roundtrip_without_read_timeout(&Request::SdkWaitForOutputRef(
431 SdkWaitForOutputRefRequest {
432 owner_id,
433 wait_id,
434 target,
435 bytes,
436 start,
437 },
438 ))
439 }
440
441 pub fn arm_sdk_wait_for_output_ref(
446 &mut self,
447 owner_id: SdkWaitOwnerId,
448 wait_id: SdkWaitId,
449 target: PaneTargetRef,
450 bytes: Vec<u8>,
451 start: PaneOutputSubscriptionStart,
452 ) -> Result<(), ClientError> {
453 if !self.supports_capability(CAPABILITY_SDK_WAITS)? {
454 return Err(ClientError::Protocol(
455 rmux_proto::RmuxError::UnsupportedCapability {
456 feature: CAPABILITY_SDK_WAITS.to_owned(),
457 supported: Vec::new(),
458 },
459 ));
460 }
461 self.write_request(&Request::SdkWaitForOutputRef(SdkWaitForOutputRefRequest {
462 owner_id,
463 wait_id,
464 target,
465 bytes,
466 start,
467 }))
468 }
469
470 pub fn cancel_sdk_wait(
472 &mut self,
473 owner_id: SdkWaitOwnerId,
474 wait_id: SdkWaitId,
475 ) -> Result<Response, ClientError> {
476 if !self.supports_capability(CAPABILITY_SDK_WAITS)? {
477 return Err(ClientError::Protocol(
478 rmux_proto::RmuxError::UnsupportedCapability {
479 feature: CAPABILITY_SDK_WAITS.to_owned(),
480 supported: Vec::new(),
481 },
482 ));
483 }
484 self.roundtrip(&Request::CancelSdkWait(CancelSdkWaitRequest {
485 owner_id,
486 wait_id,
487 }))
488 }
489
490 pub fn send_prefix(
492 &mut self,
493 target: Option<PaneTarget>,
494 secondary: bool,
495 ) -> Result<Response, ClientError> {
496 self.roundtrip(&Request::SendPrefix(SendPrefixRequest {
497 target,
498 secondary,
499 }))
500 }
501
502 pub fn copy_mode(&mut self, request: CopyModeRequest) -> Result<Response, ClientError> {
504 self.roundtrip(&Request::CopyMode(request))
505 }
506
507 pub fn clock_mode(&mut self, target: Option<PaneTarget>) -> Result<Response, ClientError> {
509 self.roundtrip(&Request::ClockMode(ClockModeRequest { target }))
510 }
511}