Fixed some bugs relating to text and cursor printing.

This commit is contained in:
Nathan Vegdahl 2015-01-02 16:47:17 -08:00
parent fc78fbeb3e
commit 940068a4dd
4 changed files with 134 additions and 18 deletions

View File

@ -245,6 +245,42 @@ impl Line {
} }
pub fn grapheme_at_index<'a>(&'a self, index: uint) -> &'a str {
let mut iter = self.grapheme_iter();
let mut i = 0;
for g in iter {
if i == index {
return g;
}
else {
i += 1;
}
}
// Should never get here
panic!("Line::grapheme_at_index(): index past end of line.");
}
pub fn grapheme_width_at_index(&self, index: uint) -> uint {
let mut iter = self.grapheme_vis_iter();
let mut i = 0;
for (_, _, width) in iter {
if i == index {
return width;
}
else {
i += 1;
}
}
// Should never get here
panic!("Line::grapheme_at_index(): index past end of line.");
}
/// Translates a grapheme index into a visual horizontal position /// Translates a grapheme index into a visual horizontal position
pub fn grapheme_index_to_closest_vis_pos(&self, index: uint) -> uint { pub fn grapheme_index_to_closest_vis_pos(&self, index: uint) -> uint {
let mut pos = 0; let mut pos = 0;
@ -604,7 +640,9 @@ impl<'a> LineGraphemeVisIter<'a> {
} }
} }
pub fn skip_vis_positions(&mut self, n: uint) { // Skips at least n visual positions, and returns the number of excess
// skipped visual positions beyond n.
pub fn skip_vis_positions(&mut self, n: uint) -> uint {
let mut i = 0; let mut i = 0;
while i < n { while i < n {
if let Some((_, _, width)) = self.next() { if let Some((_, _, width)) = self.next() {
@ -614,6 +652,13 @@ impl<'a> LineGraphemeVisIter<'a> {
break; break;
} }
} }
if i > n {
return i - n;
}
else {
return 0;
}
} }
} }

View File

@ -38,6 +38,26 @@ impl Buffer {
} }
pub fn get_grapheme<'a>(&'a self, index: uint) -> &'a str {
if index >= self.len() {
panic!("Buffer::get_grapheme(): index past last grapheme.");
}
else {
return self.root.get_grapheme_recursive(index);
}
}
pub fn get_grapheme_width(&self, index: uint) -> uint {
if index >= self.len() {
panic!("Buffer::get_grapheme_width(): index past last grapheme.");
}
else {
return self.root.get_grapheme_width_recursive(index);
}
}
pub fn get_line<'a>(&'a self, index: uint) -> &'a Line { pub fn get_line<'a>(&'a self, index: uint) -> &'a Line {
if index >= self.line_count() { if index >= self.line_count() {
panic!("get_line(): index out of bounds."); panic!("get_line(): index out of bounds.");

View File

@ -184,6 +184,42 @@ impl BufferNode {
} }
pub fn get_grapheme_recursive<'a>(&'a self, index: uint) -> &'a str {
match self.data {
BufferNodeData::Leaf(ref line) => {
return line.grapheme_at_index(index);
},
BufferNodeData::Branch(ref left, ref right) => {
if index < left.grapheme_count {
return left.get_grapheme_recursive(index);
}
else {
return right.get_grapheme_recursive(index - left.grapheme_count);
}
}
}
}
pub fn get_grapheme_width_recursive(&self, index: uint) -> uint {
match self.data {
BufferNodeData::Leaf(ref line) => {
return line.grapheme_width_at_index(index);
},
BufferNodeData::Branch(ref left, ref right) => {
if index < left.grapheme_count {
return left.get_grapheme_width_recursive(index);
}
else {
return right.get_grapheme_width_recursive(index - left.grapheme_count);
}
}
}
}
pub fn get_line_recursive<'a>(&'a self, index: uint) -> &'a Line { pub fn get_line_recursive<'a>(&'a self, index: uint) -> &'a Line {
match self.data { match self.data {
BufferNodeData::Leaf(ref line) => { BufferNodeData::Leaf(ref line) => {

View File

@ -155,28 +155,32 @@ impl TermUI {
pub fn draw_editor(&self, editor: &Editor, c1: (uint, uint), c2: (uint, uint)) { pub fn draw_editor(&self, editor: &Editor, c1: (uint, uint), c2: (uint, uint)) {
let mut line_iter = editor.buffer.line_iter_at_index(editor.view_pos.0); let mut line_iter = editor.buffer.line_iter_at_index(editor.view_pos.0);
let mut line_num = editor.view_pos.0; let mut grapheme_index;
let mut col_num = editor.view_pos.1;
let mut vis_line_num = editor.view_pos.0;
let mut vis_col_num = editor.view_pos.1;
let mut print_line_num = c1.0; let mut print_line_num = c1.0;
let mut print_col_num; let mut print_col_num = c1.1;
let max_print_line = c2.0 - c1.0; let max_print_line = c2.0 - c1.0;
let max_print_col = c2.1 - c1.1; let max_print_col = c2.1 - c1.1;
let cursor_pos = editor.buffer.pos_1d_to_closest_2d(editor.cursor.range.0);
let print_cursor_pos = (cursor_pos.0 + editor.view_pos.0, cursor_pos.1 + editor.view_pos.1);
loop { loop {
if let Some(line) = line_iter.next() { if let Some(line) = line_iter.next() {
let mut g_iter = line.grapheme_vis_iter(); let mut g_iter = line.grapheme_vis_iter();
g_iter.skip_vis_positions(editor.view_pos.1); let excess = g_iter.skip_vis_positions(editor.view_pos.1);
vis_col_num += excess;
print_col_num += excess;
grapheme_index = editor.buffer.pos_vis_2d_to_closest_1d((vis_line_num, vis_col_num));
for (g, pos, width) in g_iter { for (g, pos, width) in g_iter {
print_col_num = pos - editor.view_pos.1; print_col_num = pos - editor.view_pos.1;
if is_line_ending(g) { if is_line_ending(g) {
if (line_num, col_num) == cursor_pos { if grapheme_index == editor.cursor.range.0 {
self.rb.print(print_col_num, print_line_num, rustbox::RB_NORMAL, Color::Black, Color::White, " "); self.rb.print(print_col_num, print_line_num, rustbox::RB_NORMAL, Color::Black, Color::White, " ");
} }
} }
@ -185,12 +189,12 @@ impl TermUI {
self.rb.print(i, print_line_num, rustbox::RB_NORMAL, Color::White, Color::Black, " "); self.rb.print(i, print_line_num, rustbox::RB_NORMAL, Color::White, Color::Black, " ");
} }
if (line_num, col_num) == cursor_pos { if grapheme_index == editor.cursor.range.0 {
self.rb.print(print_col_num, print_line_num, rustbox::RB_NORMAL, Color::Black, Color::White, " "); self.rb.print(print_col_num, print_line_num, rustbox::RB_NORMAL, Color::Black, Color::White, " ");
} }
} }
else { else {
if (line_num, col_num) == cursor_pos { if grapheme_index == editor.cursor.range.0 {
self.rb.print(print_col_num, print_line_num, rustbox::RB_NORMAL, Color::Black, Color::White, g); self.rb.print(print_col_num, print_line_num, rustbox::RB_NORMAL, Color::Black, Color::White, g);
} }
else { else {
@ -198,7 +202,8 @@ impl TermUI {
} }
} }
col_num += 1; vis_col_num += width;
grapheme_index += 1;
print_col_num += width; print_col_num += width;
if print_col_num > max_print_col { if print_col_num > max_print_col {
@ -206,21 +211,31 @@ impl TermUI {
} }
} }
} }
else if print_cursor_pos.0 >= c1.0 && print_cursor_pos.0 < c2.0 && print_cursor_pos.1 >= c1.1 && print_cursor_pos.1 < c2.1 { else {
if editor.cursor.range.0 >= editor.buffer.len() {
self.rb.print(print_cursor_pos.1, print_cursor_pos.0, rustbox::RB_NORMAL, Color::Black, Color::White, " ");
}
break; break;
} }
line_num += 1; vis_line_num += 1;
print_line_num += 1; print_line_num += 1;
col_num = editor.view_pos.1; vis_col_num = editor.view_pos.1;
if print_line_num > max_print_line { if print_line_num > max_print_line {
break; break;
} }
} }
// Print cursor if it's at the end of the text, and thus wasn't printed
// already.
if editor.cursor.range.0 >= editor.buffer.len() {
let vis_cursor_pos = editor.buffer.pos_1d_to_closest_vis_2d(editor.cursor.range.0);
if (vis_cursor_pos.0 >= editor.view_pos.0) && (vis_cursor_pos.1 >= editor.view_pos.1) {
let print_cursor_pos = (vis_cursor_pos.0 - editor.view_pos.0, vis_cursor_pos.1 - editor.view_pos.1);
if print_cursor_pos.0 >= c1.0 && print_cursor_pos.0 <= c2.0 && print_cursor_pos.1 >= c1.1 && print_cursor_pos.1 <= c2.1 {
self.rb.print(print_cursor_pos.1, print_cursor_pos.0, rustbox::RB_NORMAL, Color::Black, Color::White, " ");
}
}
}
} }