1457 lines
47 KiB
Rust
1457 lines
47 KiB
Rust
#![allow(dead_code)]
|
|
|
|
use std::path::{Path, PathBuf};
|
|
use std::fs::File;
|
|
use std::io;
|
|
use std::io::{BufReader, BufWriter, Read, Write};
|
|
|
|
use ropey;
|
|
use ropey::{Rope, RopeSlice};
|
|
use self::undo_stack::UndoStack;
|
|
use self::undo_stack::Operation::*;
|
|
use string_utils::char_count;
|
|
|
|
mod undo_stack;
|
|
|
|
// =============================================================
|
|
// Buffer
|
|
// =============================================================
|
|
|
|
/// A text buffer
|
|
pub struct Buffer {
|
|
text: Rope,
|
|
file_path: Option<PathBuf>,
|
|
undo_stack: UndoStack,
|
|
}
|
|
|
|
impl Buffer {
|
|
pub fn new() -> Buffer {
|
|
Buffer {
|
|
text: Rope::new(),
|
|
file_path: None,
|
|
undo_stack: UndoStack::new(),
|
|
}
|
|
}
|
|
|
|
pub fn new_from_str(s: &str) -> Buffer {
|
|
Buffer {
|
|
text: Rope::from_str(s),
|
|
file_path: None,
|
|
undo_stack: UndoStack::new(),
|
|
}
|
|
}
|
|
|
|
pub fn new_from_file(path: &Path) -> io::Result<Buffer> {
|
|
let mut f = BufReader::new(try!(File::open(path)));
|
|
let mut string = String::new();
|
|
try!(f.read_to_string(&mut string));
|
|
|
|
let buf = Buffer {
|
|
text: Rope::from_str(&string[..]),
|
|
file_path: Some(path.to_path_buf()),
|
|
undo_stack: UndoStack::new(),
|
|
};
|
|
|
|
return Ok(buf);
|
|
}
|
|
|
|
pub fn save_to_file(&self, path: &Path) -> io::Result<()> {
|
|
let mut f = BufWriter::new(try!(File::create(path)));
|
|
|
|
for c in self.text.chunks() {
|
|
let _ = f.write(c.as_bytes());
|
|
}
|
|
|
|
return Ok(());
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
// Functions for getting information about the buffer.
|
|
// ------------------------------------------------------------------------
|
|
|
|
pub fn char_count(&self) -> usize {
|
|
self.text.len_chars()
|
|
}
|
|
|
|
pub fn grapheme_count(&self) -> usize {
|
|
// TODO: be correct
|
|
self.text.len_chars()
|
|
}
|
|
|
|
pub fn line_count(&self) -> usize {
|
|
self.text.len_lines()
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
// Editing operations
|
|
// ------------------------------------------------------------------------
|
|
|
|
/// Insert 'text' at grapheme position 'pos'.
|
|
pub fn insert_text(&mut self, text: &str, pos: usize) {
|
|
self.text.insert(pos, text);
|
|
|
|
self.undo_stack.push(InsertText(text.to_string(), pos));
|
|
}
|
|
|
|
/// 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.text.slice(pos - len, pos).to_string();
|
|
|
|
self.text.remove(pos - len, pos);
|
|
|
|
// Push operation to the undo stack
|
|
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.text.slice(pos, pos + len).to_string();
|
|
|
|
self.text.remove(pos, pos + len);
|
|
|
|
// Push operation to the undo stack
|
|
self.undo_stack.push(RemoveTextAfter(removed_text, pos));
|
|
}
|
|
|
|
/// 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.text.len_chars() {
|
|
panic!("Buffer::_move_text(): specified text range is beyond end of buffer.");
|
|
}
|
|
// Bounds error
|
|
else if pos_to > (self.text.len_chars() - (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.text.len_chars() {
|
|
return;
|
|
}
|
|
// All other cases
|
|
else {
|
|
// TODO: a more efficient implementation that directly
|
|
// manipulates the node tree.
|
|
let s = self.text.slice(pos_a, pos_b).to_string();
|
|
self.text.remove(pos_a, pos_b);
|
|
self.text.insert(pos_to, &s);
|
|
}
|
|
}
|
|
|
|
/// Removes the lines in line indices [line_a, line_b).
|
|
/// TODO: undo
|
|
pub fn remove_lines(&mut self, line_a: usize, line_b: usize) {
|
|
// Nothing to do
|
|
if line_a == line_b {
|
|
return;
|
|
}
|
|
// Bounds error
|
|
else if line_a > line_b {
|
|
panic!("Buffer::remove_lines(): line_a must be less than or equal to line_b.");
|
|
}
|
|
// Bounds error
|
|
else if line_b > self.line_count() {
|
|
panic!("Buffer::remove_lines(): attempt to remove lines past the last line of text.");
|
|
}
|
|
// All other cases
|
|
else {
|
|
let a = self.text.line_to_char(line_a);
|
|
let b = self.text.line_to_char(line_b);
|
|
|
|
self.text.remove(a, b);
|
|
}
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
// Undo/redo functionality
|
|
// ------------------------------------------------------------------------
|
|
|
|
/// Undoes operations that were pushed to the undo stack, and returns a
|
|
/// cursor position that the cursor should jump to, if any.
|
|
pub fn undo(&mut self) -> Option<usize> {
|
|
if let Some(op) = self.undo_stack.prev() {
|
|
match op {
|
|
InsertText(ref s, p) => {
|
|
let size = char_count(s);
|
|
self.text.remove(p, p + size);
|
|
return Some(p);
|
|
}
|
|
|
|
RemoveTextBefore(ref s, p) => {
|
|
let size = char_count(s);
|
|
self.text.insert(p, s);
|
|
return Some(p + size);
|
|
}
|
|
|
|
RemoveTextAfter(ref s, p) => {
|
|
self.text.insert(p, s);
|
|
return Some(p);
|
|
}
|
|
|
|
MoveText(pa, pb, pto) => {
|
|
let size = pb - pa;
|
|
self._move_text(pto, pto + size, pa);
|
|
return Some(pa);
|
|
}
|
|
|
|
_ => {
|
|
return None;
|
|
}
|
|
}
|
|
}
|
|
|
|
return None;
|
|
}
|
|
|
|
/// Redoes the last undone operation, and returns a cursor position that
|
|
/// the cursor should jump to, if any.
|
|
pub fn redo(&mut self) -> Option<usize> {
|
|
if let Some(op) = self.undo_stack.next() {
|
|
match op {
|
|
InsertText(ref s, p) => {
|
|
let size = char_count(s);
|
|
self.text.insert(p, s);
|
|
return Some(p + size);
|
|
}
|
|
|
|
RemoveTextBefore(ref s, p) | RemoveTextAfter(ref s, p) => {
|
|
let size = char_count(s);
|
|
self.text.remove(p, p + size);
|
|
return Some(p);
|
|
}
|
|
|
|
MoveText(pa, pb, pto) => {
|
|
self._move_text(pa, pb, pto);
|
|
return Some(pa);
|
|
}
|
|
|
|
_ => {
|
|
return None;
|
|
}
|
|
}
|
|
}
|
|
|
|
return None;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
// Position conversions
|
|
// ------------------------------------------------------------------------
|
|
|
|
/// Converts a char index into a line number and char-column
|
|
/// number.
|
|
///
|
|
/// If the index is off the end of the text, returns the line and column
|
|
/// number of the last valid text position.
|
|
pub fn index_to_line_col(&self, pos: usize) -> (usize, usize) {
|
|
if pos < self.text.len_chars() {
|
|
let line = self.text.char_to_line(pos);
|
|
let line_pos = self.text.line_to_char(line);
|
|
|
|
return (line, pos - line_pos);
|
|
} else {
|
|
let line = self.text.len_lines() - 1;
|
|
let line_pos = self.text.line_to_char(line);
|
|
|
|
return (line, pos - line_pos);
|
|
}
|
|
}
|
|
|
|
/// Converts a line number and char-column number into a char
|
|
/// index.
|
|
///
|
|
/// If the column number given is beyond the end of the line, returns the
|
|
/// index of the line's last valid position. If the line number given is
|
|
/// beyond the end of the buffer, returns the index of the buffer's last
|
|
/// valid position.
|
|
pub fn line_col_to_index(&self, pos: (usize, usize)) -> usize {
|
|
if pos.0 < self.text.len_lines() {
|
|
let l_begin_pos = self.text.line_to_char(pos.0);
|
|
return (l_begin_pos + pos.1).min(self.text.len_chars());
|
|
} else {
|
|
return self.text.len_chars();
|
|
}
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
// Text reading functions
|
|
// ------------------------------------------------------------------------
|
|
|
|
pub fn get_grapheme<'a>(&'a self, index: usize) -> &'a str {
|
|
self.text
|
|
.slice(index, index + 1)
|
|
.graphemes()
|
|
.nth(0)
|
|
.unwrap()
|
|
}
|
|
|
|
pub fn get_line<'a>(&'a self, index: usize) -> RopeSlice<'a> {
|
|
self.text.line(index)
|
|
}
|
|
|
|
/// Creates a String from the buffer text in grapheme range [pos_a, posb).
|
|
fn string_from_range(&self, pos_a: usize, pos_b: usize) -> String {
|
|
self.text.slice(pos_a, pos_b).to_string()
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
// Iterator creators
|
|
// ------------------------------------------------------------------------
|
|
|
|
/// Creates an iterator at the first character
|
|
pub fn grapheme_iter<'a>(&'a self) -> ropey::iter::Graphemes<'a> {
|
|
self.text.graphemes()
|
|
}
|
|
|
|
/// Creates an iterator starting at the specified grapheme index.
|
|
/// If the index is past the end of the text, then the iterator will
|
|
/// return None on next().
|
|
pub fn grapheme_iter_at_index<'a>(&'a self, index: usize) -> ropey::iter::Graphemes<'a> {
|
|
let len = self.text.len_chars();
|
|
self.text.slice(index, len).graphemes()
|
|
}
|
|
|
|
pub fn line_iter<'a>(&'a self) -> ropey::iter::Lines<'a> {
|
|
self.text.lines()
|
|
}
|
|
|
|
pub fn line_iter_at_index<'a>(&'a self, line_idx: usize) -> ropey::iter::Lines<'a> {
|
|
let start = self.text.line_to_char(line_idx);
|
|
let len = self.text.len_chars();
|
|
self.text.slice(start, len).lines()
|
|
}
|
|
}
|
|
|
|
// ================================================================
|
|
// TESTS
|
|
// ================================================================
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
#![allow(unused_imports)]
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn insert_text() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hello 世界!", 0);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert!(buf.grapheme_count() == 9);
|
|
assert!(buf.line_count() == 1);
|
|
assert!(Some("H") == iter.next());
|
|
assert!(Some("e") == iter.next());
|
|
assert!(Some("l") == iter.next());
|
|
assert!(Some("l") == iter.next());
|
|
assert!(Some("o") == iter.next());
|
|
assert!(Some(" ") == iter.next());
|
|
assert!(Some("世") == iter.next());
|
|
assert!(Some("界") == iter.next());
|
|
assert!(Some("!") == iter.next());
|
|
assert!(None == iter.next());
|
|
}
|
|
|
|
#[test]
|
|
fn insert_text_with_newlines() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hello\n 世界\r\n!", 0);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert!(buf.grapheme_count() == 11);
|
|
assert!(buf.line_count() == 3);
|
|
assert!(Some("H") == iter.next());
|
|
assert!(Some("e") == iter.next());
|
|
assert!(Some("l") == iter.next());
|
|
assert!(Some("l") == iter.next());
|
|
assert!(Some("o") == iter.next());
|
|
assert!(Some("\n") == iter.next());
|
|
assert!(Some(" ") == iter.next());
|
|
assert!(Some("世") == iter.next());
|
|
assert!(Some("界") == iter.next());
|
|
assert!(Some("\r\n") == iter.next());
|
|
assert!(Some("!") == iter.next());
|
|
assert!(None == iter.next());
|
|
}
|
|
|
|
#[test]
|
|
fn insert_text_in_non_empty_buffer_1() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hello\n 世界\r\n!", 0);
|
|
buf.insert_text("Again ", 0);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert!(buf.grapheme_count() == 17);
|
|
assert!(buf.line_count() == 3);
|
|
assert!(Some("A") == iter.next());
|
|
assert!(Some("g") == iter.next());
|
|
assert!(Some("a") == iter.next());
|
|
assert!(Some("i") == iter.next());
|
|
assert!(Some("n") == iter.next());
|
|
assert!(Some(" ") == iter.next());
|
|
assert!(Some("H") == iter.next());
|
|
assert!(Some("e") == iter.next());
|
|
assert!(Some("l") == iter.next());
|
|
assert!(Some("l") == iter.next());
|
|
assert!(Some("o") == iter.next());
|
|
assert!(Some("\n") == iter.next());
|
|
assert!(Some(" ") == iter.next());
|
|
assert!(Some("世") == iter.next());
|
|
assert!(Some("界") == iter.next());
|
|
assert!(Some("\r\n") == iter.next());
|
|
assert!(Some("!") == iter.next());
|
|
assert!(None == iter.next());
|
|
}
|
|
|
|
#[test]
|
|
fn insert_text_in_non_empty_buffer_2() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hello\n 世界\r\n!", 0);
|
|
buf.insert_text(" again", 5);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert!(buf.grapheme_count() == 17);
|
|
assert!(buf.line_count() == 3);
|
|
assert!(Some("H") == iter.next());
|
|
assert!(Some("e") == iter.next());
|
|
assert!(Some("l") == iter.next());
|
|
assert!(Some("l") == iter.next());
|
|
assert!(Some("o") == iter.next());
|
|
assert!(Some(" ") == iter.next());
|
|
assert!(Some("a") == iter.next());
|
|
assert!(Some("g") == iter.next());
|
|
assert!(Some("a") == iter.next());
|
|
assert!(Some("i") == iter.next());
|
|
assert!(Some("n") == iter.next());
|
|
assert!(Some("\n") == iter.next());
|
|
assert!(Some(" ") == iter.next());
|
|
assert!(Some("世") == iter.next());
|
|
assert!(Some("界") == iter.next());
|
|
assert!(Some("\r\n") == iter.next());
|
|
assert!(Some("!") == iter.next());
|
|
assert!(None == iter.next());
|
|
}
|
|
|
|
#[test]
|
|
fn insert_text_in_non_empty_buffer_3() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hello\n 世界\r\n!", 0);
|
|
buf.insert_text("again", 6);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert!(buf.grapheme_count() == 16);
|
|
assert!(buf.line_count() == 3);
|
|
assert!(Some("H") == iter.next());
|
|
assert!(Some("e") == iter.next());
|
|
assert!(Some("l") == iter.next());
|
|
assert!(Some("l") == iter.next());
|
|
assert!(Some("o") == iter.next());
|
|
assert!(Some("\n") == iter.next());
|
|
assert!(Some("a") == iter.next());
|
|
assert!(Some("g") == iter.next());
|
|
assert!(Some("a") == iter.next());
|
|
assert!(Some("i") == iter.next());
|
|
assert!(Some("n") == iter.next());
|
|
assert!(Some(" ") == iter.next());
|
|
assert!(Some("世") == iter.next());
|
|
assert!(Some("界") == iter.next());
|
|
assert!(Some("\r\n") == iter.next());
|
|
assert!(Some("!") == iter.next());
|
|
assert!(None == iter.next());
|
|
}
|
|
|
|
#[test]
|
|
fn insert_text_in_non_empty_buffer_4() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hello\n 世界\r\n!", 0);
|
|
buf.insert_text("again", 11);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert!(buf.grapheme_count() == 16);
|
|
assert!(buf.line_count() == 3);
|
|
assert!(Some("H") == iter.next());
|
|
assert!(Some("e") == iter.next());
|
|
assert!(Some("l") == iter.next());
|
|
assert!(Some("l") == iter.next());
|
|
assert!(Some("o") == iter.next());
|
|
assert!(Some("\n") == iter.next());
|
|
assert!(Some(" ") == iter.next());
|
|
assert!(Some("世") == iter.next());
|
|
assert!(Some("界") == iter.next());
|
|
assert!(Some("\r\n") == iter.next());
|
|
assert!(Some("!") == iter.next());
|
|
assert!(Some("a") == iter.next());
|
|
assert!(Some("g") == iter.next());
|
|
assert!(Some("a") == iter.next());
|
|
assert!(Some("i") == iter.next());
|
|
assert!(Some("n") == iter.next());
|
|
assert!(None == iter.next());
|
|
}
|
|
|
|
#[test]
|
|
fn insert_text_in_non_empty_buffer_5() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hello\n 世界\r\n!", 0);
|
|
buf.insert_text("again", 2);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert!(buf.grapheme_count() == 16);
|
|
assert!(buf.line_count() == 3);
|
|
assert!(Some("H") == iter.next());
|
|
assert!(Some("e") == iter.next());
|
|
assert!(Some("a") == iter.next());
|
|
assert!(Some("g") == iter.next());
|
|
assert!(Some("a") == iter.next());
|
|
assert!(Some("i") == iter.next());
|
|
assert!(Some("n") == iter.next());
|
|
assert!(Some("l") == iter.next());
|
|
assert!(Some("l") == iter.next());
|
|
assert!(Some("o") == iter.next());
|
|
assert!(Some("\n") == iter.next());
|
|
assert!(Some(" ") == iter.next());
|
|
assert!(Some("世") == iter.next());
|
|
assert!(Some("界") == iter.next());
|
|
assert!(Some("\r\n") == iter.next());
|
|
assert!(Some("!") == iter.next());
|
|
|
|
assert!(None == iter.next());
|
|
}
|
|
|
|
#[test]
|
|
fn insert_text_in_non_empty_buffer_6() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hello\n 世界\r\n!", 0);
|
|
buf.insert_text("again", 8);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert!(buf.grapheme_count() == 16);
|
|
assert!(buf.line_count() == 3);
|
|
assert!(Some("H") == iter.next());
|
|
assert!(Some("e") == iter.next());
|
|
assert!(Some("l") == iter.next());
|
|
assert!(Some("l") == iter.next());
|
|
assert!(Some("o") == iter.next());
|
|
assert!(Some("\n") == iter.next());
|
|
assert!(Some(" ") == iter.next());
|
|
assert!(Some("世") == iter.next());
|
|
assert!(Some("a") == iter.next());
|
|
assert!(Some("g") == iter.next());
|
|
assert!(Some("a") == iter.next());
|
|
assert!(Some("i") == iter.next());
|
|
assert!(Some("n") == iter.next());
|
|
assert!(Some("界") == iter.next());
|
|
assert!(Some("\r\n") == iter.next());
|
|
assert!(Some("!") == iter.next());
|
|
|
|
assert!(None == iter.next());
|
|
}
|
|
|
|
#[test]
|
|
fn insert_text_in_non_empty_buffer_7() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hello\n 世界\r\n!", 0);
|
|
buf.insert_text("\nag\n\nain\n", 2);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert!(buf.grapheme_count() == 20);
|
|
assert!(buf.line_count() == 7);
|
|
assert!(Some("H") == iter.next());
|
|
assert!(Some("e") == iter.next());
|
|
assert!(Some("\n") == iter.next());
|
|
assert!(Some("a") == iter.next());
|
|
assert!(Some("g") == iter.next());
|
|
assert!(Some("\n") == iter.next());
|
|
assert!(Some("\n") == iter.next());
|
|
assert!(Some("a") == iter.next());
|
|
assert!(Some("i") == iter.next());
|
|
assert!(Some("n") == iter.next());
|
|
assert!(Some("\n") == iter.next());
|
|
assert!(Some("l") == iter.next());
|
|
assert!(Some("l") == iter.next());
|
|
assert!(Some("o") == iter.next());
|
|
assert!(Some("\n") == iter.next());
|
|
assert!(Some(" ") == iter.next());
|
|
assert!(Some("世") == iter.next());
|
|
assert!(Some("界") == iter.next());
|
|
assert!(Some("\r\n") == iter.next());
|
|
assert!(Some("!") == iter.next());
|
|
|
|
assert!(None == iter.next());
|
|
}
|
|
|
|
#[test]
|
|
fn remove_text_1() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
|
assert!(buf.grapheme_count() == 29);
|
|
assert!(buf.line_count() == 6);
|
|
|
|
buf._remove_text(0, 3);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert!(buf.grapheme_count() == 26);
|
|
assert!(buf.line_count() == 5);
|
|
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]
|
|
fn remove_text_2() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
|
assert!(buf.grapheme_count() == 29);
|
|
assert!(buf.line_count() == 6);
|
|
|
|
buf._remove_text(0, 12);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert!(buf.grapheme_count() == 17);
|
|
assert!(buf.line_count() == 4);
|
|
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 remove_text_3() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
|
assert!(buf.grapheme_count() == 29);
|
|
assert!(buf.line_count() == 6);
|
|
|
|
buf._remove_text(5, 17);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert!(buf.grapheme_count() == 17);
|
|
assert!(buf.line_count() == 4);
|
|
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("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 remove_text_4() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
|
assert!(buf.grapheme_count() == 29);
|
|
assert!(buf.line_count() == 6);
|
|
|
|
buf._remove_text(23, 29);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert!(buf.grapheme_count() == 23);
|
|
assert!(buf.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!(None == iter.next());
|
|
}
|
|
|
|
#[test]
|
|
fn remove_text_5() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
|
assert!(buf.grapheme_count() == 29);
|
|
assert!(buf.line_count() == 6);
|
|
|
|
buf._remove_text(17, 29);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert!(buf.grapheme_count() == 17);
|
|
assert!(buf.line_count() == 4);
|
|
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!(None == iter.next());
|
|
}
|
|
|
|
#[test]
|
|
fn remove_text_6() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hello\nworld!", 0);
|
|
assert!(buf.grapheme_count() == 12);
|
|
assert!(buf.line_count() == 2);
|
|
|
|
buf._remove_text(3, 12);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert!(buf.grapheme_count() == 3);
|
|
assert!(buf.line_count() == 1);
|
|
assert!(Some("H") == iter.next());
|
|
assert!(Some("e") == iter.next());
|
|
assert!(Some("l") == iter.next());
|
|
assert!(None == iter.next());
|
|
}
|
|
|
|
#[test]
|
|
fn remove_text_7() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hi\nthere\nworld!", 0);
|
|
assert!(buf.grapheme_count() == 15);
|
|
assert!(buf.line_count() == 3);
|
|
|
|
buf._remove_text(5, 15);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert!(buf.grapheme_count() == 5);
|
|
assert!(buf.line_count() == 2);
|
|
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!(None == iter.next());
|
|
}
|
|
|
|
#[test]
|
|
fn remove_text_8() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hello\nworld!", 0);
|
|
assert!(buf.grapheme_count() == 12);
|
|
assert!(buf.line_count() == 2);
|
|
|
|
buf._remove_text(3, 11);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert!(buf.grapheme_count() == 4);
|
|
assert!(buf.line_count() == 1);
|
|
assert!(Some("H") == iter.next());
|
|
assert!(Some("e") == iter.next());
|
|
assert!(Some("l") == iter.next());
|
|
assert!(Some("!") == iter.next());
|
|
assert!(None == iter.next());
|
|
}
|
|
|
|
#[test]
|
|
fn remove_text_9() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hello\nworld!", 0);
|
|
assert!(buf.grapheme_count() == 12);
|
|
assert!(buf.line_count() == 2);
|
|
|
|
buf._remove_text(8, 12);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert!(buf.grapheme_count() == 8);
|
|
assert!(buf.line_count() == 2);
|
|
assert!(Some("H") == iter.next());
|
|
assert!(Some("e") == iter.next());
|
|
assert!(Some("l") == iter.next());
|
|
assert!(Some("l") == iter.next());
|
|
assert!(Some("o") == iter.next());
|
|
assert!(Some("\n") == iter.next());
|
|
assert!(Some("w") == iter.next());
|
|
assert!(Some("o") == iter.next());
|
|
assert!(None == iter.next());
|
|
}
|
|
|
|
#[test]
|
|
fn remove_text_10() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("12\n34\n56\n78", 0);
|
|
assert!(buf.grapheme_count() == 11);
|
|
assert!(buf.line_count() == 4);
|
|
|
|
buf._remove_text(4, 11);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert!(buf.grapheme_count() == 4);
|
|
assert!(buf.line_count() == 2);
|
|
assert!(Some("1") == iter.next());
|
|
assert!(Some("2") == iter.next());
|
|
assert!(Some("\n") == iter.next());
|
|
assert!(Some("3") == iter.next());
|
|
assert!(None == iter.next());
|
|
}
|
|
|
|
#[test]
|
|
fn remove_text_11() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("1234567890", 0);
|
|
assert!(buf.grapheme_count() == 10);
|
|
assert!(buf.line_count() == 1);
|
|
|
|
buf._remove_text(9, 10);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert!(buf.grapheme_count() == 9);
|
|
assert!(buf.line_count() == 1);
|
|
assert!(Some("1") == iter.next());
|
|
assert!(Some("2") == iter.next());
|
|
assert!(Some("3") == iter.next());
|
|
assert!(Some("4") == iter.next());
|
|
assert!(Some("5") == iter.next());
|
|
assert!(Some("6") == iter.next());
|
|
assert!(Some("7") == iter.next());
|
|
assert!(Some("8") == iter.next());
|
|
assert!(Some("9") == iter.next());
|
|
assert!(None == iter.next());
|
|
}
|
|
|
|
#[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.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.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.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.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.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]
|
|
fn remove_lines_1() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
|
assert!(buf.grapheme_count() == 29);
|
|
assert!(buf.line_count() == 6);
|
|
|
|
buf.remove_lines(0, 3);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert!(buf.grapheme_count() == 13);
|
|
assert!(buf.line_count() == 3);
|
|
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 remove_lines_2() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
|
assert!(buf.grapheme_count() == 29);
|
|
assert!(buf.line_count() == 6);
|
|
|
|
buf.remove_lines(1, 4);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert!(buf.grapheme_count() == 13);
|
|
assert!(buf.line_count() == 3);
|
|
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("\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 remove_lines_3() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
|
assert_eq!(buf.grapheme_count(), 29);
|
|
assert_eq!(buf.line_count(), 6);
|
|
|
|
buf.remove_lines(3, 6);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert_eq!(buf.grapheme_count(), 15);
|
|
assert_eq!(buf.line_count(), 3);
|
|
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!(None == iter.next());
|
|
}
|
|
|
|
#[test]
|
|
fn remove_lines_4() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\n", 0);
|
|
assert_eq!(buf.grapheme_count(), 23);
|
|
assert_eq!(buf.line_count(), 6);
|
|
|
|
buf.remove_lines(3, 6);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert_eq!(buf.grapheme_count(), 15);
|
|
assert_eq!(buf.line_count(), 3);
|
|
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!(None == iter.next());
|
|
}
|
|
|
|
#[test]
|
|
fn remove_lines_5() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
|
assert_eq!(buf.grapheme_count(), 29);
|
|
assert_eq!(buf.line_count(), 6);
|
|
|
|
buf.remove_lines(0, 6);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert_eq!(buf.grapheme_count(), 0);
|
|
assert_eq!(buf.line_count(), 1);
|
|
assert!(None == iter.next());
|
|
}
|
|
|
|
#[test]
|
|
fn remove_lines_6() {
|
|
let mut buf = Buffer::new();
|
|
|
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\n", 0);
|
|
assert_eq!(buf.grapheme_count(), 23);
|
|
assert_eq!(buf.line_count(), 6);
|
|
|
|
buf.remove_lines(0, 6);
|
|
|
|
let mut iter = buf.grapheme_iter();
|
|
|
|
assert_eq!(buf.grapheme_count(), 0);
|
|
assert_eq!(buf.line_count(), 1);
|
|
assert!(None == iter.next());
|
|
}
|
|
|
|
#[test]
|
|
fn line_col_to_index_1() {
|
|
let mut buf = Buffer::new();
|
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
|
|
|
let pos = buf.line_col_to_index((2, 3));
|
|
|
|
assert!(pos == 12);
|
|
}
|
|
|
|
#[test]
|
|
fn line_col_to_index_2() {
|
|
let mut buf = Buffer::new();
|
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
|
|
|
let pos = buf.line_col_to_index((2, 10));
|
|
|
|
assert!(pos == 15);
|
|
}
|
|
|
|
#[test]
|
|
fn line_col_to_index_3() {
|
|
let mut buf = Buffer::new();
|
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
|
|
|
let pos = buf.line_col_to_index((10, 2));
|
|
|
|
assert!(pos == 29);
|
|
}
|
|
|
|
#[test]
|
|
fn line_col_to_index_4() {
|
|
let mut buf = Buffer::new();
|
|
buf.insert_text("Hello\nworld!\n", 0);
|
|
|
|
assert_eq!(buf.line_col_to_index((0, 0)), 0);
|
|
assert_eq!(buf.line_col_to_index((0, 5)), 5);
|
|
assert_eq!(buf.line_col_to_index((0, 6)), 5);
|
|
|
|
assert_eq!(buf.line_col_to_index((1, 0)), 6);
|
|
assert_eq!(buf.line_col_to_index((1, 6)), 12);
|
|
assert_eq!(buf.line_col_to_index((1, 7)), 12);
|
|
|
|
assert_eq!(buf.line_col_to_index((2, 0)), 13);
|
|
assert_eq!(buf.line_col_to_index((2, 1)), 13);
|
|
}
|
|
|
|
#[test]
|
|
fn index_to_line_col_1() {
|
|
let mut buf = Buffer::new();
|
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
|
|
|
let pos = buf.index_to_line_col(5);
|
|
|
|
assert!(pos == (1, 2));
|
|
}
|
|
|
|
#[test]
|
|
fn index_to_line_col_2() {
|
|
let mut buf = Buffer::new();
|
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
|
|
|
let pos = buf.index_to_line_col(50);
|
|
|
|
assert!(pos == (5, 6));
|
|
}
|
|
|
|
#[test]
|
|
fn index_to_line_col_3() {
|
|
let mut buf = Buffer::new();
|
|
buf.insert_text("Hello\nworld!\n", 0);
|
|
|
|
assert_eq!(buf.index_to_line_col(0), (0, 0));
|
|
assert_eq!(buf.index_to_line_col(5), (0, 5));
|
|
assert_eq!(buf.index_to_line_col(6), (1, 0));
|
|
assert_eq!(buf.index_to_line_col(12), (1, 6));
|
|
assert_eq!(buf.index_to_line_col(13), (2, 0));
|
|
assert_eq!(buf.index_to_line_col(14), (2, 0));
|
|
}
|
|
|
|
#[test]
|
|
fn string_from_range_1() {
|
|
let mut buf = Buffer::new();
|
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
|
|
|
let s = buf.string_from_range(1, 12);
|
|
|
|
assert!(&s[..] == "i\nthere\npeo");
|
|
}
|
|
|
|
#[test]
|
|
fn string_from_range_2() {
|
|
let mut buf = Buffer::new();
|
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
|
|
|
let s = buf.string_from_range(0, 29);
|
|
|
|
assert!(&s[..] == "Hi\nthere\npeople\nof\nthe\nworld!");
|
|
}
|
|
|
|
#[test]
|
|
fn grapheme_iter_at_index_1() {
|
|
let mut buf = Buffer::new();
|
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
|
|
|
let mut iter = buf.grapheme_iter_at_index(16);
|
|
|
|
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 grapheme_iter_at_index_2() {
|
|
let mut buf = Buffer::new();
|
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
|
|
|
let mut iter = buf.grapheme_iter_at_index(29);
|
|
|
|
assert!(None == iter.next());
|
|
}
|
|
|
|
}
|