1use rmux_proto::{
2 KillWindowRequest, LastWindowRequest, LayoutName, LinkWindowRequest, ListWindowsRequest,
3 MoveWindowRequest, MoveWindowTarget, NewWindowRequest, NextWindowRequest,
4 PreviousWindowRequest, RenameWindowRequest, Request, Response, RotateWindowDirection,
5 RotateWindowRequest, SelectCustomLayoutRequest, SelectLayoutRequest, SelectLayoutTarget,
6 SelectOldLayoutRequest, SelectWindowRequest, SessionName, SplitDirection,
7 SplitWindowExtRequest, SplitWindowRequest, SplitWindowTarget, SplitWindowTargetActionRequest,
8 SpreadLayoutRequest, SwapWindowRequest, UnlinkWindowRequest, WindowTarget,
9};
10
11use crate::{connection::Connection, ClientError};
12
13#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct SplitWindowOptions {
16 pub target: SplitWindowTarget,
18 pub direction: SplitDirection,
20 pub before: bool,
23 pub environment: Option<Vec<String>>,
25 pub command: Option<Vec<String>>,
27}
28
29impl Connection {
30 pub fn new_window(
32 &mut self,
33 target: rmux_proto::SessionName,
34 name: Option<String>,
35 detached: bool,
36 ) -> Result<Response, ClientError> {
37 self.new_window_with_environment(target, name, detached, None, None, None)
38 }
39
40 pub fn new_window_with_environment(
42 &mut self,
43 target: rmux_proto::SessionName,
44 name: Option<String>,
45 detached: bool,
46 environment: Option<Vec<String>>,
47 start_directory: Option<std::path::PathBuf>,
48 command: Option<Vec<String>>,
49 ) -> Result<Response, ClientError> {
50 self.new_window_at_with_environment(
51 target,
52 None,
53 name,
54 detached,
55 environment,
56 start_directory,
57 command,
58 false,
59 )
60 }
61
62 #[allow(clippy::too_many_arguments)]
64 pub fn new_window_at_with_environment(
65 &mut self,
66 target: rmux_proto::SessionName,
67 target_window_index: Option<u32>,
68 name: Option<String>,
69 detached: bool,
70 environment: Option<Vec<String>>,
71 start_directory: Option<std::path::PathBuf>,
72 command: Option<Vec<String>>,
73 insert_at_target: bool,
74 ) -> Result<Response, ClientError> {
75 self.roundtrip(&Request::NewWindow(Box::new(NewWindowRequest {
76 target,
77 name,
78 detached,
79 start_directory,
80 environment,
81 command,
82 process_command: None,
83 target_window_index,
84 insert_at_target,
85 })))
86 }
87
88 pub fn kill_window(
90 &mut self,
91 target: WindowTarget,
92 kill_others: bool,
93 ) -> Result<Response, ClientError> {
94 self.roundtrip(&Request::KillWindow(KillWindowRequest {
95 target,
96 kill_all_others: kill_others,
97 }))
98 }
99
100 pub fn select_window(&mut self, target: WindowTarget) -> Result<Response, ClientError> {
102 self.roundtrip(&Request::SelectWindow(SelectWindowRequest { target }))
103 }
104
105 pub fn rename_window(
107 &mut self,
108 target: WindowTarget,
109 new_name: String,
110 ) -> Result<Response, ClientError> {
111 self.roundtrip(&Request::RenameWindow(RenameWindowRequest {
112 target,
113 name: new_name,
114 }))
115 }
116
117 pub fn next_window(
119 &mut self,
120 target: SessionName,
121 alerts_only: bool,
122 ) -> Result<Response, ClientError> {
123 self.roundtrip(&Request::NextWindow(NextWindowRequest {
124 target,
125 alerts_only,
126 }))
127 }
128
129 pub fn previous_window(
131 &mut self,
132 target: SessionName,
133 alerts_only: bool,
134 ) -> Result<Response, ClientError> {
135 self.roundtrip(&Request::PreviousWindow(PreviousWindowRequest {
136 target,
137 alerts_only,
138 }))
139 }
140
141 pub fn last_window(&mut self, target: SessionName) -> Result<Response, ClientError> {
143 self.roundtrip(&Request::LastWindow(LastWindowRequest { target }))
144 }
145
146 pub fn list_windows(
148 &mut self,
149 target: SessionName,
150 format: Option<String>,
151 ) -> Result<Response, ClientError> {
152 self.list_windows_with_options(target, format, None, None, false)
153 }
154
155 pub fn list_windows_with_options(
157 &mut self,
158 target: SessionName,
159 format: Option<String>,
160 filter: Option<String>,
161 sort_order: Option<String>,
162 reversed: bool,
163 ) -> Result<Response, ClientError> {
164 self.roundtrip(&Request::ListWindows(Box::new(ListWindowsRequest {
165 target,
166 format,
167 filter,
168 sort_order,
169 reversed,
170 })))
171 }
172
173 pub fn link_window(
175 &mut self,
176 source: WindowTarget,
177 target: WindowTarget,
178 after: bool,
179 before: bool,
180 kill_destination: bool,
181 detached: bool,
182 ) -> Result<Response, ClientError> {
183 self.roundtrip(&Request::LinkWindow(LinkWindowRequest {
184 source,
185 target,
186 after,
187 before,
188 kill_destination,
189 detached,
190 }))
191 }
192
193 pub fn move_window(
195 &mut self,
196 source: Option<WindowTarget>,
197 target: MoveWindowTarget,
198 renumber: bool,
199 kill_destination: bool,
200 detached: bool,
201 ) -> Result<Response, ClientError> {
202 self.move_window_with_position(
203 source,
204 target,
205 renumber,
206 kill_destination,
207 detached,
208 false,
209 false,
210 )
211 }
212
213 #[allow(clippy::too_many_arguments)]
215 pub fn move_window_with_position(
216 &mut self,
217 source: Option<WindowTarget>,
218 target: MoveWindowTarget,
219 renumber: bool,
220 kill_destination: bool,
221 detached: bool,
222 after: bool,
223 before: bool,
224 ) -> Result<Response, ClientError> {
225 self.roundtrip(&Request::MoveWindow(MoveWindowRequest {
226 source,
227 target,
228 renumber,
229 kill_destination,
230 detached,
231 after,
232 before,
233 }))
234 }
235
236 pub fn swap_window(
238 &mut self,
239 source: WindowTarget,
240 target: WindowTarget,
241 detached: bool,
242 ) -> Result<Response, ClientError> {
243 self.roundtrip(&Request::SwapWindow(SwapWindowRequest {
244 source,
245 target,
246 detached,
247 }))
248 }
249
250 pub fn rotate_window(
252 &mut self,
253 target: WindowTarget,
254 direction: RotateWindowDirection,
255 ) -> Result<Response, ClientError> {
256 self.rotate_window_with_zoom(target, direction, false)
257 }
258
259 pub fn rotate_window_with_zoom(
261 &mut self,
262 target: WindowTarget,
263 direction: RotateWindowDirection,
264 restore_zoom: bool,
265 ) -> Result<Response, ClientError> {
266 self.roundtrip(&Request::RotateWindow(RotateWindowRequest {
267 target,
268 direction,
269 restore_zoom,
270 }))
271 }
272
273 pub fn resize_window(
275 &mut self,
276 target: WindowTarget,
277 width: Option<u16>,
278 height: Option<u16>,
279 adjustment: Option<rmux_proto::ResizeWindowAdjustment>,
280 ) -> Result<Response, ClientError> {
281 self.roundtrip(&Request::ResizeWindow(rmux_proto::ResizeWindowRequest {
282 target,
283 width,
284 height,
285 adjustment,
286 }))
287 }
288
289 pub fn unlink_window(
291 &mut self,
292 target: WindowTarget,
293 kill_if_last: bool,
294 ) -> Result<Response, ClientError> {
295 self.roundtrip(&Request::UnlinkWindow(UnlinkWindowRequest {
296 target,
297 kill_if_last,
298 }))
299 }
300
301 pub fn respawn_window(
303 &mut self,
304 target: WindowTarget,
305 kill: bool,
306 ) -> Result<Response, ClientError> {
307 self.respawn_window_with_environment(target, kill, None, None, None)
308 }
309
310 pub fn respawn_window_with_environment(
312 &mut self,
313 target: WindowTarget,
314 kill: bool,
315 environment: Option<Vec<String>>,
316 start_directory: Option<std::path::PathBuf>,
317 command: Option<Vec<String>>,
318 ) -> Result<Response, ClientError> {
319 self.roundtrip(&Request::RespawnWindow(Box::new(
320 rmux_proto::RespawnWindowRequest {
321 target,
322 kill,
323 start_directory,
324 environment,
325 command,
326 },
327 )))
328 }
329
330 pub fn split_window(&mut self, target: SplitWindowTarget) -> Result<Response, ClientError> {
332 self.split_window_with_direction(target, SplitDirection::Vertical)
333 }
334
335 pub fn split_window_with_direction(
337 &mut self,
338 target: SplitWindowTarget,
339 direction: SplitDirection,
340 ) -> Result<Response, ClientError> {
341 self.split_window_with_direction_and_environment(target, direction, None)
342 }
343
344 pub fn split_window_with_direction_and_environment(
346 &mut self,
347 target: SplitWindowTarget,
348 direction: SplitDirection,
349 environment: Option<Vec<String>>,
350 ) -> Result<Response, ClientError> {
351 self.split_window_with_spawn(target, direction, environment, None)
352 }
353
354 pub fn split_window_with_spawn(
359 &mut self,
360 target: SplitWindowTarget,
361 direction: SplitDirection,
362 environment: Option<Vec<String>>,
363 command: Option<Vec<String>>,
364 ) -> Result<Response, ClientError> {
365 self.split_window_with_start_directory(target, direction, environment, None, command)
366 }
367
368 pub fn split_window_with_start_directory(
373 &mut self,
374 target: SplitWindowTarget,
375 direction: SplitDirection,
376 environment: Option<Vec<String>>,
377 start_directory: Option<std::path::PathBuf>,
378 command: Option<Vec<String>>,
379 ) -> Result<Response, ClientError> {
380 if command.is_some() || start_directory.is_some() {
381 return self.roundtrip(&Request::SplitWindowExt(Box::new(SplitWindowExtRequest {
382 target,
383 direction,
384 before: false,
385 environment,
386 command,
387 process_command: None,
388 start_directory,
389 keep_alive_on_exit: None,
390 detached: false,
391 size: None,
392 preserve_zoom: false,
393 full_size: false,
394 stdin_payload: None,
395 })));
396 }
397 self.split_window_with_options(SplitWindowOptions {
398 target,
399 direction,
400 before: false,
401 environment,
402 command,
403 })
404 }
405
406 pub fn split_window_with_options(
408 &mut self,
409 options: SplitWindowOptions,
410 ) -> Result<Response, ClientError> {
411 let SplitWindowOptions {
412 target,
413 direction,
414 before,
415 environment,
416 command,
417 } = options;
418 if command.is_some() {
419 return self.roundtrip(&Request::SplitWindowExt(Box::new(SplitWindowExtRequest {
420 target,
421 direction,
422 before,
423 environment,
424 command,
425 process_command: None,
426 start_directory: None,
427 keep_alive_on_exit: None,
428 detached: false,
429 size: None,
430 preserve_zoom: false,
431 full_size: false,
432 stdin_payload: None,
433 })));
434 }
435 self.roundtrip(&Request::SplitWindow(SplitWindowRequest {
436 target,
437 direction,
438 before,
439 environment,
440 }))
441 }
442
443 pub fn split_window_target_action(
445 &mut self,
446 request: SplitWindowTargetActionRequest,
447 ) -> Result<Response, ClientError> {
448 self.roundtrip(&Request::SplitWindowTargetAction(Box::new(request)))
449 }
450
451 pub fn select_layout(
453 &mut self,
454 target: SelectLayoutTarget,
455 layout: LayoutName,
456 ) -> Result<Response, ClientError> {
457 self.roundtrip(&Request::SelectLayout(SelectLayoutRequest {
458 target,
459 layout,
460 }))
461 }
462
463 pub fn select_custom_layout(
465 &mut self,
466 target: SelectLayoutTarget,
467 layout: String,
468 ) -> Result<Response, ClientError> {
469 self.roundtrip(&Request::SelectCustomLayout(SelectCustomLayoutRequest {
470 target,
471 layout,
472 }))
473 }
474
475 pub fn select_old_layout(
477 &mut self,
478 target: SelectLayoutTarget,
479 ) -> Result<Response, ClientError> {
480 self.roundtrip(&Request::SelectOldLayout(SelectOldLayoutRequest { target }))
481 }
482
483 pub fn spread_layout(&mut self, target: SelectLayoutTarget) -> Result<Response, ClientError> {
485 self.roundtrip(&Request::SpreadLayout(SpreadLayoutRequest { target }))
486 }
487
488 pub fn next_layout(&mut self, target: WindowTarget) -> Result<Response, ClientError> {
490 self.roundtrip(&Request::NextLayout(rmux_proto::NextLayoutRequest {
491 target,
492 }))
493 }
494
495 pub fn previous_layout(&mut self, target: WindowTarget) -> Result<Response, ClientError> {
497 self.roundtrip(&Request::PreviousLayout(
498 rmux_proto::PreviousLayoutRequest { target },
499 ))
500 }
501}