diff --git a/Cargo.toml b/Cargo.toml index 7f14dd4..df7f76c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ name = "codemp_client" crate-type = ["cdylib"] [dependencies] -codemp = { git = "ssh://git@github.com/codewithotherpeopleandchangenamelater/codemp.git", tag="v0.5.0"} +codemp = { git = "ssh://git@github.com/codewithotherpeopleandchangenamelater/codemp.git", tag="v0.5.1"} pyo3 = { version = "0.20", features = ["extension-module"] } pyo3-asyncio = { version = "0.20", features = ["tokio-runtime"] } tokio = "1.29.1" diff --git a/bindings/codemp_client.cpython-38-darwin.so.REMOVED.git-id b/bindings/codemp_client.cpython-38-darwin.so.REMOVED.git-id index b93438c..5c4edd1 100644 --- a/bindings/codemp_client.cpython-38-darwin.so.REMOVED.git-id +++ b/bindings/codemp_client.cpython-38-darwin.so.REMOVED.git-id @@ -1 +1 @@ -55ed2ebf31cde48dafa1993cd5227bbe01669172 \ No newline at end of file +ef547495939b20dc50fcf0505d8ebd77dc3721f1 \ No newline at end of file diff --git a/plugin.py b/plugin.py index 7713a4a..b259af7 100644 --- a/plugin.py +++ b/plugin.py @@ -3,6 +3,11 @@ import sublime_plugin # import Codemp.codemp_client as codemp from Codemp.src.codemp_client import * + +# we import the PyTextChange type to be able to access its @classmethods: from_diff and index_to_rowcol +# PyTextChange instances are not meant to be created from python, but only received immutable from codemp. +from Codemp.bindings.codemp_client import PyTextChange + import Codemp.ext.sublime_asyncio as sublime_asyncio import asyncio import os @@ -272,6 +277,10 @@ class CodempSublimeBuffer(): while text_change := await self.controller.recv(): # In case a change arrives to a background buffer, just apply it. We are not listening on it. # Otherwise, interrupt the listening to avoid echoing back the change just received. + if text_change.is_empty(): + status_log("change is empty. skipping.") + continue + active = is_active(self.view) if active: safe_listener_detach(_txt_change_listener) diff --git a/src/lib.rs b/src/lib.rs index 7bb8215..2f30211 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,7 +6,7 @@ use codemp::errors::Error as CodempError; use pyo3::{ prelude::*, exceptions::{PyConnectionError, PyRuntimeError, PyBaseException}, - types::PyString, + types::{PyString, PyType}, }; struct PyCodempError(CodempError); @@ -324,21 +324,60 @@ impl From for PyCursorEvent { } } -#[pyclass] -struct PyTextChange { - #[pyo3(get, set)] - start_incl: usize, - - #[pyo3(get, set)] - end_excl: usize, +// TODO: change the python text change to hold a wrapper to the original text change, with helper getter +// and setters for unpacking the span, instead of a flattened version of text change. - #[pyo3(get, set)] - content: String -} +#[pyclass] +struct PyTextChange(CodempTextChange); impl From for PyTextChange { fn from(value: CodempTextChange) -> Self { - PyTextChange { start_incl: value.span.start, end_excl: value.span.end, content: value.content } + PyTextChange(value) + } +} + +#[pymethods] +impl PyTextChange { + + #[getter] + fn start_incl(&self) -> PyResult { + Ok(self.0.span.start) + } + + #[getter] + fn end_excl(&self) -> PyResult { + Ok(self.0.span.end) + } + + #[getter] + fn content(&self) -> PyResult { + Ok(self.0.content.clone()) + } + + fn is_deletion(&self) -> bool { + self.0.is_deletion() + } + + fn is_addition(&self) -> bool { + self.0.is_addition() + } + + fn is_empty(&self) -> bool { + self.0.is_empty() + } + + fn apply(&self, txt: &str) -> String { + self.0.apply(txt) + } + + #[classmethod] + fn from_diff(_cls: &PyType, before: &str, after: &str) -> PyTextChange { + PyTextChange(CodempTextChange::from_diff(before, after)) + } + + #[classmethod] + fn index_to_rowcol(_cls: &PyType, txt: &str, index: usize) -> (i32, i32) { + CodempTextChange::index_to_rowcol(txt, index).into() } }