use std::{
io::Write,
os::unix::net::UnixStream,
process::{Command, Stdio},
};
use anyhow::{bail, Result};
use clap::Parser;
use crate::io::Args;
pub fn nvim_open(server_address: &str, filepath: &std::path::Path) -> Result<()> {
let args = Args::parse();
if let Some(output_socket) = args.output_socket {
nvim_inform_ipc(&output_socket, NvimIPCAction::OPEN(&filepath))
} else {
nvim_remote_send_open(server_address, filepath)
}
}
fn nvim_remote_send_open(server_address: &str, filepath: &std::path::Path) -> Result<()> {
if !std::path::Path::new(server_address).exists() {
bail!("Neovim server {server_address} doesn't exists.");
}
let args = [
"--server",
server_address,
"--remote",
&filepath.to_string_lossy(),
];
let output = Command::new("nvim")
.args(args)
.stdin(Stdio::null())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.output()?;
if !output.stdout.is_empty() || !output.stderr.is_empty() {
crate::log_info!(
"nvim {args:?}\nstdout: {stdout}\nstderr: {stderr}",
stdout = String::from_utf8_lossy(&output.stdout),
stderr = String::from_utf8_lossy(&output.stderr),
);
}
Ok(())
}
#[non_exhaustive]
pub enum NvimIPCAction<'a, P>
where
P: AsRef<std::path::Path>,
{
OPEN(&'a P),
DELETE(&'a P),
}
pub fn nvim_inform_ipc<P>(output_socket: &str, action: NvimIPCAction<P>) -> Result<()>
where
P: AsRef<std::path::Path>,
{
crate::log_info!("Using argument socket file {output_socket}");
let mut stream = UnixStream::connect(output_socket)?;
match action {
NvimIPCAction::OPEN(filepath) => {
writeln!(
stream,
"OPEN {filepath}",
filepath = filepath.as_ref().display()
)?;
crate::log_info!(
"Wrote to socket {output_socket}: OPEN {filepath}",
filepath = filepath.as_ref().display()
);
}
NvimIPCAction::DELETE(filepath) => {
writeln!(
stream,
"DELETE {filepath}",
filepath = filepath.as_ref().display()
)?;
crate::log_info!(
"Wrote to socket {output_socket}: DELETE {filepath}",
filepath = filepath.as_ref().display()
);
}
}
Ok(())
}