use std::{
io::{BufRead, BufReader, Write},
process::{Child, ChildStdin, Command, Stdio},
thread::JoinHandle,
};
use winit::event_loop::EventLoopProxy;
use crate::{
AppMessage, Rpc,
json_ui::{self, Response},
};
pub struct Kakoune {
child: Child,
stdin: ChildStdin,
join_handle: JoinHandle<()>,
}
impl Kakoune {
pub fn new(event_loop_proxy: EventLoopProxy<AppMessage>) -> Self {
let mut child = Command::new("kak")
.args(["-ui", "json", "src/main.rs"])
.stdout(Stdio::piped())
.stdin(Stdio::piped())
.spawn()
.expect("Failed to spawn Kakoune");
let mut stdout = BufReader::new(child.stdout.take().expect("Failed to get Kakoune stdout"));
let stdin = child.stdin.take().expect("Failed to get stdin");
let join_handle = std::thread::spawn(move || {
let mut buf = String::new();
loop {
buf.clear();
let Ok(read) = stdout.read_line(&mut buf) else {
break;
};
if read == 0 {
break;
}
let Ok(content): Result<Rpc<json_ui::Request>, _> = serde_json::from_str(&buf)
else {
continue;
};
event_loop_proxy
.send_event(AppMessage::Kakoune(content.inner))
.unwrap();
}
});
Self {
child,
stdin,
join_handle,
}
}
pub fn send_response(&mut self, resp: Response) {
let resp = serde_json::to_string(&Rpc::from(resp)).unwrap();
self.stdin.write(resp.as_bytes()).unwrap();
self.stdin.write(b"\n").unwrap();
}
pub fn join(mut self) {
self.child.kill().unwrap();
self.child.wait().unwrap();
self.join_handle.join().unwrap();
}
}