Split remove_text() into remove_text_before() and remove_text_after().
This is useful so that undo knows where to put the cursor.
This commit is contained in:
parent
b31903e838
commit
f56d3f0ad4
|
@ -70,14 +70,29 @@ impl Buffer {
|
|||
}
|
||||
|
||||
|
||||
/// Remove the text between grapheme positions 'pos_a' and 'pos_b'.
|
||||
pub fn remove_text(&mut self, pos_a: usize, pos_b: usize) {
|
||||
let removed_text = self.string_from_range(pos_a, pos_b);
|
||||
/// Remove the text before grapheme position 'pos' of length 'len'.
|
||||
pub fn remove_text_before(&mut self, pos: usize, len: usize) {
|
||||
if pos >= len {
|
||||
let removed_text = self.string_from_range(pos - len, pos);
|
||||
|
||||
self._remove_text(pos_a, pos_b);
|
||||
self._remove_text(pos - len, pos);
|
||||
|
||||
// Push operation to the undo stack
|
||||
self.undo_stack.push(RemoveText(removed_text, pos_a));
|
||||
self.undo_stack.push(RemoveTextBefore(removed_text, pos - len));
|
||||
}
|
||||
else {
|
||||
panic!("Buffer::remove_text_before(): attempt to remove text before beginning of buffer.");
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove the text after grapheme position 'pos' of length 'len'.
|
||||
pub fn remove_text_after(&mut self, pos: usize, len: usize) {
|
||||
let removed_text = self.string_from_range(pos, pos + len);
|
||||
|
||||
self._remove_text(pos, pos + len);
|
||||
|
||||
// Push operation to the undo stack
|
||||
self.undo_stack.push(RemoveTextAfter(removed_text, pos));
|
||||
}
|
||||
|
||||
fn _remove_text(&mut self, pos_a: usize, pos_b: usize) {
|
||||
|
@ -146,8 +161,8 @@ impl Buffer {
|
|||
// TODO: a more efficient implementation that directly
|
||||
// manipulates the node tree.
|
||||
let s = self.string_from_range(pos_a, pos_b);
|
||||
self.remove_text(pos_a, pos_b);
|
||||
self.insert_text(s.as_slice(), pos_to);
|
||||
self._remove_text(pos_a, pos_b);
|
||||
self._insert_text(s.as_slice(), pos_to);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,12 +218,18 @@ impl Buffer {
|
|||
return Some(p);
|
||||
},
|
||||
|
||||
RemoveText(ref s, p) => {
|
||||
RemoveTextBefore(ref s, p) => {
|
||||
let size = grapheme_count(s.as_slice());
|
||||
self._insert_text(s.as_slice(), p);
|
||||
return Some(p+size);
|
||||
},
|
||||
|
||||
RemoveTextAfter(ref s, p) => {
|
||||
let size = grapheme_count(s.as_slice());
|
||||
self._insert_text(s.as_slice(), p);
|
||||
return Some(p);
|
||||
},
|
||||
|
||||
MoveText(pa, pb, pto) => {
|
||||
let size = pb - pa;
|
||||
self._move_text(pto, pto + size, pa);
|
||||
|
@ -236,7 +257,7 @@ impl Buffer {
|
|||
return Some(p+size);
|
||||
},
|
||||
|
||||
RemoveText(ref s, p) => {
|
||||
RemoveTextBefore(ref s, p) | RemoveTextAfter(ref s, p) => {
|
||||
let size = grapheme_count(s.as_slice());
|
||||
self._remove_text(p, p+size);
|
||||
return Some(p);
|
||||
|
@ -782,7 +803,7 @@ mod tests {
|
|||
assert!(buf.grapheme_count() == 29);
|
||||
assert!(buf.text.line_count == 6);
|
||||
|
||||
buf.remove_text(0, 3);
|
||||
buf._remove_text(0, 3);
|
||||
|
||||
let mut iter = buf.grapheme_iter();
|
||||
|
||||
|
@ -826,7 +847,7 @@ mod tests {
|
|||
assert!(buf.grapheme_count() == 29);
|
||||
assert!(buf.text.line_count == 6);
|
||||
|
||||
buf.remove_text(0, 12);
|
||||
buf._remove_text(0, 12);
|
||||
|
||||
let mut iter = buf.grapheme_iter();
|
||||
|
||||
|
@ -861,7 +882,7 @@ mod tests {
|
|||
assert!(buf.grapheme_count() == 29);
|
||||
assert!(buf.text.line_count == 6);
|
||||
|
||||
buf.remove_text(5, 17);
|
||||
buf._remove_text(5, 17);
|
||||
|
||||
let mut iter = buf.grapheme_iter();
|
||||
|
||||
|
@ -896,7 +917,7 @@ mod tests {
|
|||
assert!(buf.grapheme_count() == 29);
|
||||
assert!(buf.text.line_count == 6);
|
||||
|
||||
buf.remove_text(23, 29);
|
||||
buf._remove_text(23, 29);
|
||||
|
||||
let mut iter = buf.grapheme_iter();
|
||||
|
||||
|
@ -937,7 +958,7 @@ mod tests {
|
|||
assert!(buf.grapheme_count() == 29);
|
||||
assert!(buf.text.line_count == 6);
|
||||
|
||||
buf.remove_text(17, 29);
|
||||
buf._remove_text(17, 29);
|
||||
|
||||
let mut iter = buf.grapheme_iter();
|
||||
|
||||
|
@ -972,7 +993,7 @@ mod tests {
|
|||
assert!(buf.grapheme_count() == 12);
|
||||
assert!(buf.text.line_count == 2);
|
||||
|
||||
buf.remove_text(3, 12);
|
||||
buf._remove_text(3, 12);
|
||||
|
||||
let mut iter = buf.grapheme_iter();
|
||||
|
||||
|
@ -993,7 +1014,7 @@ mod tests {
|
|||
assert!(buf.grapheme_count() == 15);
|
||||
assert!(buf.text.line_count == 3);
|
||||
|
||||
buf.remove_text(5, 15);
|
||||
buf._remove_text(5, 15);
|
||||
|
||||
let mut iter = buf.grapheme_iter();
|
||||
|
||||
|
@ -1016,7 +1037,7 @@ mod tests {
|
|||
assert!(buf.grapheme_count() == 12);
|
||||
assert!(buf.text.line_count == 2);
|
||||
|
||||
buf.remove_text(3, 11);
|
||||
buf._remove_text(3, 11);
|
||||
|
||||
let mut iter = buf.grapheme_iter();
|
||||
|
||||
|
@ -1038,7 +1059,7 @@ mod tests {
|
|||
assert!(buf.grapheme_count() == 12);
|
||||
assert!(buf.text.line_count == 2);
|
||||
|
||||
buf.remove_text(8, 12);
|
||||
buf._remove_text(8, 12);
|
||||
|
||||
let mut iter = buf.grapheme_iter();
|
||||
|
||||
|
@ -1064,7 +1085,7 @@ mod tests {
|
|||
assert!(buf.grapheme_count() == 11);
|
||||
assert!(buf.text.line_count == 4);
|
||||
|
||||
buf.remove_text(4, 11);
|
||||
buf._remove_text(4, 11);
|
||||
|
||||
let mut iter = buf.grapheme_iter();
|
||||
|
||||
|
@ -1086,7 +1107,7 @@ mod tests {
|
|||
assert!(buf.grapheme_count() == 10);
|
||||
assert!(buf.text.line_count == 1);
|
||||
|
||||
buf.remove_text(9, 10);
|
||||
buf._remove_text(9, 10);
|
||||
|
||||
let mut iter = buf.grapheme_iter();
|
||||
|
||||
|
|
|
@ -5,7 +5,8 @@ use std::collections::DList;
|
|||
#[derive(Clone)]
|
||||
pub enum Operation {
|
||||
InsertText(String, usize),
|
||||
RemoveText(String, usize),
|
||||
RemoveTextBefore(String, usize),
|
||||
RemoveTextAfter(String, usize),
|
||||
MoveText(usize, usize, usize),
|
||||
CompositeOp(Vec<Operation>),
|
||||
}
|
||||
|
|
|
@ -287,17 +287,15 @@ impl Editor {
|
|||
return;
|
||||
}
|
||||
|
||||
let pos_b = self.cursor.range.0;
|
||||
let pos_a = if pos_b >= grapheme_count {pos_b - grapheme_count} else {0};
|
||||
let tot_g = pos_b - pos_a;
|
||||
let len = min(self.cursor.range.0, grapheme_count);
|
||||
|
||||
// Remove text
|
||||
self.buffer.remove_text(pos_a, pos_b);
|
||||
self.buffer.remove_text_before(self.cursor.range.0, len);
|
||||
self.dirty = true;
|
||||
|
||||
// Move cursor
|
||||
self.cursor.range.0 -= tot_g;
|
||||
self.cursor.range.1 -= tot_g;
|
||||
self.cursor.range.0 -= len;
|
||||
self.cursor.range.1 -= len;
|
||||
self.cursor.update_vis_start(&(self.buffer));
|
||||
|
||||
// Adjust view
|
||||
|
@ -310,11 +308,11 @@ impl Editor {
|
|||
return;
|
||||
}
|
||||
|
||||
let pos_a = self.cursor.range.1;
|
||||
let pos_b = if (pos_a + grapheme_count) <= self.buffer.grapheme_count() {pos_a + grapheme_count} else {self.buffer.grapheme_count()};
|
||||
let max_len = if self.buffer.grapheme_count() > self.cursor.range.1 {self.buffer.grapheme_count() - self.cursor.range.1} else {0};
|
||||
let len = min(max_len, grapheme_count);
|
||||
|
||||
// Remove text
|
||||
self.buffer.remove_text(pos_a, pos_b);
|
||||
self.buffer.remove_text_after(self.cursor.range.1, len);
|
||||
self.dirty = true;
|
||||
|
||||
// Move cursor
|
||||
|
@ -327,7 +325,7 @@ impl Editor {
|
|||
pub fn remove_text_inside_cursor(&mut self) {
|
||||
// If selection, remove text
|
||||
if self.cursor.range.0 < self.cursor.range.1 {
|
||||
self.buffer.remove_text(self.cursor.range.0, self.cursor.range.1);
|
||||
self.buffer.remove_text_before(self.cursor.range.0, self.cursor.range.1 - self.cursor.range.0);
|
||||
self.dirty = true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user