diff --git a/src/buffer/line.rs b/src/buffer/line.rs index d136056..2bc0bd8 100644 --- a/src/buffer/line.rs +++ b/src/buffer/line.rs @@ -2,7 +2,7 @@ use std::mem; use super::rope::{Rope, RopeGraphemeIter}; -use string_utils::is_line_ending; +use string_utils::{is_line_ending, grapheme_count}; /// A single line of text @@ -100,7 +100,7 @@ impl Line { } - pub fn new_from_str_unchecked(text: &str) -> Line { + pub fn new_from_str_with_count_unchecked(text: &str, count: usize) -> Line { let mut ending = LineEnding::None; let bytes = text.as_bytes(); @@ -175,8 +175,9 @@ impl Line { } // Create and return Line + let cnt = if ending == LineEnding::None { count } else { count - 1 }; return Line { - text: Rope::new_from_str(&text[..(bytes.len()-le_size)]), + text: Rope::new_from_str_with_count(&text[..(bytes.len()-le_size)], cnt), ending: ending, }; } @@ -189,7 +190,7 @@ impl Line { // TODO: this can be smarter, and can pass the string // directly to the Rope after taking off any line // endings. - return Line::new_from_str_unchecked(text.as_slice()); + return Line::new_from_str_with_count_unchecked(text.as_slice(), grapheme_count(text.as_slice())); } diff --git a/src/buffer/mod.rs b/src/buffer/mod.rs index a6d09d0..e962b80 100644 --- a/src/buffer/mod.rs +++ b/src/buffer/mod.rs @@ -73,7 +73,7 @@ impl Buffer { if a != b { let substr = &string[a..b]; - let line = Line::new_from_str_unchecked(substr); + let line = Line::new_from_str_with_count_unchecked(substr, count); let node = BufferNode::new_from_line_with_count_unchecked(line, count); buf.append_leaf_node_unchecked(node); } diff --git a/src/buffer/rope.rs b/src/buffer/rope.rs index 28213a8..ffc09e1 100644 --- a/src/buffer/rope.rs +++ b/src/buffer/rope.rs @@ -32,6 +32,7 @@ impl Rope { tree_height: 1, } } + /// Creates a new rope from a string slice pub fn new_from_str(s: &str) -> Rope { @@ -106,6 +107,19 @@ impl Rope { return rope; } + pub fn new_from_str_with_count(s: &str, count: usize) -> Rope { + if count <= MAX_NODE_SIZE { + Rope { + data: RopeData::Leaf(String::from_str(s)), + grapheme_count_: count, + tree_height: 1, + } + } + else { + Rope::new_from_str(s) + } + } + /// Creates a new rope from a string, consuming the string pub fn new_from_string(s: String) -> Rope { // TODO: special case short strings?