transaction: Also modify map_pos to work with insert|delete order.

pull/8/head
Blaž Hrastnik 3 years ago
parent d5f9622e2e
commit af55ebd002

@ -335,7 +335,7 @@ impl ChangeSet {
Delete(i) | Retain(i) => *i, Delete(i) | Retain(i) => *i,
Insert(_) => 0, Insert(_) => 0,
}; };
let old_end = old_pos + len; let mut old_end = old_pos + len;
match change { match change {
Retain(_) => { Retain(_) => {
@ -345,37 +345,37 @@ impl ChangeSet {
new_pos += len; new_pos += len;
} }
Delete(_) => { Delete(_) => {
// a subsequent ins means a replace, consume it
let ins = if let Some(Insert(s)) = iter.peek() {
iter.next();
s.chars().count()
} else {
0
};
// in range // in range
if old_end > pos { if old_end > pos {
// at point or tracking before return new_pos;
if pos == old_pos || assoc == Assoc::Before {
return new_pos;
} else {
// place to end of delete
return new_pos + ins;
}
} }
new_pos += ins;
} }
Insert(s) => { Insert(s) => {
let ins = s.chars().count(); let ins = s.chars().count();
// at insert point
if old_pos == pos { // a subsequent delete means a replace, consume it
// return position before inserted text if let Some(Delete(len)) = iter.peek() {
if assoc == Assoc::Before { old_end = old_pos + len;
return new_pos; // in range of replaced text
} else { if old_end > pos {
// after text // at point or tracking before
return new_pos + ins; if pos == old_pos || assoc == Assoc::Before {
return new_pos;
} else {
// place to end of insert
return new_pos + ins;
}
}
} else {
// at insert point
if old_pos == pos {
// return position before inserted text
if assoc == Assoc::Before {
return new_pos;
} else {
// after text
return new_pos + ins;
}
} }
} }
@ -602,10 +602,10 @@ mod test {
// stays inbetween replacements // stays inbetween replacements
let cs = ChangeSet { let cs = ChangeSet {
changes: vec![ changes: vec![
Delete(2),
Insert("ab".into()), Insert("ab".into()),
Delete(2), Delete(2),
Insert("cd".into()), Insert("cd".into()),
Delete(2),
], ],
len: 4, len: 4,
}; };

Loading…
Cancel
Save