mirror of
https://github.com/hexedtech/codemp.git
synced 2024-11-22 07:14:50 +01:00
feat: implemented basic create/sync client
This commit is contained in:
parent
754695770d
commit
2195cb28b8
2 changed files with 75 additions and 90 deletions
|
@ -1,72 +0,0 @@
|
||||||
pub mod proto_core {
|
|
||||||
tonic::include_proto!("session");
|
|
||||||
}
|
|
||||||
|
|
||||||
use tonic::transport::Channel;
|
|
||||||
|
|
||||||
use proto_core::workspace_client::WorkspaceClient;
|
|
||||||
use proto_core::SessionRequest;
|
|
||||||
|
|
||||||
use tokio::sync::{mpsc, oneshot};
|
|
||||||
|
|
||||||
use self::proto_core::SessionResponse;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Command {
|
|
||||||
CreateSession {
|
|
||||||
key: String,
|
|
||||||
resp: oneshot::Sender<SessionResponse>,
|
|
||||||
},
|
|
||||||
JoinSession {
|
|
||||||
key: String,
|
|
||||||
resp: oneshot::Sender<SessionResponse>,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Command {
|
|
||||||
pub fn create_session_cmd(key: String) -> (Command, oneshot::Receiver<SessionResponse>) {
|
|
||||||
let (resp, x) = oneshot::channel();
|
|
||||||
( Command::CreateSession { key, resp }, x )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ConnectionManager {
|
|
||||||
client: WorkspaceClient<Channel>,
|
|
||||||
rx: mpsc::Receiver<Command>
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
impl ConnectionManager {
|
|
||||||
pub async fn new(addr:String, outbound:mpsc::Receiver<Command>) -> Result<Self, Box<dyn std::error::Error>> {
|
|
||||||
Ok(ConnectionManager {
|
|
||||||
client: WorkspaceClient::connect(addr).await?,
|
|
||||||
rx: outbound
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn process_packets(&mut self) {
|
|
||||||
{
|
|
||||||
let request = tonic::Request::new(SessionRequest {
|
|
||||||
session_id: -1,
|
|
||||||
session_key: "INIT".to_string(),
|
|
||||||
});
|
|
||||||
let response = self.client.create(request).await.unwrap();
|
|
||||||
eprintln!("RESPONSE={:?}", response);
|
|
||||||
}
|
|
||||||
loop {
|
|
||||||
if let Some(cmd) = self.rx.recv().await {
|
|
||||||
match cmd {
|
|
||||||
Command::CreateSession { key, resp } => {
|
|
||||||
let request = tonic::Request::new(SessionRequest {session_id: 1, session_key: key});
|
|
||||||
let response = self.client.create(request).await.unwrap();
|
|
||||||
resp.send(response.into_inner()).unwrap();
|
|
||||||
},
|
|
||||||
_ => eprintln!("[!] Received unexpected command")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +1,21 @@
|
||||||
use rmpv::Value;
|
use rmpv::Value;
|
||||||
|
|
||||||
use tokio::io::Stdout;
|
use tokio::io::Stdout;
|
||||||
use tokio::sync::mpsc;
|
|
||||||
|
|
||||||
use nvim_rs::{compat::tokio::Compat, Handler, Neovim};
|
use nvim_rs::{compat::tokio::Compat, Handler, Neovim};
|
||||||
|
use nvim_rs::create::tokio::new_parent;
|
||||||
|
use tonic::transport::Channel;
|
||||||
|
|
||||||
use crate::manager::Command;
|
use crate::proto::{SessionRequest, workspace_client::WorkspaceClient};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct NeovimHandler {
|
pub struct NeovimHandler {
|
||||||
tx: mpsc::Sender<Command>,
|
client: WorkspaceClient<Channel>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NeovimHandler {
|
impl NeovimHandler {
|
||||||
pub async fn new(tx: mpsc::Sender<Command>) -> Result<Self, tonic::transport::Error> {
|
pub fn new(client: WorkspaceClient<Channel>) -> Self {
|
||||||
Ok(NeovimHandler { tx })
|
NeovimHandler { client }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,23 +26,65 @@ impl Handler for NeovimHandler {
|
||||||
async fn handle_request(
|
async fn handle_request(
|
||||||
&self,
|
&self,
|
||||||
name: String,
|
name: String,
|
||||||
_args: Vec<Value>,
|
args: Vec<Value>,
|
||||||
_neovim: Neovim<Compat<Stdout>>,
|
neovim: Neovim<Compat<Stdout>>,
|
||||||
) -> Result<Value, Value> {
|
) -> Result<Value, Value> {
|
||||||
match name.as_ref() {
|
match name.as_ref() {
|
||||||
"ping" => Ok(Value::from("pong")),
|
"ping" => Ok(Value::from("pong")),
|
||||||
"rpc" => {
|
"create" => {
|
||||||
let (cmd, rx) = Command::create_session_cmd("asd".to_string());
|
if args.len() < 1 {
|
||||||
self.tx.send(cmd).await.unwrap();
|
return Err(Value::from("[!] no session key"));
|
||||||
let resp = rx.await.unwrap();
|
}
|
||||||
Ok(Value::from(format!("{:?}", resp)))
|
let buf = neovim.get_current_buf().await.unwrap();
|
||||||
|
let content = buf.get_lines(0, buf.line_count().await.unwrap(), false).await.unwrap().join("\n");
|
||||||
|
let request = tonic::Request::new(SessionRequest {
|
||||||
|
session_key: args[0].to_string(), content: Some(content),
|
||||||
|
});
|
||||||
|
let mut c = self.client.clone();
|
||||||
|
let resp = c.create(request).await.unwrap().into_inner();
|
||||||
|
if resp.accepted {
|
||||||
|
Ok(Value::from(resp.session_key))
|
||||||
|
} else {
|
||||||
|
Err(Value::from("[!] rejected"))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sync" => {
|
||||||
|
if args.len() < 1 {
|
||||||
|
return Err(Value::from("[!] no session key"));
|
||||||
|
}
|
||||||
|
let buf = neovim.get_current_buf().await.unwrap();
|
||||||
|
let request = tonic::Request::new(SessionRequest {
|
||||||
|
session_key: args[0].to_string(), content: None,
|
||||||
|
});
|
||||||
|
let mut c = self.client.clone();
|
||||||
|
let resp = c.sync(request).await.unwrap().into_inner();
|
||||||
|
if let Some(content) = resp.content {
|
||||||
|
buf.set_lines(
|
||||||
|
0,
|
||||||
|
buf.line_count().await.unwrap(),
|
||||||
|
false,
|
||||||
|
content.split("\n").map(|s| s.to_string()).collect()
|
||||||
|
).await.unwrap();
|
||||||
|
Ok(Value::from(""))
|
||||||
|
} else {
|
||||||
|
Err(Value::from("[!] no content"))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"leave" => {
|
||||||
|
if args.len() < 1 {
|
||||||
|
return Err(Value::from("[!] no session key"));
|
||||||
|
}
|
||||||
|
let request = tonic::Request::new(SessionRequest {
|
||||||
|
session_key: args[0].to_string(), content: None,
|
||||||
|
});
|
||||||
|
let mut c = self.client.clone();
|
||||||
|
let resp = c.leave(request).await.unwrap().into_inner();
|
||||||
|
if resp.accepted {
|
||||||
|
Ok(Value::from(format!("closed session #{}", resp.session_key)))
|
||||||
|
} else {
|
||||||
|
Err(Value::from("[!] could not close session"))
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"buffer" => {
|
|
||||||
let buf = _neovim.create_buf(true, false).await.unwrap();
|
|
||||||
buf.set_lines(0, 1, false, vec!["codeMP".to_string()]).await.unwrap();
|
|
||||||
_neovim.set_current_buf(&buf).await.unwrap();
|
|
||||||
Ok(Value::from("ok"))
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
eprintln!("[!] unexpected call");
|
eprintln!("[!] unexpected call");
|
||||||
Ok(Value::from(""))
|
Ok(Value::from(""))
|
||||||
|
@ -62,3 +105,17 @@ impl Handler for NeovimHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn run_nvim_client(c: WorkspaceClient<Channel>) -> Result<(), Box<dyn std::error::Error + 'static>> {
|
||||||
|
let handler: NeovimHandler = NeovimHandler::new(c);
|
||||||
|
let (_nvim, io_handler) = new_parent(handler).await;
|
||||||
|
|
||||||
|
// Any error should probably be logged, as stderr is not visible to users.
|
||||||
|
match io_handler.await {
|
||||||
|
Err(err) => eprintln!("Error joining IO loop: {:?}", err),
|
||||||
|
Ok(Err(err)) => eprintln!("Process ended with error: {:?}", err),
|
||||||
|
Ok(Ok(())) => eprintln!("Finished"),
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue