Basic cursor movement is now working properly.

This commit is contained in:
Nathan Vegdahl 2014-12-26 19:29:52 -08:00
parent 5105622dcb
commit bf099d0f6d
4 changed files with 116 additions and 14 deletions

View File

@ -25,11 +25,15 @@ impl TextBuffer {
self.root.char_count self.root.char_count
} }
pub fn pos_2d_to_1d(&self, pos: (uint, uint)) -> Option<uint> { pub fn newline_count(&self) -> uint {
// TODO self.root.newline_count
return Option::None;
} }
//pub fn pos_2d_to_1d(&self, pos: (uint, uint)) -> Option<uint> {
// // TODO
// return Option::None;
//}
pub fn pos_2d_to_closest_1d(&self, pos: (uint, uint)) -> uint { pub fn pos_2d_to_closest_1d(&self, pos: (uint, uint)) -> uint {
match self.root.pos_2d_to_closest_1d(0, pos) { match self.root.pos_2d_to_closest_1d(0, pos) {
text_node::IndexOrOffset::Index(i) => i, text_node::IndexOrOffset::Index(i) => i,
@ -37,14 +41,18 @@ impl TextBuffer {
} }
} }
pub fn pos_2d_to_closest_2d(&self, pos: (uint, uint)) -> (uint, uint) { //pub fn pos_2d_to_closest_2d(&self, pos: (uint, uint)) -> (uint, uint) {
// TODO // // TODO
return (0, 0); // return (0, 0);
} //}
pub fn pos_1d_to_2d(&self, pos: uint) -> Option<(uint, uint)> { //pub fn pos_1d_to_2d(&self, pos: uint) -> Option<(uint, uint)> {
// TODO // // TODO
return Option::None; // return Option::None;
//}
pub fn pos_1d_to_closest_2d(&self, pos: uint) -> (uint, uint) {
self.root.pos_1d_to_closest_2d((0,0), pos)
} }
/// Insert 'text' at char position 'pos'. /// Insert 'text' at char position 'pos'.

View File

@ -338,8 +338,9 @@ impl TextNode {
let mut col = offset; let mut col = offset;
for c in iter { for c in iter {
// Check if we've hit a relevant character // Check if we've hit or passed the target column on
if line > pos.0 || (line == pos.0 && col >= pos.1) { // the target line.
if line == pos.0 && col >= pos.1 {
break; break;
} }
@ -347,10 +348,16 @@ impl TextNode {
if c == '\n' { if c == '\n' {
line += 1; line += 1;
col = 0; col = 0;
// Check if we've passed the target line
if line > pos.0 {
break;
}
} }
else { else {
col += 1; col += 1;
} }
i += 1; i += 1;
} }
@ -403,6 +410,89 @@ impl TextNode {
} }
/// Find the closest 2d text position that represents the given
/// 1d position well.
pub fn pos_1d_to_closest_2d(&self, offset_pos: (uint, uint), pos: uint) -> (uint, uint) {
match self.data {
TextNodeData::Leaf(ref tb) => {
let mut iter = tb.as_str().chars();
let mut line = offset_pos.0;
let mut col = offset_pos.1;
let mut i: uint = 0;
for c in iter {
if i == pos {
break;
}
if c == '\n' {
line += 1;
col = 0;
}
else {
col += 1;
}
i += 1;
}
return (line, col);
},
TextNodeData::Branch(ref left, ref right) => {
if left.char_count > pos {
return left.pos_1d_to_closest_2d(offset_pos, pos);
}
else {
let mut line = offset_pos.0;
let mut col = offset_pos.1;
if left.newline_count > 0 {
line += left.newline_count;
col = 0;
}
col += left.tail_len();
return right.pos_1d_to_closest_2d((line, col), pos - left.char_count);
}
}
}
}
/// Returns the number of characters after the last newline in the node,
/// or the total character length of the node if there are no newlines.
pub fn tail_len(&self) -> uint {
match self.data {
TextNodeData::Leaf(ref tb) => {
let mut iter = tb.as_str().chars();
let mut tlen = 0;
for c in iter {
if c == '\n' {
tlen = 0;
}
else {
tlen += 1;
}
}
return tlen;
},
TextNodeData::Branch(ref left, ref right) => {
if right.newline_count > 0 {
return right.tail_len();
}
else {
return left.tail_len() + right.char_count;
}
}
}
}
} }
impl fmt::Show for TextNode { impl fmt::Show for TextNode {

View File

@ -104,6 +104,8 @@ impl Editor {
pub fn cursor_right(&mut self) { pub fn cursor_right(&mut self) {
self.cursor.1 += 1; self.cursor.1 += 1;
let p = self.buffer.pos_2d_to_closest_1d(self.cursor);
self.cursor = self.buffer.pos_1d_to_closest_2d(p);
} }
pub fn cursor_up(&mut self) { pub fn cursor_up(&mut self) {
@ -113,6 +115,8 @@ impl Editor {
} }
pub fn cursor_down(&mut self) { pub fn cursor_down(&mut self) {
if self.cursor.0 < self.buffer.newline_count() {
self.cursor.0 += 1; self.cursor.0 += 1;
} }
} }
}

View File

@ -190,7 +190,7 @@ impl TermUI {
tb_iter.next_line(); tb_iter.next_line();
line += 1; line += 1;
column = 0; column = 0;
// TODO: handle pos incrementing here pos = editor.buffer.pos_2d_to_closest_1d((line, column));
} }
} }
} }