Skip to main content

tmai_core/runtime/
tmux_adapter.rs

1//! TmuxAdapter — delegates all RuntimeAdapter methods to TmuxClient.
2//!
3//! This is the default runtime for TUI mode. It wraps the existing
4//! `TmuxClient` with zero behavioral change.
5
6use anyhow::Result;
7
8use super::RuntimeAdapter;
9use crate::tmux::{PaneInfo, TmuxClient};
10
11/// RuntimeAdapter implementation backed by tmux.
12pub struct TmuxAdapter {
13    client: TmuxClient,
14}
15
16impl TmuxAdapter {
17    /// Create a new TmuxAdapter with the given capture line count.
18    pub fn new(capture_lines: u32) -> Self {
19        Self {
20            client: TmuxClient::with_capture_lines(capture_lines),
21        }
22    }
23}
24
25impl RuntimeAdapter for TmuxAdapter {
26    // --- Discovery ---
27
28    fn list_all_panes(&self) -> Result<Vec<PaneInfo>> {
29        self.client.list_all_panes()
30    }
31
32    fn list_panes(&self) -> Result<Vec<PaneInfo>> {
33        self.client.list_panes()
34    }
35
36    fn list_sessions(&self) -> Result<Vec<String>> {
37        self.client.list_sessions()
38    }
39
40    fn is_available(&self) -> bool {
41        self.client.is_available()
42    }
43
44    // --- Observation ---
45
46    fn capture_pane(&self, target: &str) -> Result<String> {
47        self.client.capture_pane(target)
48    }
49
50    fn capture_pane_full(&self, target: &str) -> Result<String> {
51        self.client.capture_pane_full(target)
52    }
53
54    fn capture_pane_plain(&self, target: &str) -> Result<String> {
55        self.client.capture_pane_plain(target)
56    }
57
58    fn get_pane_title(&self, target: &str) -> Result<String> {
59        self.client.get_pane_title(target)
60    }
61
62    fn get_cursor_position(&self, target: &str) -> Result<Option<(u32, u32)>> {
63        self.client.get_cursor_position(target).map(Some)
64    }
65
66    // --- Control ---
67
68    fn send_keys(&self, target: &str, keys: &str) -> Result<()> {
69        self.client.send_keys(target, keys)
70    }
71
72    fn send_keys_literal(&self, target: &str, keys: &str) -> Result<()> {
73        self.client.send_keys_literal(target, keys)
74    }
75
76    fn send_text_and_enter(&self, target: &str, text: &str) -> Result<()> {
77        self.client.send_text_and_enter(target, text)
78    }
79
80    // --- Focus / Lifecycle ---
81
82    fn focus_pane(&self, target: &str) -> Result<()> {
83        self.client.focus_pane(target)
84    }
85
86    fn kill_pane(&self, target: &str) -> Result<()> {
87        self.client.kill_pane(target)
88    }
89
90    // --- Session Management ---
91
92    fn create_session(&self, name: &str, cwd: &str, window_name: Option<&str>) -> Result<()> {
93        self.client.create_session(name, cwd, window_name)
94    }
95
96    fn new_window(&self, session: &str, cwd: &str, window_name: Option<&str>) -> Result<String> {
97        self.client.new_window(session, cwd, window_name)
98    }
99
100    fn split_window(&self, session: &str, cwd: &str) -> Result<String> {
101        self.client.split_window(session, cwd)
102    }
103
104    fn split_window_tiled(&self, session: &str, cwd: &str) -> Result<String> {
105        self.client.split_window_tiled(session, cwd)
106    }
107
108    fn select_layout(&self, target: &str, layout: &str) -> Result<()> {
109        self.client.select_layout(target, layout)
110    }
111
112    fn count_panes(&self, target: &str) -> Result<usize> {
113        self.client.count_panes(target)
114    }
115
116    fn run_command(&self, target: &str, command: &str) -> Result<()> {
117        self.client.run_command(target, command)
118    }
119
120    fn run_command_wrapped(&self, target: &str, command: &str) -> Result<()> {
121        self.client.run_command_wrapped(target, command)
122    }
123
124    fn get_current_location(&self) -> Result<(String, u32)> {
125        self.client.get_current_location()
126    }
127
128    // --- Metadata ---
129
130    fn name(&self) -> &str {
131        "tmux"
132    }
133}
134
135#[cfg(test)]
136mod tests {
137    use super::*;
138
139    #[test]
140    fn test_tmux_adapter_creation() {
141        let adapter = TmuxAdapter::new(200);
142        assert_eq!(adapter.name(), "tmux");
143    }
144}