Fixed some bugs relating to text and cursor printing.
This commit is contained in:
parent
fc78fbeb3e
commit
940068a4dd
|
@ -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
|
||||
pub fn grapheme_index_to_closest_vis_pos(&self, index: uint) -> uint {
|
||||
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;
|
||||
while i < n {
|
||||
if let Some((_, _, width)) = self.next() {
|
||||
|
@ -614,6 +652,13 @@ impl<'a> LineGraphemeVisIter<'a> {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if i > n {
|
||||
return i - n;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
if index >= self.line_count() {
|
||||
panic!("get_line(): index out of bounds.");
|
||||
|
|
|
@ -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 {
|
||||
match self.data {
|
||||
BufferNodeData::Leaf(ref line) => {
|
||||
|
|
|
@ -155,28 +155,32 @@ impl TermUI {
|
|||
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_num = editor.view_pos.0;
|
||||
let mut col_num = editor.view_pos.1;
|
||||
let mut grapheme_index;
|
||||
|
||||
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_col_num;
|
||||
let mut print_col_num = c1.1;
|
||||
|
||||
let max_print_line = c2.0 - c1.0;
|
||||
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 {
|
||||
if let Some(line) = line_iter.next() {
|
||||
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 {
|
||||
print_col_num = pos - editor.view_pos.1;
|
||||
|
||||
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, " ");
|
||||
}
|
||||
}
|
||||
|
@ -185,12 +189,12 @@ impl TermUI {
|
|||
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, " ");
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
else {
|
||||
|
@ -198,7 +202,8 @@ impl TermUI {
|
|||
}
|
||||
}
|
||||
|
||||
col_num += 1;
|
||||
vis_col_num += width;
|
||||
grapheme_index += 1;
|
||||
print_col_num += width;
|
||||
|
||||
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 {
|
||||
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, " ");
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
|
||||
line_num += 1;
|
||||
vis_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 {
|
||||
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, " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user