use std::sync::Arc; use std::sync::LazyLock; pub static ACTIVE_SOCKET: LazyLock>>> = LazyLock::new(|| Arc::new(std::sync::Mutex::new(None))); pub static HEADLESS_PROC: LazyLock>>> = LazyLock::new(|| Arc::new(std::sync::Mutex::new(None))); pub async fn spawn_headless_nvim() -> Result { if std::process::Command::new("nvim") .arg("--version") .output() .is_err() { return Err("Error: Neovim is not installed or not in PATH. Cannot execute nvim tool. Fallback to basic terminal tools.".to_string()); } #[cfg(windows)] let socket_name = format!(r"\\.\pipe\agy-headless-nvim-{}", std::process::id()); #[cfg(unix)] let socket_name = format!("/tmp/agy-headless-nvim-{}.sock", std::process::id()); let child = tokio::process::Command::new("nvim") .arg("--headless") .arg("--listen") .arg(&socket_name) .stdin(std::process::Stdio::piped()) .stdout(std::process::Stdio::null()) .stderr(std::process::Stdio::null()) .kill_on_drop(true) .spawn() .map_err(|e| format!("Failed to spawn headless Neovim: {}", e))?; tokio::time::sleep(tokio::time::Duration::from_millis(1000)).await; let old_child = { let mut lock = HEADLESS_PROC.lock().unwrap_or_else(|e| e.into_inner()); let old = lock.take(); *lock = Some(child); old }; if let Some(mut old) = old_child { let _ = old.kill().await; } Ok(socket_name) } pub async fn kill_headless_nvim() { let child_to_kill = { let mut proc_lock = HEADLESS_PROC.lock().unwrap_or_else(|e| e.into_inner()); proc_lock.take() }; if let Some(mut child) = child_to_kill { let _ = child.kill().await; } }