ito_core/viewer/
tmux_nvim.rs1use std::process::Command;
2
3use crate::errors::{CoreError, CoreResult};
4
5use super::ViewerBackend;
6use super::util::command_on_path;
7
8pub struct TmuxNvimViewer;
10
11impl ViewerBackend for TmuxNvimViewer {
12 fn name(&self) -> &str {
13 "tmux-nvim"
14 }
15
16 fn description(&self) -> &str {
17 "Open the proposal in a tmux popup with Neovim"
18 }
19
20 fn is_available(&self) -> bool {
21 std::env::var_os("TMUX").is_some() && command_on_path("tmux") && command_on_path("nvim")
22 }
23
24 fn open(&self, content: &str) -> CoreResult<()> {
25 if std::env::var_os("TMUX").is_none() {
26 return Err(CoreError::validation(
27 "tmux-nvim viewer requires an active tmux session",
28 ));
29 }
30 if !command_on_path("nvim") {
31 return Err(CoreError::not_found("nvim is not installed or not on PATH"));
32 }
33 if !command_on_path("tmux") {
34 return Err(CoreError::not_found("tmux is not installed or not on PATH"));
35 }
36
37 let mut temp_file = tempfile::Builder::new()
38 .prefix("ito-viewer-")
39 .suffix(".md")
40 .tempfile()
41 .map_err(|e| CoreError::io("creating temporary viewer file", e))?;
42 std::io::Write::write_all(&mut temp_file, content.as_bytes())
43 .map_err(|e| CoreError::io("writing temporary viewer file", e))?;
44
45 let status = Command::new("tmux")
48 .arg("display-popup")
49 .arg("-E")
50 .arg("nvim")
51 .arg("-R")
52 .arg(temp_file.path())
53 .status()
54 .map_err(|e| CoreError::io("spawning tmux display-popup", e))?;
55
56 if status.success() {
57 Ok(())
58 } else {
59 Err(CoreError::process(format!(
60 "tmux display-popup exited with status {status}"
61 )))
62 }
63 }
64}