diff options
Diffstat (limited to 'crates/dinggerd/src/tmux.rs')
| -rw-r--r-- | crates/dinggerd/src/tmux.rs | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/crates/dinggerd/src/tmux.rs b/crates/dinggerd/src/tmux.rs index edd44aa..cba1ca6 100644 --- a/crates/dinggerd/src/tmux.rs +++ b/crates/dinggerd/src/tmux.rs @@ -26,6 +26,9 @@ pub struct Pane { pub written_state: String, /// The `@agent` user option (agent label) previously written, if any. pub written_agent: String, + /// The `@dingger_ack` user option: "1" when the user already jumped to + /// this pane in its current ready episode. + pub written_ack: String, } impl Pane { @@ -70,7 +73,8 @@ pub fn list_panes() -> Result<Vec<Pane>, String> { "#{pane_start_command}\t", "#{pane_pid}\t", "#{@agent_state}\t", - "#{@agent}" + "#{@agent}\t", + "#{@dingger_ack}" ); let out = run_tmux(&["list-panes", "-a", "-F", format])?; let mut panes = Vec::new(); @@ -104,6 +108,7 @@ pub fn list_panes() -> Result<Vec<Pane>, String> { agent, written_state: fields[9].to_string(), written_agent: fields[10].to_string(), + written_ack: fields.get(11).copied().unwrap_or("").to_string(), }); } Ok(panes) @@ -166,6 +171,19 @@ fn fetch_process_tree() -> ProcessTree { (children, comm) } +/// Run a tmux command whose effect is an action (e.g. switch-client), not +/// output to parse. +pub fn run_tmux_client(args: &[&str]) -> Result<(), String> { + run_tmux(args).map(|_| ()) +} + +/// Read a format expansion for one pane. +pub fn show_pane_format(pane_id: &str, format: &str) -> Option<String> { + run_tmux(&["display-message", "-p", "-t", pane_id, format]) + .ok() + .map(|value| value.trim().to_string()) +} + /// Capture the pane's visible screen as plain text — the exact input shape /// the detection manifests expect. pub fn capture_pane(pane_id: &str) -> Result<String, String> { @@ -187,6 +205,28 @@ pub fn set_agent_state(pane_id: &str, state: AgentState) -> Result<(), String> { /// Label the pane with the agent running in it, for tmux status-line and /// menu-bar rendering; clears the label when the pane stops running one. pub fn set_agent(pane_id: &str, agent: Option<Agent>) -> Result<(), String> { - let label = agent.map(detect_core::agent_label).unwrap_or(""); - run_tmux(&["set-option", "-p", "-t", pane_id, "@agent", label]).map(|_| ()) + let label = agent.map(detect_core::agent_label).unwrap_or(""); + run_tmux(&["set-option", "-p", "-t", pane_id, "@agent", label]).map(|_| ()) +} + +/// Write a server-global option (readable from any client and from formats). +pub fn set_global(name: &str, value: &str) -> Result<(), String> { + run_tmux(&["set-option", "-g", name, value]).map(|_| ()) +} + +pub fn show_global(name: &str) -> Option<String> { + run_tmux(&["show-option", "-gv", name]) + .ok() + .map(|value| value.trim().to_string()) + .filter(|value| !value.is_empty()) +} + +/// Mark a pane as seen by the user after `dingger focus`: taken out of the +/// ready queue until its next state transition. +pub fn ack(pane_id: &str) -> Result<(), String> { + run_tmux(&["set-option", "-p", "-t", pane_id, "@dingger_ack", "1"]).map(|_| ()) +} + +pub fn clear_ack(pane_id: &str) -> Result<(), String> { + run_tmux(&["set-option", "-p", "-t", pane_id, "-u", "@dingger_ack"]).map(|_| ()) } |
