mirror of
https://github.com/hexedtech/codemp.git
synced 2024-11-22 07:14:50 +01:00
feat: moved TextChange into api, added from diff
This commit is contained in:
parent
5208ff65c0
commit
2ccb5c936b
6 changed files with 66 additions and 19 deletions
56
src/api/change.rs
Normal file
56
src/api/change.rs
Normal file
|
@ -0,0 +1,56 @@
|
|||
//! # TextChange
|
||||
//! this represent a range in the previous state of the string and a new content which should be
|
||||
//! replaced to it, allowing to represent any combination of deletions, insertions or replacements
|
||||
//!
|
||||
//! bulk and widespread operations will result in a TextChange effectively sending the whole new
|
||||
//! buffer, but small changes are efficient and easy to create or apply
|
||||
//!
|
||||
//! ### examples
|
||||
//! to insert 'a' after 4th character we should send a
|
||||
//! `TextChange { span: 4..4, content: "a".into() }`
|
||||
//!
|
||||
//! to delete a the fourth character we should send a
|
||||
//! `TextChange { span: 3..4, content: "".into() }`
|
||||
//!
|
||||
|
||||
/// an editor-friendly representation of a text change in a buffer
|
||||
/// span refers to previous text content
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct TextChange {
|
||||
/// range of text change, as char indexes in buffer previous state
|
||||
pub span: std::ops::Range<usize>,
|
||||
/// new content of text inside span
|
||||
pub content: String,
|
||||
}
|
||||
|
||||
impl TextChange {
|
||||
/// create a new TextChange from the difference of given strings
|
||||
pub fn from_diff(before: &str, after: &str) -> TextChange {
|
||||
let diff = similar::TextDiff::from_chars(before, after);
|
||||
let mut start = 0;
|
||||
let mut end = 0;
|
||||
let mut from_beginning = true;
|
||||
for op in diff.ops() {
|
||||
match op {
|
||||
similar::DiffOp::Equal { .. } => {
|
||||
if from_beginning {
|
||||
start += 1
|
||||
} else {
|
||||
end += 1
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
end = 0;
|
||||
from_beginning = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
let end_before = before.len() - end;
|
||||
let end_after = after.len() - end;
|
||||
|
||||
TextChange {
|
||||
span: start..end_before,
|
||||
content: after[start..end_after].to_string(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,4 +7,8 @@
|
|||
/// a generic async provider for bidirectional communication
|
||||
pub mod controller;
|
||||
|
||||
/// a generic representation of a text change
|
||||
pub mod change;
|
||||
|
||||
pub use controller::Controller;
|
||||
pub use change::TextChange;
|
||||
|
|
|
@ -11,7 +11,7 @@ use tonic::async_trait;
|
|||
use crate::errors::IgnorableError;
|
||||
use crate::{api::Controller, Error};
|
||||
|
||||
use super::TextChange;
|
||||
use crate::api::TextChange;
|
||||
|
||||
/// the buffer controller implementation
|
||||
///
|
||||
|
|
|
@ -12,18 +12,3 @@ pub mod controller;
|
|||
pub(crate) mod worker;
|
||||
|
||||
pub use controller::BufferController as Controller;
|
||||
|
||||
|
||||
/// an editor-friendly representation of a text change in a buffer
|
||||
///
|
||||
/// TODO move in proto
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct TextChange {
|
||||
/// range of text change, as byte indexes in buffer
|
||||
pub span: std::ops::Range<usize>,
|
||||
/// content of text change, as string
|
||||
pub content: String,
|
||||
/// content after this text change
|
||||
/// note that this field will probably be dropped, don't rely on it
|
||||
pub after: String
|
||||
}
|
||||
|
|
|
@ -12,8 +12,8 @@ use crate::errors::IgnorableError;
|
|||
use crate::proto::{OperationRequest, RawOp};
|
||||
use crate::proto::buffer_client::BufferClient;
|
||||
use crate::api::controller::ControllerWorker;
|
||||
use crate::api::TextChange;
|
||||
|
||||
use super::TextChange;
|
||||
use super::controller::BufferController;
|
||||
|
||||
|
||||
|
|
|
@ -11,14 +11,16 @@ pub use crate::{
|
|||
pub use crate::ot::OperationSeq as CodempOperationSeq;
|
||||
|
||||
#[cfg(feature = "api")]
|
||||
pub use crate::api::Controller as CodempController;
|
||||
pub use crate::api::{
|
||||
Controller as CodempController,
|
||||
TextChange as CodempTextChange,
|
||||
};
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
pub use crate::{
|
||||
client::Client as CodempClient,
|
||||
cursor::Controller as CodempCursorController,
|
||||
buffer::Controller as CodempBufferController,
|
||||
buffer::TextChange as CodempTextChange,
|
||||
Instance as CodempInstance,
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue