Got grapheme iterators and 1d/2d position translation working.
This commit is contained in:
parent
95d6d3fd3e
commit
71913eed31
|
@ -129,57 +129,18 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// /// Creates an iterator starting at the specified grapheme index.
|
/// Creates an iterator starting at the specified grapheme index.
|
||||||
// /// If the index is past the end of the text, then the iterator will
|
/// If the index is past the end of the text, then the iterator will
|
||||||
// /// return None on next().
|
/// return None on next().
|
||||||
// pub fn grapheme_iter_at_index<'a>(&'a self, index: uint) -> BufferGraphemeIter<'a> {
|
pub fn grapheme_iter_at_index<'a>(&'a self, index: uint) -> BufferGraphemeIter<'a> {
|
||||||
// let mut node_stack: Vec<&'a TextNode> = Vec::new();
|
BufferGraphemeIter {
|
||||||
// let mut cur_node = &self.root;
|
gi: self.root.grapheme_iter_at_index(index)
|
||||||
// let mut char_i = index;
|
}
|
||||||
//
|
}
|
||||||
// loop {
|
|
||||||
// match cur_node.data {
|
|
||||||
// TextNodeData::Leaf(_) => {
|
|
||||||
// let mut char_iter = match cur_node.data {
|
|
||||||
// TextNodeData::Leaf(ref tb) => tb.as_str().chars(),
|
|
||||||
// _ => panic!("This should never happen.")
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// while char_i > 0 {
|
|
||||||
// char_iter.next();
|
|
||||||
// char_i -= 1;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return TextBufferIter {
|
|
||||||
// node_stack: node_stack,
|
|
||||||
// cur_block: char_iter,
|
|
||||||
// };
|
|
||||||
// },
|
|
||||||
//
|
|
||||||
// TextNodeData::Branch(ref left, ref right) => {
|
|
||||||
// if left.char_count > char_i {
|
|
||||||
// node_stack.push(&(**right));
|
|
||||||
// cur_node = &(**left);
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// cur_node = &(**right);
|
|
||||||
// char_i -= left.char_count;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl fmt::Show for Buffer {
|
|
||||||
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
// self.root.fmt(f)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -896,3 +857,97 @@ fn remove_lines_3() {
|
||||||
assert!(Some("e") == iter.next());
|
assert!(Some("e") == iter.next());
|
||||||
assert!(None == iter.next());
|
assert!(None == iter.next());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pos_2d_to_closest_1d_1() {
|
||||||
|
let mut buf = Buffer::new();
|
||||||
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
||||||
|
|
||||||
|
let pos = buf.pos_2d_to_closest_1d((2, 3));
|
||||||
|
|
||||||
|
assert!(pos == 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pos_2d_to_closest_1d_2() {
|
||||||
|
let mut buf = Buffer::new();
|
||||||
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
||||||
|
|
||||||
|
let pos = buf.pos_2d_to_closest_1d((2, 10));
|
||||||
|
|
||||||
|
assert!(pos == 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pos_2d_to_closest_1d_3() {
|
||||||
|
let mut buf = Buffer::new();
|
||||||
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
||||||
|
|
||||||
|
let pos = buf.pos_2d_to_closest_1d((10, 2));
|
||||||
|
|
||||||
|
assert!(pos == 29);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pos_1d_to_closest_2d_1() {
|
||||||
|
let mut buf = Buffer::new();
|
||||||
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
||||||
|
|
||||||
|
let pos = buf.pos_1d_to_closest_2d(5);
|
||||||
|
|
||||||
|
assert!(pos == (1, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pos_1d_to_closest_2d_2() {
|
||||||
|
let mut buf = Buffer::new();
|
||||||
|
buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0);
|
||||||
|
|
||||||
|
let pos = buf.pos_1d_to_closest_2d(50);
|
||||||
|
|
||||||
|
assert!(pos == (5, 6));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[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());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -207,11 +207,22 @@ impl BufferNode {
|
||||||
|
|
||||||
pub fn pos_2d_to_closest_1d_recursive(&self, pos: (uint, uint)) -> uint {
|
pub fn pos_2d_to_closest_1d_recursive(&self, pos: (uint, uint)) -> uint {
|
||||||
match self.data {
|
match self.data {
|
||||||
BufferNodeData::Leaf(_) => {
|
BufferNodeData::Leaf(ref line) => {
|
||||||
if pos.0 != 0 {
|
if pos.0 != 0 {
|
||||||
panic!("pos_2d_to_closest_1d_recursive(): at leaf, but index is not zero. This should never happen!");
|
return self.grapheme_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
if pos.1 >= self.grapheme_count {
|
||||||
|
if line.ending != LineEnding::None {
|
||||||
|
return self.grapheme_count - 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return self.grapheme_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return pos.1;
|
||||||
}
|
}
|
||||||
return min(pos.1, self.grapheme_count);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
BufferNodeData::Branch(ref left, ref right) => {
|
BufferNodeData::Branch(ref left, ref right) => {
|
||||||
|
@ -607,7 +618,7 @@ impl BufferNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Creates an iterator at the first character
|
/// Creates an iterator at the first grapheme
|
||||||
pub fn grapheme_iter<'a>(&'a self) -> BufferNodeGraphemeIter<'a> {
|
pub fn grapheme_iter<'a>(&'a self) -> BufferNodeGraphemeIter<'a> {
|
||||||
let mut node_stack: Vec<&'a BufferNode> = Vec::new();
|
let mut node_stack: Vec<&'a BufferNode> = Vec::new();
|
||||||
let mut cur_node = self;
|
let mut cur_node = self;
|
||||||
|
@ -635,6 +646,41 @@ impl BufferNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Creates an iterator at the given grapheme index
|
||||||
|
pub fn grapheme_iter_at_index<'a>(&'a self, index: uint) -> BufferNodeGraphemeIter<'a> {
|
||||||
|
let mut node_stack: Vec<&'a BufferNode> = Vec::new();
|
||||||
|
let mut cur_node = self;
|
||||||
|
let mut grapheme_i = index;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
match cur_node.data {
|
||||||
|
BufferNodeData::Leaf(_) => {
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
|
||||||
|
BufferNodeData::Branch(ref left, ref right) => {
|
||||||
|
if grapheme_i < left.grapheme_count {
|
||||||
|
node_stack.push(&(**right));
|
||||||
|
cur_node = &(**left);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cur_node = &(**right);
|
||||||
|
grapheme_i -= left.grapheme_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferNodeGraphemeIter {
|
||||||
|
node_stack: node_stack,
|
||||||
|
cur_line: match cur_node.data {
|
||||||
|
BufferNodeData::Leaf(ref line) => line.grapheme_iter_at_index(grapheme_i),
|
||||||
|
_ => panic!("This should never happen.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user