fix: new cursor api in nvim probably

totally tested this go ahead ready for prod
This commit is contained in:
əlemi 2023-07-04 23:42:40 +02:00
parent 44c6f9eb1a
commit 2e39cf10f1

View file

@ -1,6 +1,7 @@
use std::sync::Arc; use std::sync::Arc;
use std::{net::TcpStream, sync::Mutex, collections::BTreeMap}; use std::{net::TcpStream, sync::Mutex, collections::BTreeMap};
use codemp::cursor::{CursorSubscriber, CursorControllerHandle};
use codemp::operation::{OperationController, OperationFactory, OperationProcessor}; use codemp::operation::{OperationController, OperationFactory, OperationProcessor};
use codemp::client::CodempClient; use codemp::client::CodempClient;
use codemp::proto::buffer_client::BufferClient; use codemp::proto::buffer_client::BufferClient;
@ -16,6 +17,7 @@ use tracing::{error, warn, debug, info};
struct NeovimHandler { struct NeovimHandler {
client: CodempClient, client: CodempClient,
factories: Arc<Mutex<BTreeMap<String, Arc<OperationController>>>>, factories: Arc<Mutex<BTreeMap<String, Arc<OperationController>>>>,
cursors: Arc<Mutex<BTreeMap<String, Arc<CursorControllerHandle>>>>,
} }
fn nullable_optional_str(args: &[Value], index: usize) -> Option<String> { fn nullable_optional_str(args: &[Value], index: usize) -> Option<String> {
@ -38,6 +40,10 @@ impl NeovimHandler {
fn buffer_controller(&self, path: &String) -> Option<Arc<OperationController>> { fn buffer_controller(&self, path: &String) -> Option<Arc<OperationController>> {
Some(self.factories.lock().unwrap().get(path)?.clone()) Some(self.factories.lock().unwrap().get(path)?.clone())
} }
fn cursor_controller(&self, path: &String) -> Option<Arc<CursorControllerHandle>> {
Some(self.cursors.lock().unwrap().get(path)?.clone())
}
} }
#[async_trait::async_trait] #[async_trait::async_trait]
@ -193,22 +199,17 @@ impl Handler for NeovimHandler {
let mut c = self.client.clone(); let mut c = self.client.clone();
match c.listen().await { match c.listen().await {
Err(e) => Err(Value::from(format!("could not listen cursors: {}", e))), Err(e) => Err(Value::from(format!("could not listen cursors: {}", e))),
Ok(cursor) => { Ok(mut cursor) => {
let mut sub = cursor.sub(); self.cursors.lock().unwrap().insert(path, cursor.clone().into());
debug!("spawning cursor processing worker"); debug!("spawning cursor processing worker");
tokio::spawn(async move { tokio::spawn(async move {
loop { while let Some(cur) = cursor.poll().await {
if !controller.run() { break debug!("cursor worker clean exit") } if !controller.run() { break }
match sub.recv().await { if let Err(e) = buf.clear_namespace(ns, 0, -1).await {
Err(e) => break error!("error receiving cursor update from controller: {}", e), error!("could not clear previous cursor highlight: {}", e);
Ok((_usr, cur)) => { }
if let Err(e) = buf.clear_namespace(ns, 0, -1).await { if let Err(e) = buf.add_highlight(ns, "ErrorMsg", cur.start.row-1, cur.start.col, cur.start.col+1).await {
error!("could not clear previous cursor highlight: {}", e); error!("could not create highlight for cursor: {}", e);
}
if let Err(e) = buf.add_highlight(ns, "ErrorMsg", cur.start.row-1, cur.start.col, cur.start.col+1).await {
error!("could not create highlight for cursor: {}", e);
}
}
} }
} }
if let Err(e) = buf.clear_namespace(ns, 0, -1).await { if let Err(e) = buf.clear_namespace(ns, 0, -1).await {
@ -228,10 +229,12 @@ impl Handler for NeovimHandler {
let row = default_zero_number(&args, 1); let row = default_zero_number(&args, 1);
let col = default_zero_number(&args, 2); let col = default_zero_number(&args, 2);
let mut c = self.client.clone(); match self.cursor_controller(&path) {
match c.cursor(path, row, col).await { None => Err(Value::from("no path given")),
Ok(_) => Ok(Value::Nil), Some(cur) => {
Err(e) => Err(Value:: from(format!("could not update cursor: {}", e))), cur.send(&path, (row, col).into(), (0i64, 0i64).into()).await;
Ok(Value::Nil)
}
} }
}, },
@ -291,6 +294,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let handler: NeovimHandler = NeovimHandler { let handler: NeovimHandler = NeovimHandler {
client: client.into(), client: client.into(),
factories: Arc::new(Mutex::new(BTreeMap::new())), factories: Arc::new(Mutex::new(BTreeMap::new())),
cursors: Arc::new(Mutex::new(BTreeMap::new())),
}; };
let (_nvim, io_handler) = create::new_parent(handler).await; let (_nvim, io_handler) = create::new_parent(handler).await;