diff --git a/src/buffer/mod.rs b/src/buffer/mod.rs index 5d30951..90d14a7 100644 --- a/src/buffer/mod.rs +++ b/src/buffer/mod.rs @@ -9,11 +9,9 @@ use self::line::Line; use self::node::{BufferNode, BufferNodeGraphemeIter, BufferNodeLineIter}; use self::undo_stack::{UndoStack}; use self::undo_stack::Operation::*; -use self::line_formatter::{LineFormatter, RoundingBehavior}; use string_utils::{is_line_ending, grapheme_count}; pub mod line; -pub mod line_formatter; mod node; mod undo_stack; @@ -23,33 +21,30 @@ mod undo_stack; //============================================================= /// A text buffer -pub struct Buffer { +pub struct Buffer { text: BufferNode, file_path: Option, undo_stack: UndoStack, - pub formatter: T, } -impl Buffer { - pub fn new(formatter: T) -> Buffer { +impl Buffer { + pub fn new() -> Buffer { Buffer { - text: BufferNode::new(&formatter), + text: BufferNode::new(), file_path: None, undo_stack: UndoStack::new(), - formatter: formatter, } } - pub fn new_from_file(formatter: T, path: &Path) -> IoResult> { + pub fn new_from_file(path: &Path) -> IoResult { let mut f = BufferedReader::new(try!(File::open(path))); let mut buf = Buffer { - text: BufferNode::new(&formatter), + text: BufferNode::new(), file_path: Some(path.clone()), undo_stack: UndoStack::new(), - formatter: formatter, }; let string = f.read_to_string().unwrap(); @@ -77,7 +72,7 @@ impl Buffer { if a != b { let substr = &string[a..b]; let line = Line::new_from_str_unchecked(substr); - let node = BufferNode::new_from_line_with_count_unchecked(&buf.formatter, line, count); + let node = BufferNode::new_from_line_with_count_unchecked(line, count); buf.append_leaf_node_unchecked(node); } @@ -90,6 +85,7 @@ impl Buffer { return Ok(buf); } + //------------------------------------------------------------------------ @@ -104,11 +100,7 @@ impl Buffer { pub fn line_count(&self) -> usize { self.text.line_count } - - - pub fn dimensions(&self) -> (usize, usize) { - self.text.vis_dim - } + @@ -124,7 +116,7 @@ impl Buffer { } fn _insert_text(&mut self, text: &str, pos: usize) { - self.text.insert_text(&self.formatter, text, pos); + self.text.insert_text(text, pos); } @@ -168,15 +160,15 @@ impl Buffer { } // Complete removal of all text else if pos_a == 0 && pos_b == self.text.grapheme_count { - let mut temp_node = BufferNode::new(&self.formatter); + let mut temp_node = BufferNode::new(); mem::swap(&mut (self.text), &mut temp_node); } // All other cases else { - if self.text.remove_text_recursive(&self.formatter, 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!"); } - self.text.set_last_line_ending_recursive(&self.formatter); + self.text.set_last_line_ending_recursive(); } } @@ -241,13 +233,13 @@ impl Buffer { } // Complete removal of all lines else if line_a == 0 && line_b == self.text.line_count { - let mut temp_node = BufferNode::new(&self.formatter); + let mut temp_node = BufferNode::new(); mem::swap(&mut (self.text), &mut temp_node); } // All other cases else { - self.text.remove_lines_recursive(&self.formatter, line_a, line_b); - self.text.set_last_line_ending_recursive(&self.formatter); + self.text.remove_lines_recursive(line_a, line_b); + self.text.set_last_line_ending_recursive(); } } @@ -256,19 +248,12 @@ impl Buffer { /// doing any sanity checks. This is primarily for efficient /// file loading. pub fn append_line_unchecked(&mut self, line: Line) { - self.text.append_line_unchecked_recursive(&self.formatter, line); + self.text.append_line_unchecked_recursive(line); } fn append_leaf_node_unchecked(&mut self, node: BufferNode) { - self.text.append_leaf_node_unchecked_recursive(&self.formatter, node); - } - - - /// Runs the formatter on all of the text. Should be run whenever the - /// formatter has been changed. - pub fn reformat(&mut self) { - self.text.reformat_recursive(&self.formatter); + self.text.append_leaf_node_unchecked_recursive(node); } @@ -374,31 +359,6 @@ impl Buffer { pub fn line_col_to_index(&self, pos: (usize, usize)) -> usize { return self.text.line_col_to_index_recursive(pos); } - - - /// Converts a grapheme index into a visual line and column number. - /// - /// If the index is off the end of the text, returns the visual line and - /// column number of the last valid text position. - pub fn index_to_v2d(&self, pos: usize) -> (usize, usize) { - let mut index = pos; - if index > self.grapheme_count() { - index = self.grapheme_count(); - } - return self.text.index_to_v2d_recursive(&self.formatter, index); - } - - - /// Converts a visual line and column number into a grapheme index. - /// - /// If the visual column number given is outside of the text, returns the - /// index of the horizontally-closest valid position. If the visual line - /// number given is beyond the end of the buffer, returns the index of - /// the buffer's last valid position. - pub fn v2d_to_index(&self, pos: (usize, usize), rounding: (RoundingBehavior, RoundingBehavior)) -> usize { - return self.text.v2d_to_index_recursive(&self.formatter, pos, rounding); - } - //------------------------------------------------------------------------ @@ -575,12 +535,11 @@ impl<'a> Iterator for BufferLineIter<'a> { #[cfg(test)] mod tests { - use super::line_formatter::TestLineFormatter; use super::{Buffer, BufferGraphemeIter, BufferLineIter}; #[test] fn insert_text() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hello 世界!", 0); @@ -603,7 +562,7 @@ mod tests { #[test] fn insert_text_with_newlines() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hello\n 世界\r\n!", 0); @@ -628,7 +587,7 @@ mod tests { #[test] fn insert_text_in_non_empty_buffer_1() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hello\n 世界\r\n!", 0); buf.insert_text("Again ", 0); @@ -660,7 +619,7 @@ mod tests { #[test] fn insert_text_in_non_empty_buffer_2() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hello\n 世界\r\n!", 0); buf.insert_text(" again", 5); @@ -692,7 +651,7 @@ mod tests { #[test] fn insert_text_in_non_empty_buffer_3() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hello\n 世界\r\n!", 0); buf.insert_text("again", 6); @@ -723,7 +682,7 @@ mod tests { #[test] fn insert_text_in_non_empty_buffer_4() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hello\n 世界\r\n!", 0); buf.insert_text("again", 11); @@ -754,7 +713,7 @@ mod tests { #[test] fn insert_text_in_non_empty_buffer_5() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hello\n 世界\r\n!", 0); buf.insert_text("again", 2); @@ -786,7 +745,7 @@ mod tests { #[test] fn insert_text_in_non_empty_buffer_6() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hello\n 世界\r\n!", 0); buf.insert_text("again", 8); @@ -818,7 +777,7 @@ mod tests { #[test] fn insert_text_in_non_empty_buffer_7() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hello\n 世界\r\n!", 0); buf.insert_text("\nag\n\nain\n", 2); @@ -854,7 +813,7 @@ mod tests { #[test] fn remove_text_1() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0); assert!(buf.grapheme_count() == 29); @@ -898,7 +857,7 @@ mod tests { #[test] fn remove_text_2() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0); assert!(buf.grapheme_count() == 29); @@ -933,7 +892,7 @@ mod tests { #[test] fn remove_text_3() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0); assert!(buf.grapheme_count() == 29); @@ -968,7 +927,7 @@ mod tests { #[test] fn remove_text_4() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0); assert!(buf.grapheme_count() == 29); @@ -1009,7 +968,7 @@ mod tests { #[test] fn remove_text_5() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0); assert!(buf.grapheme_count() == 29); @@ -1044,7 +1003,7 @@ mod tests { #[test] fn remove_text_6() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hello\nworld!", 0); assert!(buf.grapheme_count() == 12); @@ -1065,7 +1024,7 @@ mod tests { #[test] fn remove_text_7() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\nworld!", 0); assert!(buf.grapheme_count() == 15); @@ -1088,7 +1047,7 @@ mod tests { #[test] fn remove_text_8() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hello\nworld!", 0); assert!(buf.grapheme_count() == 12); @@ -1110,7 +1069,7 @@ mod tests { #[test] fn remove_text_9() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hello\nworld!", 0); assert!(buf.grapheme_count() == 12); @@ -1136,7 +1095,7 @@ mod tests { #[test] fn remove_text_10() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("12\n34\n56\n78", 0); assert!(buf.grapheme_count() == 11); @@ -1158,7 +1117,7 @@ mod tests { #[test] fn remove_text_11() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("1234567890", 0); assert!(buf.grapheme_count() == 10); @@ -1185,7 +1144,7 @@ mod tests { #[test] fn move_text_1() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0); @@ -1230,7 +1189,7 @@ mod tests { #[test] fn move_text_2() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0); @@ -1275,7 +1234,7 @@ mod tests { #[test] fn move_text_3() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0); @@ -1320,7 +1279,7 @@ mod tests { #[test] fn move_text_4() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0); @@ -1365,7 +1324,7 @@ mod tests { #[test] fn move_text_5() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0); @@ -1410,7 +1369,7 @@ mod tests { #[test] fn remove_lines_1() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0); assert!(buf.grapheme_count() == 29); @@ -1441,7 +1400,7 @@ mod tests { #[test] fn remove_lines_2() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0); assert!(buf.grapheme_count() == 29); @@ -1472,7 +1431,7 @@ mod tests { #[test] fn remove_lines_3() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0); assert!(buf.grapheme_count() == 29); @@ -1505,7 +1464,7 @@ mod tests { #[test] fn line_col_to_index_1() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0); let pos = buf.line_col_to_index((2, 3)); @@ -1516,7 +1475,7 @@ mod tests { #[test] fn line_col_to_index_2() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0); let pos = buf.line_col_to_index((2, 10)); @@ -1526,7 +1485,7 @@ mod tests { #[test] fn line_col_to_index_3() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0); let pos = buf.line_col_to_index((10, 2)); @@ -1537,7 +1496,7 @@ mod tests { #[test] fn index_to_line_col_1() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0); let pos = buf.index_to_line_col(5); @@ -1548,7 +1507,7 @@ mod tests { #[test] fn index_to_line_col_2() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0); let pos = buf.index_to_line_col(50); @@ -1559,7 +1518,7 @@ mod tests { #[test] fn string_from_range_1() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0); let s = buf.string_from_range(1, 12); @@ -1570,7 +1529,7 @@ mod tests { #[test] fn string_from_range_2() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0); let s = buf.string_from_range(0, 29); @@ -1581,7 +1540,7 @@ mod tests { #[test] fn grapheme_iter_at_index_1() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0); let mut iter = buf.grapheme_iter_at_index(16); @@ -1605,7 +1564,7 @@ mod tests { #[test] fn grapheme_iter_at_index_2() { - let mut buf = Buffer::new(TestLineFormatter::new()); + let mut buf = Buffer::new(); buf.insert_text("Hi\nthere\npeople\nof\nthe\nworld!", 0); let mut iter = buf.grapheme_iter_at_index(29); diff --git a/src/buffer/node.rs b/src/buffer/node.rs index 366b38c..d5cede9 100644 --- a/src/buffer/node.rs +++ b/src/buffer/node.rs @@ -1,7 +1,6 @@ use std::mem; use std::cmp::{min, max}; -use super::line_formatter::{LineFormatter, RoundingBehavior}; use string_utils::is_line_ending; use super::line::{Line, LineEnding, LineGraphemeIter, str_to_line_ending}; @@ -16,46 +15,39 @@ pub struct BufferNode { pub grapheme_count: usize, pub line_count: usize, - - pub vis_dim: (usize, usize), // Height, width } impl BufferNode { - pub fn new(f: &T) -> BufferNode { + pub fn new() -> BufferNode { let line = Line::new(); - let dim = f.dimensions(&line); BufferNode { data: BufferNodeData::Leaf(line), tree_height: 1, grapheme_count: 0, line_count: 1, - vis_dim: dim, } } - pub fn new_from_line(f: &T, line: Line) -> BufferNode { + pub fn new_from_line(line: Line) -> BufferNode { let gc = line.grapheme_count(); - let dim = f.dimensions(&line); BufferNode { data: BufferNodeData::Leaf(line), tree_height: 1, grapheme_count: gc, line_count: 1, - vis_dim: dim, } } - pub fn new_from_line_with_count_unchecked(_: &T, line: Line, grapheme_count: usize) -> BufferNode { + pub fn new_from_line_with_count_unchecked(line: Line, grapheme_count: usize) -> BufferNode { BufferNode { data: BufferNodeData::Leaf(line), tree_height: 1, grapheme_count: grapheme_count, line_count: 1, - vis_dim: (1, grapheme_count), } } @@ -73,28 +65,26 @@ impl BufferNode { } - fn update_stats(&mut self, f: &T) { + fn update_stats(&mut self) { self.update_height(); match self.data { BufferNodeData::Leaf(ref line) => { self.grapheme_count = line.grapheme_count(); self.line_count = 1; - self.vis_dim = f.dimensions(line); }, BufferNodeData::Branch(ref left, ref right) => { self.grapheme_count = left.grapheme_count + right.grapheme_count; self.line_count = left.line_count + right.line_count; - self.vis_dim = (left.vis_dim.0 + right.vis_dim.0, max(left.vis_dim.1, right.vis_dim.1)); } } } /// Rotates the tree under the node left - fn rotate_left(&mut self, f: &T) { - let mut temp = BufferNode::new(f); + fn rotate_left(&mut self) { + let mut temp = BufferNode::new(); if let BufferNodeData::Branch(_, ref mut right) = self.data { mem::swap(&mut temp, &mut (**right)); @@ -112,17 +102,17 @@ impl BufferNode { if let BufferNodeData::Branch(ref mut left, _) = temp.data { mem::swap(&mut (**left), self); - left.update_stats(f); + left.update_stats(); } mem::swap(&mut temp, self); - self.update_stats(f); + self.update_stats(); } /// Rotates the tree under the node right - fn rotate_right(&mut self, f: &T) { - let mut temp = BufferNode::new(f); + fn rotate_right(&mut self) { + let mut temp = BufferNode::new(); if let BufferNodeData::Branch(ref mut left, _) = self.data { mem::swap(&mut temp, &mut (**left)); @@ -140,16 +130,16 @@ impl BufferNode { if let BufferNodeData::Branch(_, ref mut right) = temp.data { mem::swap(&mut (**right), self); - right.update_stats(f); + right.update_stats(); } mem::swap(&mut temp, self); - self.update_stats(f); + self.update_stats(); } /// Rebalances the tree under the node - fn rebalance(&mut self, f: &T) { + fn rebalance(&mut self) { loop { let mut rot: isize; @@ -166,7 +156,7 @@ impl BufferNode { } if child_rot { - left.rotate_left(f); + left.rotate_left(); } rot = 1; @@ -181,7 +171,7 @@ impl BufferNode { } if child_rot { - right.rotate_right(f); + right.rotate_right(); } rot = -1; @@ -197,25 +187,10 @@ impl BufferNode { } if rot == 1 { - self.rotate_right(f); + self.rotate_right(); } else if rot == -1 { - self.rotate_left(f); - } - } - } - - - pub fn reformat_recursive(&mut self, f: &T) { - match self.data { - BufferNodeData::Branch(ref mut left, ref mut right) => { - left.reformat_recursive(f); - right.reformat_recursive(f); - self.vis_dim = ((left.vis_dim.0 + right.vis_dim.0), max(left.vis_dim.1, right.vis_dim.1)); - }, - - BufferNodeData::Leaf(ref line) => { - self.vis_dim = f.dimensions(line); + self.rotate_left(); } } } @@ -311,66 +286,8 @@ impl BufferNode { } - pub fn index_to_v2d_recursive(&self, f: &T, index: usize) -> (usize, usize) { - match self.data { - BufferNodeData::Leaf(ref line) => { - return f.index_to_v2d(line, index); - }, - - BufferNodeData::Branch(ref left, ref right) => { - if index < left.grapheme_count { - return left.index_to_v2d_recursive(f, index); - } - else { - let (y, x) = right.index_to_v2d_recursive(f, (index - left.grapheme_count)); - return (y + left.vis_dim.0, x); - } - } - } - } - - - pub fn v2d_to_index_recursive(&self, f: &T, pos: (usize, usize), rounding: (RoundingBehavior, RoundingBehavior)) -> usize { - match self.data { - BufferNodeData::Leaf(ref line) => { - let mut r = f.v2d_to_index(line, pos, rounding); - - // TODO: is this the right thing to do? The idea is that - // the non-leaf branch code should put us in the right leaf - // anyway, and returning an index equal to the leaf's - // grapheme count is putting it on the next line instead of - // this one. - if r == self.grapheme_count && self.grapheme_count > 0 { - r -= 1; - } - return r; - }, - - BufferNodeData::Branch(ref left, ref right) => { - if rounding.0 == RoundingBehavior::Round { - // TODO - return 0; - - } - else if rounding.0 == RoundingBehavior::Floor { - if pos.0 < left.vis_dim.0 { - return left.v2d_to_index_recursive(f, pos, rounding); - } - else { - return left.grapheme_count + right.v2d_to_index_recursive(f, (pos.0 - left.vis_dim.0, pos.1), rounding); - } - } - else { // RoundingBehavior::Ceiling - // TODO - return 0; - } - } - } - } - - /// Insert 'text' at grapheme position 'pos'. - pub fn insert_text(&mut self, f: &T, text: &str, pos: usize) { + pub fn insert_text(&mut self, text: &str, pos: usize) { // Byte indices let mut b1: usize = 0; let mut b2: usize = 0; @@ -383,14 +300,14 @@ impl BufferNode { for grapheme in text.grapheme_indices(true) { if is_line_ending(grapheme.1) { if g1 < g2 { - self.insert_text_recursive(f, &text[b1..b2], pos + g1); + self.insert_text_recursive(&text[b1..b2], pos + g1); } g1 = g2; b2 += grapheme.1.len(); g2 += 1; - self.insert_line_break_recursive(f, str_to_line_ending(grapheme.1), pos + g1); + self.insert_line_break_recursive(str_to_line_ending(grapheme.1), pos + g1); b1 = b2; g1 = g2; @@ -402,22 +319,22 @@ impl BufferNode { } if g1 < g2 { - self.insert_text_recursive(f, &text[b1..b2], pos + g1); + self.insert_text_recursive(&text[b1..b2], pos + g1); } } /// Inserts the given text string at the given grapheme position. /// Note: this assumes the given text has no newline graphemes. - pub fn insert_text_recursive(&mut self, f: &T, text: &str, pos: usize) { + pub fn insert_text_recursive(&mut self, text: &str, pos: usize) { match self.data { // Find node for text to be inserted into BufferNodeData::Branch(ref mut left, ref mut right) => { if pos < left.grapheme_count { - left.insert_text_recursive(f, text, pos); + left.insert_text_recursive(text, pos); } else { - right.insert_text_recursive(f, text, pos - left.grapheme_count); + right.insert_text_recursive(text, pos - left.grapheme_count); } }, @@ -428,12 +345,12 @@ impl BufferNode { }, } - self.update_stats(f); + self.update_stats(); } /// Inserts a line break at the given grapheme position - pub fn insert_line_break_recursive(&mut self, f: &T, ending: LineEnding, pos: usize) { + pub fn insert_line_break_recursive(&mut self, ending: LineEnding, pos: usize) { if ending == LineEnding::None { return; } @@ -445,10 +362,10 @@ impl BufferNode { // Find node for the line break to be inserted into BufferNodeData::Branch(ref mut left, ref mut right) => { if pos < left.grapheme_count { - left.insert_line_break_recursive(f, ending, pos); + left.insert_line_break_recursive(ending, pos); } else { - right.insert_line_break_recursive(f, ending, pos - left.grapheme_count); + right.insert_line_break_recursive(ending, pos - left.grapheme_count); } do_split = false; }, @@ -464,16 +381,16 @@ impl BufferNode { if do_split { // Insert line break let new_line = old_line.split(ending, pos); - let new_node_a = Box::new(BufferNode::new_from_line(f, old_line)); - let new_node_b = Box::new(BufferNode::new_from_line(f, new_line)); + let new_node_a = Box::new(BufferNode::new_from_line(old_line)); + let new_node_b = Box::new(BufferNode::new_from_line(new_line)); self.data = BufferNodeData::Branch(new_node_a, new_node_b); - self.update_stats(f); + self.update_stats(); } else { - self.update_stats(f); - self.rebalance(f); + self.update_stats(); + self.rebalance(); } } @@ -481,8 +398,8 @@ impl BufferNode { /// Removes text between grapheme positions pos_a and pos_b. /// Returns true if a dangling left side remains from the removal. /// Returns false otherwise. - pub fn remove_text_recursive(&mut self, f: &T, pos_a: usize, pos_b: usize, is_last: bool) -> bool { - let mut temp_node = BufferNode::new(f); + pub fn remove_text_recursive(&mut self, pos_a: usize, pos_b: usize, is_last: bool) -> bool { + let mut temp_node = BufferNode::new(); let mut total_side_removal = false; let mut dangling_line = false; let mut do_merge_fix = false; @@ -500,7 +417,7 @@ impl BufferNode { if pos_b > left.grapheme_count { let a = 0; let b = pos_b - left.grapheme_count; - right.remove_text_recursive(f, a, b, is_last); + right.remove_text_recursive(a, b, is_last); } total_side_removal = true; @@ -511,7 +428,7 @@ impl BufferNode { if pos_a < left.grapheme_count { let a = pos_a; let b = left.grapheme_count; - dangling_line = left.remove_text_recursive(f, a, b, false); + dangling_line = left.remove_text_recursive(a, b, false); } if is_last && !dangling_line { @@ -532,14 +449,14 @@ impl BufferNode { if pos_b > left.grapheme_count { let a = if pos_a > left.grapheme_count {pos_a - left.grapheme_count} else {0}; let b = pos_b - left.grapheme_count; - dangling_line = right.remove_text_recursive(f, a, b, is_last) && !is_last; + dangling_line = right.remove_text_recursive(a, b, is_last) && !is_last; } // Left side if pos_a < left.grapheme_count { let a = pos_a; let b = min(pos_b, left.grapheme_count); - do_merge_fix = left.remove_text_recursive(f, a, b, false); + do_merge_fix = left.remove_text_recursive(a, b, false); merge_line_number = left.line_count - 1; } } @@ -560,7 +477,7 @@ impl BufferNode { // Do the merge fix if necessary if do_merge_fix { - self.merge_line_with_next_recursive(f, merge_line_number, None); + self.merge_line_with_next_recursive(merge_line_number, None); } // If one of the sides was completely removed, replace self with the // remaining side. @@ -568,54 +485,54 @@ impl BufferNode { mem::swap(&mut temp_node, self); } - self.update_stats(f); - self.rebalance(f); + self.update_stats(); + self.rebalance(); return dangling_line; } - pub fn append_line_unchecked_recursive(&mut self, f: &T, line: Line) { + pub fn append_line_unchecked_recursive(&mut self, line: Line) { let mut other_line = Line::new(); if let BufferNodeData::Branch(_, ref mut right) = self.data { - right.append_line_unchecked_recursive(f, line); + right.append_line_unchecked_recursive(line); } else { if let BufferNodeData::Leaf(ref mut this_line) = self.data { mem::swap(this_line, &mut other_line); } - let new_node_a = Box::new(BufferNode::new_from_line(f, other_line)); - let new_node_b = Box::new(BufferNode::new_from_line(f, line)); + let new_node_a = Box::new(BufferNode::new_from_line(other_line)); + let new_node_b = Box::new(BufferNode::new_from_line(line)); self.data = BufferNodeData::Branch(new_node_a, new_node_b); } - self.update_stats(f); - self.rebalance(f); + self.update_stats(); + self.rebalance(); } - pub fn append_leaf_node_unchecked_recursive(&mut self, f: &T, node: BufferNode) { + pub fn append_leaf_node_unchecked_recursive(&mut self, node: BufferNode) { if let BufferNodeData::Branch(_, ref mut right) = self.data { - right.append_leaf_node_unchecked_recursive(f, node); + right.append_leaf_node_unchecked_recursive(node); } else { - let mut new_left_node = BufferNode::new(f); + let mut new_left_node = BufferNode::new(); mem::swap(self, &mut new_left_node); self.data = BufferNodeData::Branch(Box::new(new_left_node), Box::new(node)); } - self.update_stats(f); - self.rebalance(f); + self.update_stats(); + self.rebalance(); } /// Removes lines in line number range [line_a, line_b) - pub fn remove_lines_recursive(&mut self, f: &T, line_a: usize, line_b: usize) { + pub fn remove_lines_recursive(&mut self, line_a: usize, line_b: usize) { let mut remove_left = false; let mut remove_right = false; - let mut temp_node = BufferNode::new(f); + let mut temp_node = BufferNode::new(); if let BufferNodeData::Branch(ref mut left, ref mut right) = self.data { // Right node completely removed @@ -626,7 +543,7 @@ impl BufferNode { else if line_b > left.line_count { let a = if line_a > left.line_count {line_a - left.line_count} else {0}; let b = line_b - left.line_count; - right.remove_lines_recursive(f, a, b); + right.remove_lines_recursive(a, b); } // Left node completely removed @@ -637,7 +554,7 @@ impl BufferNode { else if line_a < left.line_count { let a = line_a; let b = min(left.line_count, line_b); - left.remove_lines_recursive(f, a, b); + left.remove_lines_recursive(a, b); } // Set up for node removal @@ -660,17 +577,17 @@ impl BufferNode { mem::swap(&mut temp_node, self); } - self.update_stats(f); - self.rebalance(f); + self.update_stats(); + self.rebalance(); } - pub fn merge_line_with_next_recursive(&mut self, f: &T, line_number: usize, fetched_line: Option<&Line>) { + pub fn merge_line_with_next_recursive(&mut self, line_number: usize, fetched_line: Option<&Line>) { match fetched_line { None => { - let line: Option = self.pull_out_line_recursive(f, line_number + 1); + let line: Option = self.pull_out_line_recursive(line_number + 1); if let Some(ref l) = line { - self.merge_line_with_next_recursive(f, line_number, Some(l)); + self.merge_line_with_next_recursive(line_number, Some(l)); } }, @@ -678,10 +595,10 @@ impl BufferNode { match self.data { BufferNodeData::Branch(ref mut left, ref mut right) => { if line_number < left.line_count { - left.merge_line_with_next_recursive(f, line_number, Some(line)); + left.merge_line_with_next_recursive(line_number, Some(line)); } else { - right.merge_line_with_next_recursive(f, line_number - left.line_count, Some(line)); + right.merge_line_with_next_recursive(line_number - left.line_count, Some(line)); } }, @@ -693,15 +610,15 @@ impl BufferNode { } } - self.update_stats(f); - self.rebalance(f); + self.update_stats(); + self.rebalance(); } /// Removes a single line out of the text and returns it. - pub fn pull_out_line_recursive(&mut self, f: &T, line_number: usize) -> Option { + pub fn pull_out_line_recursive(&mut self, line_number: usize) -> Option { let mut pulled_line = Line::new(); - let mut temp_node = BufferNode::new(f); + let mut temp_node = BufferNode::new(); let mut side_removal = false; match self.data { @@ -713,7 +630,7 @@ impl BufferNode { side_removal = true; } else { - pulled_line = left.pull_out_line_recursive(f, line_number).unwrap(); + pulled_line = left.pull_out_line_recursive(line_number).unwrap(); } } else if line_number < self.line_count { @@ -723,7 +640,7 @@ impl BufferNode { side_removal = true; } else { - pulled_line = right.pull_out_line_recursive(f, line_number - left.line_count).unwrap(); + pulled_line = right.pull_out_line_recursive(line_number - left.line_count).unwrap(); } } else { @@ -741,8 +658,8 @@ impl BufferNode { mem::swap(&mut temp_node, self); } - self.update_stats(f); - self.rebalance(f); + self.update_stats(); + self.rebalance(); return Some(pulled_line); } @@ -750,10 +667,10 @@ impl BufferNode { /// Ensures that the last line in the node tree has no /// ending line break. - pub fn set_last_line_ending_recursive(&mut self, f: &T) { + pub fn set_last_line_ending_recursive(&mut self) { match self.data { BufferNodeData::Branch(_, ref mut right) => { - right.set_last_line_ending_recursive(f); + right.set_last_line_ending_recursive(); }, BufferNodeData::Leaf(ref mut line) => { @@ -761,7 +678,7 @@ impl BufferNode { }, } - self.update_stats(f); + self.update_stats(); } @@ -1015,18 +932,16 @@ impl<'a> Iterator for BufferNodeLineIter<'a> { mod tests { use super::BufferNode; use super::super::line::LineEnding; - use super::super::line_formatter::TestLineFormatter; #[test] fn merge_line_with_next_recursive_1() { - let f = TestLineFormatter::new(); - let mut node = BufferNode::new(&f); - node.insert_text(&f, "Hi\n there!", 0); + let mut node = BufferNode::new(); + node.insert_text("Hi\n there!", 0); assert!(node.grapheme_count == 10); assert!(node.line_count == 2); - node.merge_line_with_next_recursive(&f, 0, None); + node.merge_line_with_next_recursive(0, None); let mut iter = node.grapheme_iter(); @@ -1047,14 +962,13 @@ mod tests { #[test] fn merge_line_with_next_recursive_2() { - let f = TestLineFormatter::new(); - let mut node = BufferNode::new(&f); - node.insert_text(&f, "Hi\n there\n people \nof the\n world!", 0); + let mut node = BufferNode::new(); + node.insert_text("Hi\n there\n people \nof the\n world!", 0); assert!(node.grapheme_count == 33); assert!(node.line_count == 5); - node.merge_line_with_next_recursive(&f, 2, None); + node.merge_line_with_next_recursive(2, None); let mut iter = node.grapheme_iter(); @@ -1098,14 +1012,13 @@ mod tests { #[test] fn merge_line_with_next_recursive_3() { - let f = TestLineFormatter::new(); - let mut node = BufferNode::new(&f); - node.insert_text(&f, "Hi\n there\n people \nof the\n world!", 0); + let mut node = BufferNode::new(); + node.insert_text("Hi\n there\n people \nof the\n world!", 0); assert!(node.grapheme_count == 33); assert!(node.line_count == 5); - node.merge_line_with_next_recursive(&f, 0, None); + node.merge_line_with_next_recursive(0, None); let mut iter = node.grapheme_iter(); @@ -1149,14 +1062,13 @@ mod tests { #[test] fn pull_out_line_recursive_1() { - let f = TestLineFormatter::new(); - let mut node = BufferNode::new(&f); - node.insert_text(&f, "Hi\n there\n people \nof the\n world!", 0); + let mut node = BufferNode::new(); + node.insert_text("Hi\n there\n people \nof the\n world!", 0); assert!(node.grapheme_count == 33); assert!(node.line_count == 5); - let line = node.pull_out_line_recursive(&f, 0).unwrap(); + let line = node.pull_out_line_recursive(0).unwrap(); assert!(line.as_str() == "Hi"); assert!(line.ending == LineEnding::LF); @@ -1200,14 +1112,13 @@ mod tests { #[test] fn pull_out_line_recursive_2() { - let f = TestLineFormatter::new(); - let mut node = BufferNode::new(&f); - node.insert_text(&f, "Hi\n there\n people \nof the\n world!", 0); + let mut node = BufferNode::new(); + node.insert_text("Hi\n there\n people \nof the\n world!", 0); assert!(node.grapheme_count == 33); assert!(node.line_count == 5); - let line = node.pull_out_line_recursive(&f, 2).unwrap(); + let line = node.pull_out_line_recursive(2).unwrap(); assert!(line.as_str() == " people "); assert!(line.ending == LineEnding::LF); @@ -1245,14 +1156,13 @@ mod tests { #[test] fn pull_out_line_recursive_3() { - let f = TestLineFormatter::new(); - let mut node = BufferNode::new(&f); - node.insert_text(&f, "Hi\n there\n people \nof the\n world!", 0); + let mut node = BufferNode::new(); + node.insert_text("Hi\n there\n people \nof the\n world!", 0); assert!(node.grapheme_count == 33); assert!(node.line_count == 5); - let line = node.pull_out_line_recursive(&f, 4).unwrap(); + let line = node.pull_out_line_recursive(4).unwrap(); assert!(line.as_str() == " world!"); assert!(line.ending == LineEnding::None); diff --git a/src/editor/cursor.rs b/src/editor/cursor.rs index 6bbe61f..803b2fa 100644 --- a/src/editor/cursor.rs +++ b/src/editor/cursor.rs @@ -5,7 +5,7 @@ use std::ops::{Index, IndexMut}; use std::cmp::Ordering; use buffer::Buffer; -use buffer::line_formatter::LineFormatter; +use super::formatter::LineFormatter; /// A text cursor. Also represents selections when range.0 != range.1. /// @@ -27,9 +27,10 @@ impl Cursor { } } - pub fn update_vis_start(&mut self, buf: &Buffer) { - let (_, h) = buf.index_to_v2d(self.range.0); - self.vis_start = h; + pub fn update_vis_start(&mut self, buf: &Buffer, f: &T) { + // TODO + //let (_, h) = buf.index_to_v2d(self.range.0); + //self.vis_start = h; } } diff --git a/src/buffer/line_formatter.rs b/src/editor/formatter.rs similarity index 100% rename from src/buffer/line_formatter.rs rename to src/editor/formatter.rs diff --git a/src/editor/mod.rs b/src/editor/mod.rs index 0aefeb8..8e4dbda 100644 --- a/src/editor/mod.rs +++ b/src/editor/mod.rs @@ -2,19 +2,21 @@ use buffer::Buffer; use buffer::line::LineEnding; -use buffer::line_formatter::LineFormatter; -use buffer::line_formatter::RoundingBehavior::*; +use self::formatter::LineFormatter; +use self::formatter::RoundingBehavior::*; use std::path::Path; use std::cmp::{min, max}; use files::{save_buffer_to_file}; use string_utils::grapheme_count; use self::cursor::CursorSet; +pub mod formatter; mod cursor; pub struct Editor { - pub buffer: Buffer, + pub buffer: Buffer, + pub formatter: T, pub file_path: Path, pub line_ending_type: LineEnding, pub soft_tabs: bool, @@ -34,7 +36,8 @@ impl Editor { /// Create a new blank editor pub fn new(formatter: T) -> Editor { Editor { - buffer: Buffer::new(formatter), + buffer: Buffer::new(), + formatter: formatter, file_path: Path::new(""), line_ending_type: LineEnding::LF, soft_tabs: false, @@ -47,8 +50,7 @@ impl Editor { } pub fn new_from_file(formatter: T, path: &Path) -> Editor { - //let buf = match load_file_to_buffer(path, formatter) { - let buf = match Buffer::new_from_file(formatter, path) { + let buf = match Buffer::new_from_file(path) { Ok(b) => {b}, // TODO: handle un-openable file better _ => panic!("Could not open file!"), @@ -56,6 +58,7 @@ impl Editor { let mut ed = Editor { buffer: buf, + formatter: formatter, file_path: path.clone(), line_ending_type: LineEnding::LF, soft_tabs: false, @@ -70,7 +73,7 @@ impl Editor { //let mut cur = Cursor::new(); //cur.range.0 = 30; //cur.range.1 = 30; - //cur.update_vis_start(&(ed.buffer)); + //cur.update_vis_start(&(ed.buffer), &(ed.formatter)); //ed.cursors.add_cursor(cur); ed.auto_detect_line_ending(); @@ -259,7 +262,7 @@ impl Editor { self.cursors.truncate(1); self.cursors[0].range.0 = pos; self.cursors[0].range.1 = pos; - self.cursors[0].update_vis_start(&(self.buffer)); + self.cursors[0].update_vis_start(&(self.buffer), &(self.formatter)); self.move_view_to_cursor(); @@ -276,7 +279,7 @@ impl Editor { self.cursors.truncate(1); self.cursors[0].range.0 = pos; self.cursors[0].range.1 = pos; - self.cursors[0].update_vis_start(&(self.buffer)); + self.cursors[0].update_vis_start(&(self.buffer), &(self.formatter)); self.move_view_to_cursor(); @@ -292,23 +295,25 @@ impl Editor { // TODO: handle multiple cursors properly. Should only move if // there are no cursors currently in view, and should jump to // the closest cursor. - let (v, h) = self.buffer.index_to_v2d(self.cursors[0].range.0); - // Horizontal - if h < self.view_pos.1 { - self.view_pos.1 = h; - } - else if h >= (self.view_pos.1 + self.view_dim.1) { - self.view_pos.1 = 1 + h - self.view_dim.1; - } - - // Vertical - if v < self.view_pos.0 { - self.view_pos.0 = v; - } - else if v >= (self.view_pos.0 + self.view_dim.0) { - self.view_pos.0 = 1 + v - self.view_dim.0; - } + // TODO: update to new formatting code + //let (v, h) = self.buffer.index_to_v2d(self.cursors[0].range.0); + // + //// Horizontal + //if h < self.view_pos.1 { + // self.view_pos.1 = h; + //} + //else if h >= (self.view_pos.1 + self.view_dim.1) { + // self.view_pos.1 = 1 + h - self.view_dim.1; + //} + // + //// Vertical + //if v < self.view_pos.0 { + // self.view_pos.0 = v; + //} + //else if v >= (self.view_pos.0 + self.view_dim.0) { + // self.view_pos.0 = 1 + v - self.view_dim.0; + //} } pub fn insert_text_at_cursor(&mut self, text: &str) { @@ -325,7 +330,7 @@ impl Editor { // Move cursor c.range.0 += str_len + offset; c.range.1 += str_len + offset; - c.update_vis_start(&(self.buffer)); + c.update_vis_start(&(self.buffer), &(self.formatter)); // Update offset offset += str_len; @@ -336,43 +341,45 @@ impl Editor { } pub fn insert_tab_at_cursor(&mut self) { - self.cursors.make_consistent(); + // TODO: update to new formatting code - if self.soft_tabs { - let mut offset = 0; - - for c in self.cursors.iter_mut() { - // Update cursor with offset - c.range.0 += offset; - c.range.1 += offset; - - // Figure out how many spaces to insert - let (_, vis_pos) = self.buffer.index_to_v2d(c.range.0); - // TODO: handle tab settings - let next_tab_stop = ((vis_pos / self.soft_tab_width as usize) + 1) * self.soft_tab_width as usize; - let space_count = min(next_tab_stop - vis_pos, 8); - - - // Insert spaces - let space_strs = ["", " ", " ", " ", " ", " ", " ", " ", " "]; - self.buffer.insert_text(space_strs[space_count], c.range.0); - self.dirty = true; - - // Move cursor - c.range.0 += space_count; - c.range.1 += space_count; - c.update_vis_start(&(self.buffer)); - - // Update offset - offset += space_count; - } - - // Adjust view - self.move_view_to_cursor(); - } - else { - self.insert_text_at_cursor("\t"); - } + //self.cursors.make_consistent(); + // + //if self.soft_tabs { + // let mut offset = 0; + // + // for c in self.cursors.iter_mut() { + // // Update cursor with offset + // c.range.0 += offset; + // c.range.1 += offset; + // + // // Figure out how many spaces to insert + // let (_, vis_pos) = self.buffer.index_to_v2d(c.range.0); + // // TODO: handle tab settings + // let next_tab_stop = ((vis_pos / self.soft_tab_width as usize) + 1) * self.soft_tab_width as usize; + // let space_count = min(next_tab_stop - vis_pos, 8); + // + // + // // Insert spaces + // let space_strs = ["", " ", " ", " ", " ", " ", " ", " ", " "]; + // self.buffer.insert_text(space_strs[space_count], c.range.0); + // self.dirty = true; + // + // // Move cursor + // c.range.0 += space_count; + // c.range.1 += space_count; + // c.update_vis_start(&(self.buffer), &(self.formatter)); + // + // // Update offset + // offset += space_count; + // } + // + // // Adjust view + // self.move_view_to_cursor(); + //} + //else { + // self.insert_text_at_cursor("\t"); + //} } pub fn backspace_at_cursor(&mut self) { @@ -409,7 +416,7 @@ impl Editor { // Move cursor c.range.0 -= len; c.range.1 -= len; - c.update_vis_start(&(self.buffer)); + c.update_vis_start(&(self.buffer), &(self.formatter)); // Update offset offset += len; @@ -444,7 +451,7 @@ impl Editor { self.dirty = true; // Move cursor - c.update_vis_start(&(self.buffer)); + c.update_vis_start(&(self.buffer), &(self.formatter)); // Update offset offset += len; @@ -480,7 +487,7 @@ impl Editor { offset += len; } - c.update_vis_start(&(self.buffer)); + c.update_vis_start(&(self.buffer), &(self.formatter)); } self.cursors.make_consistent(); @@ -493,7 +500,7 @@ impl Editor { self.cursors = CursorSet::new(); self.cursors[0].range = (0, 0); - self.cursors[0].update_vis_start(&(self.buffer)); + self.cursors[0].update_vis_start(&(self.buffer), &(self.formatter)); // Adjust view self.move_view_to_cursor(); @@ -504,7 +511,7 @@ impl Editor { self.cursors = CursorSet::new(); self.cursors[0].range = (end, end); - self.cursors[0].update_vis_start(&(self.buffer)); + self.cursors[0].update_vis_start(&(self.buffer), &(self.formatter)); // Adjust view self.move_view_to_cursor(); @@ -520,7 +527,7 @@ impl Editor { } c.range.1 = c.range.0; - c.update_vis_start(&(self.buffer)); + c.update_vis_start(&(self.buffer), &(self.formatter)); } // Adjust view @@ -536,7 +543,7 @@ impl Editor { } c.range.0 = c.range.1; - c.update_vis_start(&(self.buffer)); + c.update_vis_start(&(self.buffer), &(self.formatter)); } // Adjust view @@ -544,93 +551,103 @@ impl Editor { } pub fn cursor_up(&mut self, n: usize) { - for c in self.cursors.iter_mut() { - let vmove = n * self.buffer.formatter.single_line_height(); - let (v, _) = self.buffer.index_to_v2d(c.range.0); - - if vmove <= v { - c.range.0 = self.buffer.v2d_to_index((v - vmove, c.vis_start), (Floor, Floor)); - c.range.1 = c.range.0; - } - else { - c.range = (0, 0); - c.update_vis_start(&(self.buffer)); - } - } + // TODO: update to new formatting code - // Adjust view - self.move_view_to_cursor(); + //for c in self.cursors.iter_mut() { + // let vmove = n * self.buffer.formatter.single_line_height(); + // let (v, _) = self.buffer.index_to_v2d(c.range.0); + // + // if vmove <= v { + // c.range.0 = self.buffer.v2d_to_index((v - vmove, c.vis_start), (Floor, Floor)); + // c.range.1 = c.range.0; + // } + // else { + // c.range = (0, 0); + // c.update_vis_start(&(self.buffer), &(self.formatter)); + // } + //} + // + //// Adjust view + //self.move_view_to_cursor(); } pub fn cursor_down(&mut self, n: usize) { - for c in self.cursors.iter_mut() { - let vmove = n * self.buffer.formatter.single_line_height(); - let (v, _) = self.buffer.index_to_v2d(c.range.0); - let (h, _) = self.buffer.dimensions(); - - if vmove < (h - v) { - c.range.0 = self.buffer.v2d_to_index((v + vmove, c.vis_start), (Floor, Floor)); - c.range.1 = c.range.0; - } - else { - let end = self.buffer.grapheme_count(); - c.range = (end, end); - c.update_vis_start(&(self.buffer)); - } - } + // TODO: update to new formatting code - // Adjust view - self.move_view_to_cursor(); + //for c in self.cursors.iter_mut() { + // let vmove = n * self.buffer.formatter.single_line_height(); + // let (v, _) = self.buffer.index_to_v2d(c.range.0); + // let (h, _) = self.buffer.dimensions(); + // + // if vmove < (h - v) { + // c.range.0 = self.buffer.v2d_to_index((v + vmove, c.vis_start), (Floor, Floor)); + // c.range.1 = c.range.0; + // } + // else { + // let end = self.buffer.grapheme_count(); + // c.range = (end, end); + // c.update_vis_start(&(self.buffer), &(self.formatter)); + // } + //} + // + //// Adjust view + //self.move_view_to_cursor(); } pub fn page_up(&mut self) { - let move_amount = self.view_dim.0 - max((self.view_dim.0 / 8), self.buffer.formatter.single_line_height()); + // TODO: update to new formatting code - if self.view_pos.0 > 0 { - if self.view_pos.0 >= move_amount { - self.view_pos.0 -= move_amount; - } - else { - self.view_pos.0 = 0; - } - } - - self.cursor_up(move_amount); - - // Adjust view - self.move_view_to_cursor(); + //let move_amount = self.view_dim.0 - max((self.view_dim.0 / 8), self.buffer.formatter.single_line_height()); + // + //if self.view_pos.0 > 0 { + // if self.view_pos.0 >= move_amount { + // self.view_pos.0 -= move_amount; + // } + // else { + // self.view_pos.0 = 0; + // } + //} + // + //self.cursor_up(move_amount); + // + //// Adjust view + //self.move_view_to_cursor(); } pub fn page_down(&mut self) { - let nlc = self.buffer.line_count() - 1; - let move_amount = self.view_dim.0 - max((self.view_dim.0 / 8), self.buffer.formatter.single_line_height()); + // TODO: update to new formatting code - if self.view_pos.0 < nlc { - let max_move = nlc - self.view_pos.0; - - if max_move >= move_amount { - self.view_pos.0 += move_amount; - } - else { - self.view_pos.0 += max_move; - } - - } - - self.cursor_down(move_amount); - - // Adjust view - self.move_view_to_cursor(); + //let nlc = self.buffer.line_count() - 1; + //let move_amount = self.view_dim.0 - max((self.view_dim.0 / 8), self.buffer.formatter.single_line_height()); + // + //if self.view_pos.0 < nlc { + // let max_move = nlc - self.view_pos.0; + // + // if max_move >= move_amount { + // self.view_pos.0 += move_amount; + // } + // else { + // self.view_pos.0 += max_move; + // } + // + //} + // + //self.cursor_down(move_amount); + // + //// Adjust view + //self.move_view_to_cursor(); } pub fn jump_to_line(&mut self, n: usize) { - let pos = self.buffer.line_col_to_index((n, 0)); - let (v, _) = self.buffer.index_to_v2d(pos); - self.cursors.truncate(1); - self.cursors[0].range.0 = self.buffer.v2d_to_index((v, self.cursors[0].vis_start), (Floor, Floor)); - self.cursors[0].range.1 = self.cursors[0].range.0; + // TODO: update to new formatting code - // Adjust view - self.move_view_to_cursor(); + //let pos = self.buffer.line_col_to_index((n, 0)); + //let (v, _) = self.buffer.index_to_v2d(pos); + //self.cursors.truncate(1); + //self.cursors[0].range.0 = self.buffer.v2d_to_index((v, self.cursors[0].vis_start), (Floor, Floor)); + //self.cursors[0].range.1 = self.cursors[0].range.0; + // + //// Adjust view + //self.move_view_to_cursor(); } } diff --git a/src/files.rs b/src/files.rs index b06751d..b302fa1 100644 --- a/src/files.rs +++ b/src/files.rs @@ -3,10 +3,9 @@ use std::old_io::fs::File; use std::path::Path; use buffer::line::{line_ending_to_str}; -use buffer::line_formatter::LineFormatter; use buffer::Buffer as TextBuffer; -pub fn save_buffer_to_file(tb: &TextBuffer, path: &Path) -> IoResult<()> { +pub fn save_buffer_to_file(tb: &TextBuffer, path: &Path) -> IoResult<()> { // TODO: make save atomic let mut iter = tb.line_iter(); let mut f = BufferedWriter::new(try!(File::create(path))); diff --git a/src/term_ui/formatter.rs b/src/term_ui/formatter.rs index ba946d5..87c8e13 100644 --- a/src/term_ui/formatter.rs +++ b/src/term_ui/formatter.rs @@ -2,7 +2,7 @@ use std::cmp::max; use string_utils::{is_line_ending}; use buffer::line::{Line, LineGraphemeIter}; -use buffer::line_formatter::{LineFormatter, RoundingBehavior}; +use editor::formatter::{LineFormatter, RoundingBehavior}; //=================================================================== // LineFormatter implementation for terminals/consoles. diff --git a/src/term_ui/mod.rs b/src/term_ui/mod.rs index 96d5e34..5733792 100644 --- a/src/term_ui/mod.rs +++ b/src/term_ui/mod.rs @@ -3,11 +3,11 @@ use rustbox; use rustbox::Color; use editor::Editor; +use editor::formatter::{LineFormatter, RoundingBehavior}; use std::char; use std::time::duration::Duration; use string_utils::{is_line_ending}; use buffer::line::{line_ending_to_str, LineEnding}; -use buffer::line_formatter::{LineFormatter, RoundingBehavior}; use self::formatter::ConsoleLineFormatter; pub mod formatter; @@ -84,8 +84,7 @@ impl TermUI { let mut resize: Option<(usize, usize)> = None; self.editor.update_dim(self.height-1, self.width); - self.editor.buffer.formatter.wrap_width = self.width as usize; - self.editor.buffer.reformat(); + self.editor.formatter.wrap_width = self.width as usize; loop { // Draw the editor to screen @@ -197,8 +196,7 @@ impl TermUI { self.width = w as usize; self.height = h as usize; self.editor.update_dim(self.height-1, self.width); - self.editor.buffer.formatter.wrap_width = self.width; - self.editor.buffer.reformat(); + self.editor.formatter.wrap_width = self.width; println!("Resized window!"); } resize = None; @@ -354,101 +352,103 @@ impl TermUI { fn draw_editor_text(&self, editor: &Editor, c1: (usize, usize), c2: (usize, usize)) { - // Calculate all the starting info - let editor_corner_index = editor.buffer.v2d_to_index(editor.view_pos, (RoundingBehavior::Floor, RoundingBehavior::Floor)); - let (starting_line, _) = editor.buffer.index_to_line_col(editor_corner_index); - let mut grapheme_index = editor.buffer.line_col_to_index((starting_line, 0)); - let (vis_starting_line, _) = editor.buffer.index_to_v2d(grapheme_index); - - let mut screen_line = c1.0 as isize + vis_starting_line as isize; - let screen_col = c1.1 as isize; + // TODO: update to new formatting code - let mut line_iter = editor.buffer.line_iter_at_index(starting_line); - - for line in line_iter { - let mut g_iter = editor.buffer.formatter.vis_grapheme_iter(line); - - // Loop through the graphemes of the line and print them to - // the screen. - for (g, (pos_y, pos_x), width) in g_iter { - // Calculate the cell coordinates at which to draw the grapheme - let px = pos_x as isize + screen_col - editor.view_pos.1 as isize; - let py = pos_y as isize + screen_line - editor.view_pos.0 as isize; - - // If we're off the bottom, we're done - if py > c2.0 as isize { - return; - } - - // Draw the grapheme to the screen if it's in bounds - if (px >= c1.1 as isize) && (py >= c1.0 as isize) && (px <= c2.1 as isize) { - // Check if the character is within a cursor - let mut at_cursor = false; - for c in editor.cursors.iter() { - if grapheme_index >= c.range.0 && grapheme_index <= c.range.1 { - at_cursor = true; - } - } - - // Actually print the character - if is_line_ending(g) { - if at_cursor { - self.rb.print(px as usize, py as usize, rustbox::RB_NORMAL, Color::Black, Color::White, " "); - } - } - else if g == "\t" { - for i in 0..width { - let tpx = px as usize + i; - if tpx <= c2.1 { - self.rb.print(tpx as usize, py as usize, rustbox::RB_NORMAL, Color::White, Color::Black, " "); - } - } - - if at_cursor { - self.rb.print(px as usize, py as usize, rustbox::RB_NORMAL, Color::Black, Color::White, " "); - } - } - else { - if at_cursor { - self.rb.print(px as usize, py as usize, rustbox::RB_NORMAL, Color::Black, Color::White, g); - } - else { - self.rb.print(px as usize, py as usize, rustbox::RB_NORMAL, Color::White, Color::Black, g); - } - } - } - - grapheme_index += 1; - } - - let (dim_y, _) = editor.buffer.formatter.dimensions(line); - screen_line += dim_y as isize; - } - - - - // If we get here, it means we reached the end of the text buffer - // without going off the bottom of the screen. So draw the cursor - // at the end if needed. - - // Check if the character is within a cursor - let mut at_cursor = false; - for c in editor.cursors.iter() { - if grapheme_index >= c.range.0 && grapheme_index <= c.range.1 { - at_cursor = true; - } - } - - if at_cursor { - // Calculate the cell coordinates at which to draw the cursor - let (pos_y, pos_x) = editor.buffer.index_to_v2d(grapheme_index); - let px = pos_x as isize + c1.1 as isize - editor.view_pos.1 as isize; - let py = pos_y as isize + c1.0 as isize - editor.view_pos.0 as isize; - - if (px >= c1.1 as isize) && (py >= c1.0 as isize) && (px <= c2.1 as isize) && (py <= c2.0 as isize) { - self.rb.print(px as usize, py as usize, rustbox::RB_NORMAL, Color::Black, Color::White, " "); - } - } + //// Calculate all the starting info + //let editor_corner_index = editor.buffer.v2d_to_index(editor.view_pos, (RoundingBehavior::Floor, RoundingBehavior::Floor)); + //let (starting_line, _) = editor.buffer.index_to_line_col(editor_corner_index); + //let mut grapheme_index = editor.buffer.line_col_to_index((starting_line, 0)); + //let (vis_starting_line, _) = editor.buffer.index_to_v2d(grapheme_index); + // + //let mut screen_line = c1.0 as isize + vis_starting_line as isize; + //let screen_col = c1.1 as isize; + // + //let mut line_iter = editor.buffer.line_iter_at_index(starting_line); + // + //for line in line_iter { + // let mut g_iter = editor.buffer.formatter.vis_grapheme_iter(line); + // + // // Loop through the graphemes of the line and print them to + // // the screen. + // for (g, (pos_y, pos_x), width) in g_iter { + // // Calculate the cell coordinates at which to draw the grapheme + // let px = pos_x as isize + screen_col - editor.view_pos.1 as isize; + // let py = pos_y as isize + screen_line - editor.view_pos.0 as isize; + // + // // If we're off the bottom, we're done + // if py > c2.0 as isize { + // return; + // } + // + // // Draw the grapheme to the screen if it's in bounds + // if (px >= c1.1 as isize) && (py >= c1.0 as isize) && (px <= c2.1 as isize) { + // // Check if the character is within a cursor + // let mut at_cursor = false; + // for c in editor.cursors.iter() { + // if grapheme_index >= c.range.0 && grapheme_index <= c.range.1 { + // at_cursor = true; + // } + // } + // + // // Actually print the character + // if is_line_ending(g) { + // if at_cursor { + // self.rb.print(px as usize, py as usize, rustbox::RB_NORMAL, Color::Black, Color::White, " "); + // } + // } + // else if g == "\t" { + // for i in 0..width { + // let tpx = px as usize + i; + // if tpx <= c2.1 { + // self.rb.print(tpx as usize, py as usize, rustbox::RB_NORMAL, Color::White, Color::Black, " "); + // } + // } + // + // if at_cursor { + // self.rb.print(px as usize, py as usize, rustbox::RB_NORMAL, Color::Black, Color::White, " "); + // } + // } + // else { + // if at_cursor { + // self.rb.print(px as usize, py as usize, rustbox::RB_NORMAL, Color::Black, Color::White, g); + // } + // else { + // self.rb.print(px as usize, py as usize, rustbox::RB_NORMAL, Color::White, Color::Black, g); + // } + // } + // } + // + // grapheme_index += 1; + // } + // + // let (dim_y, _) = editor.buffer.formatter.dimensions(line); + // screen_line += dim_y as isize; + //} + // + // + // + //// If we get here, it means we reached the end of the text buffer + //// without going off the bottom of the screen. So draw the cursor + //// at the end if needed. + // + //// Check if the character is within a cursor + //let mut at_cursor = false; + //for c in editor.cursors.iter() { + // if grapheme_index >= c.range.0 && grapheme_index <= c.range.1 { + // at_cursor = true; + // } + //} + // + //if at_cursor { + // // Calculate the cell coordinates at which to draw the cursor + // let (pos_y, pos_x) = editor.buffer.index_to_v2d(grapheme_index); + // let px = pos_x as isize + c1.1 as isize - editor.view_pos.1 as isize; + // let py = pos_y as isize + c1.0 as isize - editor.view_pos.0 as isize; + // + // if (px >= c1.1 as isize) && (py >= c1.0 as isize) && (px <= c2.1 as isize) && (py <= c2.0 as isize) { + // self.rb.print(px as usize, py as usize, rustbox::RB_NORMAL, Color::Black, Color::White, " "); + // } + //} }