Stub and unit tests for a move_text implementation.
This commit is contained in:
parent
f8cf8e620b
commit
8a51a796ce
|
@ -87,11 +87,11 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
// Bounds error
|
// Bounds error
|
||||||
else if pos_a > pos_b {
|
else if pos_a > pos_b {
|
||||||
panic!("Buffer::remove_text(): pos_a must be less than or equal to pos_b.");
|
panic!("Buffer::_remove_text(): pos_a must be less than or equal to pos_b.");
|
||||||
}
|
}
|
||||||
// Bounds error
|
// Bounds error
|
||||||
else if pos_b > self.grapheme_count() {
|
else if pos_b > self.grapheme_count() {
|
||||||
panic!("Buffer::remove_text(): attempt to remove text past the end of buffer.");
|
panic!("Buffer::_remove_text(): attempt to remove text past the end of buffer.");
|
||||||
}
|
}
|
||||||
// Complete removal of all text
|
// Complete removal of all text
|
||||||
else if pos_a == 0 && pos_b == self.text.grapheme_count {
|
else if pos_a == 0 && pos_b == self.text.grapheme_count {
|
||||||
|
@ -101,13 +101,54 @@ impl Buffer {
|
||||||
// All other cases
|
// All other cases
|
||||||
else {
|
else {
|
||||||
if self.text.remove_text_recursive(pos_a, pos_b, true) {
|
if self.text.remove_text_recursive(pos_a, pos_b, true) {
|
||||||
panic!("Buffer::remove_text(): dangling left side remains. This should never happen!");
|
panic!("Buffer::_remove_text(): dangling left side remains. This should never happen!");
|
||||||
}
|
}
|
||||||
self.text.set_last_line_ending_recursive();
|
self.text.set_last_line_ending_recursive();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Moves the text in [pos_a, pos_b) to begin at index pos_to.
|
||||||
|
///
|
||||||
|
/// Note that pos_to is the desired index that the text will start at
|
||||||
|
/// _after_ the operation, not the index before the operation. This is a
|
||||||
|
/// subtle but important distinction.
|
||||||
|
pub fn move_text(&mut self, pos_a: usize, pos_b: usize, pos_to: usize) {
|
||||||
|
self._move_text(pos_a, pos_b, pos_to);
|
||||||
|
|
||||||
|
// Push operation to the undo stack
|
||||||
|
self.undo_stack.push(MoveText(pos_a, pos_b, pos_to));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _move_text(&mut self, pos_a: usize, pos_b: usize, pos_to: usize) {
|
||||||
|
// Nothing to do
|
||||||
|
if pos_a == pos_b || pos_a == pos_to {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Bounds error
|
||||||
|
else if pos_a > pos_b {
|
||||||
|
panic!("Buffer::_move_text(): pos_a must be less than or equal to pos_b.");
|
||||||
|
}
|
||||||
|
// Bounds error
|
||||||
|
else if pos_b > self.grapheme_count() {
|
||||||
|
panic!("Buffer::_move_text(): specified text range is beyond end of buffer.");
|
||||||
|
}
|
||||||
|
// Bounds error
|
||||||
|
else if pos_to > (self.grapheme_count() - (pos_b - pos_a)) {
|
||||||
|
panic!("Buffer::_move_text(): specified text destination is beyond end of buffer.");
|
||||||
|
}
|
||||||
|
// Nothing to do, because entire text specified
|
||||||
|
else if pos_a == 0 && pos_b == self.grapheme_count() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// All other cases
|
||||||
|
else {
|
||||||
|
// TODO
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Removes the lines in line indices [line_a, line_b).
|
/// Removes the lines in line indices [line_a, line_b).
|
||||||
pub fn remove_lines(&mut self, line_a: usize, line_b: usize) {
|
pub fn remove_lines(&mut self, line_a: usize, line_b: usize) {
|
||||||
// Nothing to do
|
// Nothing to do
|
||||||
|
@ -165,6 +206,12 @@ impl Buffer {
|
||||||
return Some(p+size);
|
return Some(p+size);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
MoveText(pa, pb, pto) => {
|
||||||
|
let size = pb - pa;
|
||||||
|
self._move_text(pto, pto + size, pa);
|
||||||
|
return Some(pa);
|
||||||
|
},
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
return None;
|
return None;
|
||||||
},
|
},
|
||||||
|
@ -192,6 +239,11 @@ impl Buffer {
|
||||||
return Some(p);
|
return Some(p);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
MoveText(pa, pb, pto) => {
|
||||||
|
self._move_text(pa, pb, pto);
|
||||||
|
return Some(pa);
|
||||||
|
},
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
return None;
|
return None;
|
||||||
},
|
},
|
||||||
|
@ -1050,6 +1102,231 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn move_text_1() {
|
||||||
|
let mut buf = Buffer::new();
|
||||||
|
|
||||||
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
||||||
|
|
||||||
|
buf.move_text(0, 3, 2);
|
||||||
|
|
||||||
|
let mut iter = buf.grapheme_iter();
|
||||||
|
|
||||||
|
assert!(buf.grapheme_count() == 29);
|
||||||
|
assert!(buf.text.line_count == 6);
|
||||||
|
assert!(Some("t") == iter.next());
|
||||||
|
assert!(Some("h") == iter.next());
|
||||||
|
assert!(Some("H") == iter.next());
|
||||||
|
assert!(Some("i") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("r") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("p") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("o") == iter.next());
|
||||||
|
assert!(Some("p") == iter.next());
|
||||||
|
assert!(Some("l") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("o") == iter.next());
|
||||||
|
assert!(Some("f") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("t") == iter.next());
|
||||||
|
assert!(Some("h") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("w") == iter.next());
|
||||||
|
assert!(Some("o") == iter.next());
|
||||||
|
assert!(Some("r") == iter.next());
|
||||||
|
assert!(Some("l") == iter.next());
|
||||||
|
assert!(Some("d") == iter.next());
|
||||||
|
assert!(Some("!") == iter.next());
|
||||||
|
assert!(None == iter.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn move_text_2() {
|
||||||
|
let mut buf = Buffer::new();
|
||||||
|
|
||||||
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
||||||
|
|
||||||
|
buf.move_text(3, 8, 6);
|
||||||
|
|
||||||
|
let mut iter = buf.grapheme_iter();
|
||||||
|
|
||||||
|
assert!(buf.grapheme_count() == 29);
|
||||||
|
assert!(buf.text.line_count == 6);
|
||||||
|
assert!(Some("H") == iter.next());
|
||||||
|
assert!(Some("i") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("p") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("t") == iter.next());
|
||||||
|
assert!(Some("h") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("r") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("o") == iter.next());
|
||||||
|
assert!(Some("p") == iter.next());
|
||||||
|
assert!(Some("l") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("o") == iter.next());
|
||||||
|
assert!(Some("f") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("t") == iter.next());
|
||||||
|
assert!(Some("h") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("w") == iter.next());
|
||||||
|
assert!(Some("o") == iter.next());
|
||||||
|
assert!(Some("r") == iter.next());
|
||||||
|
assert!(Some("l") == iter.next());
|
||||||
|
assert!(Some("d") == iter.next());
|
||||||
|
assert!(Some("!") == iter.next());
|
||||||
|
assert!(None == iter.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn move_text_3() {
|
||||||
|
let mut buf = Buffer::new();
|
||||||
|
|
||||||
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
||||||
|
|
||||||
|
buf.move_text(12, 17, 6);
|
||||||
|
|
||||||
|
let mut iter = buf.grapheme_iter();
|
||||||
|
|
||||||
|
assert!(buf.grapheme_count() == 29);
|
||||||
|
assert!(buf.text.line_count == 6);
|
||||||
|
assert!(Some("H") == iter.next());
|
||||||
|
assert!(Some("i") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("t") == iter.next());
|
||||||
|
assert!(Some("h") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("p") == iter.next());
|
||||||
|
assert!(Some("l") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("o") == iter.next());
|
||||||
|
assert!(Some("r") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("p") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("o") == iter.next());
|
||||||
|
assert!(Some("f") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("t") == iter.next());
|
||||||
|
assert!(Some("h") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("w") == iter.next());
|
||||||
|
assert!(Some("o") == iter.next());
|
||||||
|
assert!(Some("r") == iter.next());
|
||||||
|
assert!(Some("l") == iter.next());
|
||||||
|
assert!(Some("d") == iter.next());
|
||||||
|
assert!(Some("!") == iter.next());
|
||||||
|
assert!(None == iter.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn move_text_4() {
|
||||||
|
let mut buf = Buffer::new();
|
||||||
|
|
||||||
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
||||||
|
|
||||||
|
buf.move_text(23, 29, 20);
|
||||||
|
|
||||||
|
let mut iter = buf.grapheme_iter();
|
||||||
|
|
||||||
|
assert!(buf.grapheme_count() == 29);
|
||||||
|
assert!(buf.text.line_count == 6);
|
||||||
|
assert!(Some("H") == iter.next());
|
||||||
|
assert!(Some("i") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("t") == iter.next());
|
||||||
|
assert!(Some("h") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("r") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("p") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("o") == iter.next());
|
||||||
|
assert!(Some("p") == iter.next());
|
||||||
|
assert!(Some("l") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("o") == iter.next());
|
||||||
|
assert!(Some("f") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("t") == iter.next());
|
||||||
|
assert!(Some("w") == iter.next());
|
||||||
|
assert!(Some("o") == iter.next());
|
||||||
|
assert!(Some("r") == iter.next());
|
||||||
|
assert!(Some("l") == iter.next());
|
||||||
|
assert!(Some("d") == iter.next());
|
||||||
|
assert!(Some("!") == iter.next());
|
||||||
|
assert!(Some("h") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(None == iter.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn move_text_5() {
|
||||||
|
let mut buf = Buffer::new();
|
||||||
|
|
||||||
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
||||||
|
|
||||||
|
buf.move_text(0, 29, 0);
|
||||||
|
|
||||||
|
let mut iter = buf.grapheme_iter();
|
||||||
|
|
||||||
|
assert!(buf.grapheme_count() == 29);
|
||||||
|
assert!(buf.text.line_count == 6);
|
||||||
|
assert!(Some("H") == iter.next());
|
||||||
|
assert!(Some("i") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("t") == iter.next());
|
||||||
|
assert!(Some("h") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("r") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("p") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("o") == iter.next());
|
||||||
|
assert!(Some("p") == iter.next());
|
||||||
|
assert!(Some("l") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("o") == iter.next());
|
||||||
|
assert!(Some("f") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("t") == iter.next());
|
||||||
|
assert!(Some("h") == iter.next());
|
||||||
|
assert!(Some("e") == iter.next());
|
||||||
|
assert!(Some("\n") == iter.next());
|
||||||
|
assert!(Some("w") == iter.next());
|
||||||
|
assert!(Some("o") == iter.next());
|
||||||
|
assert!(Some("r") == iter.next());
|
||||||
|
assert!(Some("l") == iter.next());
|
||||||
|
assert!(Some("d") == iter.next());
|
||||||
|
assert!(Some("!") == iter.next());
|
||||||
|
assert!(None == iter.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn remove_lines_1() {
|
fn remove_lines_1() {
|
||||||
let mut buf = Buffer::new();
|
let mut buf = Buffer::new();
|
||||||
|
|
|
@ -27,7 +27,7 @@ impl Cursor {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_vis_start(&mut self, buf: &Buffer) {
|
pub fn update_vis_start(&mut self, buf: &Buffer) {
|
||||||
let (v, h) = buf.index_to_v2d(self.range.0);
|
let (_, h) = buf.index_to_v2d(self.range.0);
|
||||||
self.vis_start = h;
|
self.vis_start = h;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,7 +248,6 @@ impl Editor {
|
||||||
pub fn insert_tab_at_cursor(&mut self) {
|
pub fn insert_tab_at_cursor(&mut self) {
|
||||||
if self.soft_tabs {
|
if self.soft_tabs {
|
||||||
// Figure out how many spaces to insert
|
// Figure out how many spaces to insert
|
||||||
let (v, h) = self.buffer.index_to_line_col(self.cursor.range.0);
|
|
||||||
let (_, vis_pos) = self.buffer.index_to_v2d(self.cursor.range.0);
|
let (_, vis_pos) = self.buffer.index_to_v2d(self.cursor.range.0);
|
||||||
let next_tab_stop = ((vis_pos / self.buffer.tab_width) + 1) * self.buffer.tab_width;
|
let next_tab_stop = ((vis_pos / self.buffer.tab_width) + 1) * self.buffer.tab_width;
|
||||||
let space_count = min(next_tab_stop - vis_pos, 8);
|
let space_count = min(next_tab_stop - vis_pos, 8);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user