feat!: start+end in cursor, merged cursor structs

This commit is contained in:
əlemi 2023-07-05 00:09:09 +02:00
parent 2e39cf10f1
commit d086997053
6 changed files with 53 additions and 70 deletions

View file

@ -208,7 +208,12 @@ impl Handler for NeovimHandler {
if let Err(e) = buf.clear_namespace(ns, 0, -1).await {
error!("could not clear previous cursor highlight: {}", e);
}
if let Err(e) = buf.add_highlight(ns, "ErrorMsg", cur.start.row-1, cur.start.col, cur.start.col+1).await {
if let Err(e) = buf.add_highlight(
ns, "ErrorMsg",
(cur.start().row-1) as i64,
cur.start().col as i64,
(cur.start().col+1) as i64
).await {
error!("could not create highlight for cursor: {}", e);
}
}
@ -226,13 +231,13 @@ impl Handler for NeovimHandler {
return Err(Value::from("not enough args"));
}
let path = default_empty_str(&args, 0);
let row = default_zero_number(&args, 1);
let col = default_zero_number(&args, 2);
let row = default_zero_number(&args, 1) as i32;
let col = default_zero_number(&args, 2) as i32;
match self.cursor_controller(&path) {
None => Err(Value::from("no path given")),
Some(cur) => {
cur.send(&path, (row, col).into(), (0i64, 0i64).into()).await;
cur.send(&path, (row, col).into(), (0, 0).into()).await;
Ok(Value::Nil)
}
}

View file

@ -221,10 +221,10 @@ fn callback_cursor(mut cx: FunctionContext) -> JsResult<JsUndefined> {
channel.send(move |mut cx| {
cb.to_inner(&mut cx)
.call_with(&cx)
.arg(cx.string(op.user))
.arg(cx.string(op.buffer))
.arg(tuple(&mut cx, op.start.row as i32, op.start.col as i32)?)
.arg(tuple(&mut cx, op.end.row as i32, op.end.col as i32)?)
.arg(cx.string(&op.user))
.arg(cx.string(&op.buffer))
.arg(tuple(&mut cx, op.start().row, op.start().col)?)
.arg(tuple(&mut cx, op.end().row, op.end().col)?)
.apply::<JsUndefined, _>(&mut cx)?;
Ok(())
});

View file

@ -6,8 +6,20 @@ service Buffer {
rpc Edit (OperationRequest) returns (BufferResponse);
rpc Create (BufferPayload) returns (BufferResponse);
rpc Sync (BufferPayload) returns (BufferResponse);
rpc Cursor (CursorMov) returns (BufferResponse);
rpc Listen (BufferPayload) returns (stream CursorMov);
rpc Moved (Cursor) returns (BufferResponse);
rpc Listen (BufferPayload) returns (stream Cursor);
}
message Position {
int32 row = 1;
int32 col = 2;
}
message Cursor {
string user = 1;
string buffer = 2;
Position start = 3;
Position end = 4;
}
message RawOp {
@ -15,13 +27,6 @@ message RawOp {
string user = 2;
}
message CursorMov {
string user = 1;
string path = 2;
int64 row = 3;
int64 col = 4;
}
message OperationRequest {
string path = 1;
string hash = 2;

View file

@ -5,13 +5,13 @@ use tonic::{Request, Response, Status};
use tokio_stream::{Stream, wrappers::ReceiverStream}; // TODO example used this?
use codemp::proto::{buffer_server::{Buffer, BufferServer}, RawOp, BufferPayload, BufferResponse, OperationRequest, CursorMov};
use codemp::proto::{buffer_server::{Buffer, BufferServer}, RawOp, BufferPayload, BufferResponse, OperationRequest, Cursor};
use tracing::info;
use super::actor::{BufferHandle, BufferStore};
type OperationStream = Pin<Box<dyn Stream<Item = Result<RawOp, Status>> + Send>>;
type CursorStream = Pin<Box<dyn Stream<Item = Result<CursorMov, Status>> + Send>>;
type CursorStream = Pin<Box<dyn Stream<Item = Result<Cursor, Status>> + Send>>;
struct BufferMap {
store: HashMap<String, BufferHandle>,
@ -34,7 +34,7 @@ impl BufferStore<String> for BufferMap {
pub struct BufferService {
map: Arc<RwLock<BufferMap>>,
cursor: broadcast::Sender<CursorMov>,
cursor: broadcast::Sender<Cursor>,
}
impl BufferService {
@ -88,7 +88,7 @@ impl Buffer for BufferService {
Ok(Response::new(Box::pin(output_stream)))
}
async fn cursor(&self, req:Request<CursorMov>) -> Result<Response<BufferResponse>, Status> {
async fn moved(&self, req:Request<Cursor>) -> Result<Response<BufferResponse>, Status> {
match self.cursor.send(req.into_inner()) {
Ok(_) => Ok(Response::new(BufferResponse { accepted: true, content: None})),
Err(e) => Err(Status::internal(format!("could not broadcast cursor update: {}", e))),

View file

@ -8,7 +8,7 @@ use uuid::Uuid;
use crate::{
cursor::{CursorControllerHandle, CursorControllerWorker, CursorProvider},
operation::{OperationProcessor, OperationController},
proto::{buffer_client::BufferClient, BufferPayload, OperationRequest, CursorMov}, errors::IgnorableError,
proto::{buffer_client::BufferClient, BufferPayload, OperationRequest}, errors::IgnorableError,
};
#[derive(Clone)]
@ -61,7 +61,7 @@ impl CodempClient {
}
},
Some(op) = controller.wait() => {
_client.cursor(CursorMov::from(op)).await
_client.moved(op).await
.unwrap_or_warn("could not send cursor update")
}

View file

@ -3,55 +3,27 @@ use std::sync::Arc;
use tokio::sync::{mpsc, broadcast};
use tonic::async_trait;
use crate::{proto::CursorMov, errors::IgnorableError};
use crate::{proto::{Position, Cursor}, errors::IgnorableError};
// TODO temp struct before we update protocol for real
#[derive(Clone, Debug, Default)]
pub struct Cursor {
pub user: String,
pub buffer: String,
pub start: Position,
pub end: Position,
}
impl From::<Cursor> for CursorMov {
fn from(cursor: Cursor) -> CursorMov {
CursorMov {
user: cursor.user,
path: cursor.buffer,
row: cursor.start.row,
col: cursor.start.col,
}
}
}
impl From::<CursorMov> for Cursor {
fn from(cursor: CursorMov) -> Self {
Cursor {
user: cursor.user,
buffer: cursor.path,
start: (cursor.row, cursor.col).into(),
end: (0,0).into(), // TODO temp!
}
}
}
#[derive(Copy, Clone, Debug, Default)]
pub struct Position {
pub row: i64,
pub col: i64,
}
impl From::<(i64, i64)> for Position {
fn from((row, col): (i64, i64)) -> Self {
Position { row, col }
impl From::<Position> for (i32, i32) {
fn from(pos: Position) -> (i32, i32) {
(pos.row, pos.col)
}
}
impl From::<(i32, i32)> for Position {
fn from((row, col): (i32, i32)) -> Self {
Position { row: row as i64, col: col as i64 }
Position { row, col }
}
}
impl Cursor {
pub fn start(&self) -> Position {
self.start.clone().unwrap_or((0, 0).into())
}
pub fn end(&self) -> Position {
self.end.clone().unwrap_or((0, 0).into())
}
}
@ -85,7 +57,8 @@ impl CursorSubscriber for CursorControllerHandle {
self.op.send(Cursor {
user: self.uid.clone(),
buffer: path.to_string(),
start, end
start: Some(start),
end: Some(end),
}).await.unwrap_or_warn("could not send cursor op")
}
@ -104,7 +77,7 @@ impl CursorSubscriber for CursorControllerHandle {
pub(crate) trait CursorProvider<T>
where T : CursorSubscriber {
fn subscribe(&self) -> T;
fn broadcast(&self, op: CursorMov);
fn broadcast(&self, op: Cursor);
async fn wait(&mut self) -> Option<Cursor>;
}
@ -130,8 +103,8 @@ impl CursorControllerWorker {
#[async_trait]
impl CursorProvider<CursorControllerHandle> for CursorControllerWorker {
fn broadcast(&self, op: CursorMov) {
self.channel.send(op.into()).unwrap_or_warn("could not broadcast cursor event")
fn broadcast(&self, op: Cursor) {
self.channel.send(op).unwrap_or_warn("could not broadcast cursor event")
}
async fn wait(&mut self) -> Option<Cursor> {