use buffer::operation::Operation;
use buffer::{Buffer, Position, Range};
use std::clone::Clone;
#[derive(Clone)]
pub struct Delete {
content: Option<String>,
range: Range,
}
impl Operation for Delete {
fn run(&mut self, buffer: &mut Buffer) {
self.content = buffer.data.borrow().read(&self.range);
buffer.data.borrow_mut().delete(&self.range);
buffer.clear_caches()
}
fn reverse(&mut self, buffer: &mut Buffer) {
match self.content {
Some(ref content) => {
buffer.data.borrow_mut().insert(content, &self.range.start());
buffer.clear_caches()
},
None => (),
}
}
fn clone_operation(&self) -> Box<Operation> {
Box::new(self.clone())
}
}
impl Delete {
pub fn new(range: Range) -> Delete {
Delete{ content: None, range: range }
}
}
impl Buffer {
pub fn delete(&mut self) {
let mut end = Position{ line: self.cursor.line, offset: self.cursor.offset + 1 };
if !self.data.borrow().in_bounds(&end) {
end.line += 1;
end.offset = 0;
}
let start = self.cursor.position.clone();
self.delete_range(Range::new(start, end));
}
pub fn delete_range(&mut self, range: Range) {
let mut op = Delete::new(range);
op.run(self);
match self.operation_group {
Some(ref mut group) => group.add(Box::new(op)),
None => self.history.add(Box::new(op)),
};
self.clear_caches();
}
}
#[cfg(test)]
mod tests {
use super::Delete;
use buffer::{Buffer, Position, Range};
use buffer::operation::Operation;
#[test]
fn run_and_reverse_remove_and_add_content_without_newlines_at_cursor_position() {
let mut buffer = Buffer::new();
buffer.insert(&"something else");
let start = Position{ line: 0, offset: 9 };
let end = Position{ line: 0, offset: 14 };
let delete_range = Range::new(start, end);
let mut delete_operation = Delete::new(delete_range);
delete_operation.run(&mut buffer);
assert_eq!(buffer.data(), "something");
delete_operation.reverse(&mut buffer);
assert_eq!(buffer.data(), "something else");
}
#[test]
fn run_and_reverse_remove_and_add_content_with_newlines_at_cursor_position() {
let mut buffer = Buffer::new();
buffer.insert(&"\n something\n else\n entirely");
let start = Position{ line: 1, offset: 10 };
let end = Position{ line: 3, offset: 9 };
let delete_range = Range::new(start, end);
let mut delete_operation = Delete::new(delete_range);
delete_operation.run(&mut buffer);
assert_eq!(buffer.data(), "\n something");
delete_operation.reverse(&mut buffer);
assert_eq!(buffer.data(), "\n something\n else\n entirely");
}
}