Fix cursor movement on shortened deletes and refactor

This commit is contained in:
Andras Schmelczer 2025-04-13 23:06:07 +01:00
commit 35bb7f2405
No known key found for this signature in database
GPG key ID: FC8F2C3D3D1A718C
4 changed files with 37 additions and 44 deletions

View file

@ -14,7 +14,7 @@ pub struct CursorPosition {
impl CursorPosition { impl CursorPosition {
#[must_use] #[must_use]
pub fn with_index(self, index: usize) -> Self { pub fn with_index(&self, index: usize) -> Self {
CursorPosition { CursorPosition {
id: self.id, id: self.id,
char_index: index, char_index: index,

View file

@ -253,55 +253,48 @@ where
.flat_map(|(OrderedOperation { order, operation }, side)| { .flat_map(|(OrderedOperation { order, operation }, side)| {
let original_start = operation.start_index() as i64; let original_start = operation.start_index() as i64;
let original_end = operation.end_index(); let original_end = operation.end_index();
let original_length = operation.len() as i64;
let result = match side {
Side::Left => operation.merge_operations_with_context(
&mut right_merge_context,
&mut left_merge_context,
),
Side::Right => operation.merge_operations_with_context(
&mut left_merge_context,
&mut right_merge_context,
),
};
if let Some(ref op @ (Operation::Insert { .. } | Operation::Equal { .. })) = result
{
let shift = op.start_index() as i64 - original_start + op.len() as i64
- original_length;
match side { match side {
Side::Left => { Side::Left => {
let result = operation.merge_operations_with_context( while let Some(cursor) =
&mut right_merge_context,
&mut left_merge_context,
);
if let Some(ref op @ (Operation::Insert { .. } | Operation::Equal { .. })) =
result
{
while let Some(mut cursor) =
left_cursors.next_if(|cursor| cursor.char_index <= original_end + 1) left_cursors.next_if(|cursor| cursor.char_index <= original_end + 1)
{ {
let shift = op.start_index() as i64 - original_start; merged_cursors.push(cursor.with_index(
(op.start_index() as i64).max(cursor.char_index as i64 + shift)
cursor.char_index = (op.start_index() as i64) as usize,
.max(cursor.char_index as i64 + shift) ));
as usize;
merged_cursors.push(cursor);
} }
} }
result
}
Side::Right => { Side::Right => {
let result = operation.merge_operations_with_context( while let Some(cursor) = right_cursors
&mut left_merge_context,
&mut right_merge_context,
);
if let Some(ref op @ (Operation::Insert { .. } | Operation::Equal { .. })) =
result
{
while let Some(mut cursor) = right_cursors
.next_if(|cursor| cursor.char_index <= original_end + 1) .next_if(|cursor| cursor.char_index <= original_end + 1)
{ {
let shift = op.start_index() as i64 - original_start; merged_cursors.push(cursor.with_index(
(op.start_index() as i64).max(cursor.char_index as i64 + shift)
cursor.char_index = (op.start_index() as i64) as usize,
.max(cursor.char_index as i64 + shift) ));
as usize; }
merged_cursors.push(cursor); }
} }
} }
result result
}
}
.map(|operation| OrderedOperation { order, operation }) .map(|operation| OrderedOperation { order, operation })
.into_iter() .into_iter()
}) })

View file

@ -65,7 +65,7 @@ impl ExampleDocument {
for (i, cursor) in text.cursors.iter().enumerate() { for (i, cursor) in text.cursors.iter().enumerate() {
assert!( assert!(
cursor.char_index <= result.len(), // equals in case of insert at the end cursor.char_index <= result.len(), // equals in case of insert at the end
"Cursor index out of bounds: {} > {}", "Cursor index out of bounds: {} > {} when testing for '{result}'",
cursor.char_index, cursor.char_index,
result.len() result.len()
); );

View file

@ -67,7 +67,7 @@ expected: market| placemarket|space
parent: A B C D parent: A B C D
left: A X B D| left: A X B D|
right: A B Y| right: A B Y|
expected: A X B Y|| expected: A X B |Y|
--- ---
parent: Please submit your assignment by Friday parent: Please submit your assignment by Friday