on master help sign in
transaction: Also modify map_pos to work with insert|delete order.
af55ebdBlaž Hrastnik
helix-core/src/transaction.rs+27−27
@@ -335,7 +335,7 @@ impl ChangeSet {
335 Delete(i) | Retain(i) => *i,
335 Delete(i) | Retain(i) => *i,
336 Insert(_) => 0,
336 Insert(_) => 0,
337 };
337 };
338− let old_end = old_pos + len;
338+ let mut old_end = old_pos + len;
339
339
340 match change {
340 match change {
341 Retain(_) => {
341 Retain(_) => {
@@ -345,37 +345,37 @@ impl ChangeSet {
345 new_pos += len;
345 new_pos += len;
346 }
346 }
347 Delete(_) => {
347 Delete(_) => {
348− // a subsequent ins means a replace, consume it
349− let ins = if let Some(Insert(s)) = iter.peek() {
350− iter.next();
351− s.chars().count()
352− } else {
353− 0
354− };
355−
356 // in range
348 // in range
357 if old_end > pos {
349 if old_end > pos {
358− // at point or tracking before
359− if pos == old_pos || assoc == Assoc::Before {
360− return new_pos;
350+ return new_pos;
361− } else {
362− // place to end of delete
363− return new_pos + ins;
364− }
365 }
351 }
366−
367− new_pos += ins;
368 }
352 }
369 Insert(s) => {
353 Insert(s) => {
370 let ins = s.chars().count();
354 let ins = s.chars().count();
371− // at insert point
355+
356+ // a subsequent delete means a replace, consume it
357+ if let Some(Delete(len)) = iter.peek() {
358+ old_end = old_pos + len;
359+ // in range of replaced text
360+ if old_end > pos {
361+ // at point or tracking before
362+ if pos == old_pos || assoc == Assoc::Before {
363+ return new_pos;
364+ } else {
365+ // place to end of insert
366+ return new_pos + ins;
367+ }
368+ }
369+ } else {
370+ // at insert point
372− if old_pos == pos {
371+ if old_pos == pos {
373− // return position before inserted text
372+ // return position before inserted text
374− if assoc == Assoc::Before {
373+ if assoc == Assoc::Before {
375− return new_pos;
374+ return new_pos;
376− } else {
375+ } else {
377− // after text
376+ // after text
378− return new_pos + ins;
377+ return new_pos + ins;
378+ }
379 }
379 }
380 }
380 }
381
381
@@ -602,10 +602,10 @@ mod test {
602 // stays inbetween replacements
602 // stays inbetween replacements
603 let cs = ChangeSet {
603 let cs = ChangeSet {
604 changes: vec![
604 changes: vec![
605− Delete(2),
606 Insert("ab".into()),
605 Insert("ab".into()),
607 Delete(2),
606 Delete(2),
608 Insert("cd".into()),
607 Insert("cd".into()),
608+ Delete(2),
609 ],
609 ],
610 len: 4,
610 len: 4,
611 };
611 };