From d018d417e8c6edd7f58d1a6823f7ce83038ba95e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= Date: Mon, 9 Dec 2024 01:01:23 +0100 Subject: [PATCH] continue iterating.. - figured out how to get the individual "splice" and "delete" ops for the changes coming in from network (ie. Patches), we can now apply those to the textView - still lots of FIXMEs --- src/application.rs | 74 ++++++++++++++++++++++++++++++++-------------- src/window.rs | 9 ++++-- 2 files changed, 57 insertions(+), 26 deletions(-) diff --git a/src/application.rs b/src/application.rs index 0daf0df..9688e4f 100644 --- a/src/application.rs +++ b/src/application.rs @@ -29,6 +29,7 @@ use gettextrs::gettext; use gtk::{gio, glib}; use tokio::sync::{mpsc, oneshot}; use automerge::ScalarValue; +use automerge::PatchAction; use crate::config::VERSION; use crate::glib::closure_local; @@ -54,20 +55,10 @@ mod imp { fn update_text(&self, position: i32, del: i32, text: &str) { let mut doc = self.automerge.borrow_mut(); - let current_text = match doc.get(automerge::ROOT, "root").expect("root exists") { + /*let current_text = match doc.get(automerge::ROOT, "root").expect("root exists") { Some((_, root)) => doc.text(&root).unwrap(), None => "".to_owned(), - }; - - println!("CMP '{}' == '{}'", current_text, text); - - if text == "" { - return; - } - - if text == current_text { - return; - } + };*/ let root = match doc.get(automerge::ROOT, "root").expect("root exists") { Some(root) => root.1, @@ -77,15 +68,30 @@ mod imp { }; println!("root = {}", root); -// doc.update_text(&root, text).unwrap(); - doc.splice( - &root, - position as usize, - del as isize, - text - .chars() - .map(|character| ScalarValue::Str(character.to_string().into())) - ); + doc.splice_text(&root,position as usize, del as isize, text).unwrap(); + + // move the diff pointer forward to current position + //doc.update_diff_cursor(); + let patches = doc.diff_incremental(); + for patch in patches.iter() { + match &patch.action { + PatchAction::SpliceText { index, value, marks } => { + }, + PatchAction::DeleteSeq { index, length } => { + }, + PatchAction::PutMap { key: _, value: _, conflict: _ } => {}, + PatchAction::PutSeq { index: _, value: _, conflict: _ } => {}, + PatchAction::Insert { index: _, values: _ } => {}, + PatchAction::Increment { prop: _, value: _ } => {}, + PatchAction::Conflict { prop: _ } => {}, + PatchAction::DeleteMap { key: _ } => {}, + PatchAction::Mark { marks: _ } => {}, + } + // there's probably either PatchAction::SpliceText or PatchAction::DeleteSeq + // in here, and those we can now apply using splice_text_view + println!("{}", patch.action); + //w.splice_text_view(pos, del, &text); + } { let bytes = doc.save_incremental(); @@ -164,12 +170,34 @@ mod imp { .expect("inserting map at root"), }; println!("root = {}", root); + + // get the latest changes + let patches = doc_local.diff_incremental(); + for patch in patches.iter() { + println!("PATCH: {}", patch.action); + match &patch.action { + PatchAction::SpliceText { index, value, marks: _ } => { + // FIXME: actually pass the value here instead of an empty string + w.splice_text_view(*index as i32, 0, ""); + }, + PatchAction::DeleteSeq { index, length } => { + w.splice_text_view(*index as i32, *length as i32, ""); + }, + PatchAction::PutMap { key: _, value: _, conflict: _ } => {}, + PatchAction::PutSeq { index: _, value: _, conflict: _ } => {}, + PatchAction::Insert { index: _, values: _ } => {}, + PatchAction::Increment { prop: _, value: _ } => {}, + PatchAction::Conflict { prop: _ } => {}, + PatchAction::DeleteMap { key: _ } => {}, + PatchAction::Mark { marks: _ } => {}, + } + } + doc_local.text(&root).unwrap() }; dbg!(&text); - println!("SET_TEXT = '{}'", text); - w.splice_text_view(0, 0, &text); + println!("new final text = '{}'", text); } }); diff --git a/src/window.rs b/src/window.rs index 019c03c..b8b7c46 100644 --- a/src/window.rs +++ b/src/window.rs @@ -98,11 +98,14 @@ impl AardvarkWindow { let window = self.imp(); let buffer = window.text_view.buffer(); - let s = buffer.text(&buffer.start_iter(), &buffer.end_iter(), false); - if text == s { println!("bailing out on superfluous set_text"); return; } - //buffer.set_text(text); + if del != 0 { + // FIXME: delete stuff from buffer here + return; + } let mut pos_iter = buffer.iter_at_offset(pos); + // FIXME: need to tell AardvarkTextBuffer to not emit ::text-change signal during this insert op + // to avoid a loop buffer.insert(&mut pos_iter, text); }