1use std::{
2 io::Write,
3 os::unix::net::UnixStream,
4 process::{Command, Stdio},
5};
6
7use anyhow::{bail, Result};
8use clap::Parser;
9
10use crate::io::Args;
11
12pub fn nvim_open(server_address: &str, filepath: &std::path::Path) -> Result<()> {
24 let args = Args::parse();
25 if let Some(output_socket) = args.output_socket {
26 nvim_inform_ipc(&output_socket, NvimIPCAction::OPEN(&filepath))
27 } else {
28 nvim_remote_send_open(server_address, filepath)
29 }
30}
31
32fn nvim_remote_send_open(server_address: &str, filepath: &std::path::Path) -> Result<()> {
33 if !std::path::Path::new(server_address).exists() {
34 bail!("Neovim server {server_address} doesn't exists.");
35 }
36 let args = [
37 "--server",
38 server_address,
39 "--remote",
40 &filepath.to_string_lossy(),
41 ];
42 let output = Command::new("nvim")
43 .args(args)
44 .stdin(Stdio::null())
45 .stdout(Stdio::piped())
46 .stderr(Stdio::piped())
47 .output()?;
48
49 if !output.stdout.is_empty() || !output.stderr.is_empty() {
50 crate::log_info!(
51 "nvim {args:?}\nstdout: {stdout}\nstderr: {stderr}",
52 stdout = String::from_utf8_lossy(&output.stdout),
53 stderr = String::from_utf8_lossy(&output.stderr),
54 );
55 }
56
57 Ok(())
58}
59
60#[non_exhaustive]
63pub enum NvimIPCAction<'a, P>
64where
65 P: AsRef<std::path::Path>,
66{
67 OPEN(&'a P),
68 DELETE(&'a P),
69}
70
71pub fn nvim_inform_ipc<P>(output_socket: &str, action: NvimIPCAction<P>) -> Result<()>
74where
75 P: AsRef<std::path::Path>,
76{
77 crate::log_info!("Using argument socket file {output_socket}");
78 let mut stream = UnixStream::connect(output_socket)?;
79
80 match action {
81 NvimIPCAction::OPEN(filepath) => {
82 writeln!(
83 stream,
84 "OPEN {filepath}",
85 filepath = filepath.as_ref().display()
86 )?;
87 crate::log_info!(
88 "Wrote to socket {output_socket}: OPEN {filepath}",
89 filepath = filepath.as_ref().display()
90 );
91 }
92 NvimIPCAction::DELETE(filepath) => {
93 writeln!(
94 stream,
95 "DELETE {filepath}",
96 filepath = filepath.as_ref().display()
97 )?;
98 crate::log_info!(
99 "Wrote to socket {output_socket}: DELETE {filepath}",
100 filepath = filepath.as_ref().display()
101 );
102 }
103 }
104 Ok(())
105}