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
|
/// 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.");
|
||||||
|
|
|
@ -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) => {
|
||||||
|
|
|
@ -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, " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user